diff --git a/ChangeLog b/ChangeLog index 276ac5440..9c78caeff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +* 29.0.0 +- Google Ads API v23_0 release. +- Remove Google Ads API v19. + * 28.4.1 - Fix issues with async functionality per issue #1045. diff --git a/examples/account_management/create_customer.py b/examples/account_management/create_customer.py index 22a69b909..e0eeb166f 100755 --- a/examples/account_management/create_customer.py +++ b/examples/account_management/create_customer.py @@ -27,11 +27,11 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.customer import Customer -from google.ads.googleads.v22.services.services.customer_service.client import ( +from google.ads.googleads.v23.resources.types.customer import Customer +from google.ads.googleads.v23.services.services.customer_service.client import ( CustomerServiceClient, ) -from google.ads.googleads.v22.services.types.customer_service import ( +from google.ads.googleads.v23.services.types.customer_service import ( CreateCustomerClientResponse, ) @@ -91,7 +91,7 @@ def main(client: GoogleAdsClient, manager_customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.manager_customer_id) diff --git a/examples/account_management/get_account_hierarchy.py b/examples/account_management/get_account_hierarchy.py index cc5e11ced..4c051b68c 100755 --- a/examples/account_management/get_account_hierarchy.py +++ b/examples/account_management/get_account_hierarchy.py @@ -28,16 +28,16 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.google_ads_service.client import ( +from google.ads.googleads.v23.services.services.google_ads_service.client import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.services.customer_service.client import ( +from google.ads.googleads.v23.services.services.customer_service.client import ( CustomerServiceClient, ) -from google.ads.googleads.v22.resources.types.customer_client import ( +from google.ads.googleads.v23.resources.types.customer_client import ( CustomerClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchPagedResponse, GoogleAdsRow, ) @@ -238,7 +238,7 @@ def print_account_hierarchy( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.login_customer_id) except GoogleAdsException as ex: diff --git a/examples/account_management/get_change_details.py b/examples/account_management/get_change_details.py index 4311b1758..01c01e527 100755 --- a/examples/account_management/get_change_details.py +++ b/examples/account_management/get_change_details.py @@ -28,15 +28,15 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException from google.ads.googleads.util import get_nested_attr -from google.ads.googleads.v22.services.services.google_ads_service.client import ( +from google.ads.googleads.v23.services.services.google_ads_service.client import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchGoogleAdsRequest, SearchPagedResponse, GoogleAdsRow, ) -from google.ads.googleads.v22.resources.types.change_event import ChangeEvent +from google.ads.googleads.v23.resources.types.change_event import ChangeEvent # [START get_change_details] @@ -218,7 +218,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.customer_id) except GoogleAdsException as ex: diff --git a/examples/account_management/get_change_summary.py b/examples/account_management/get_change_summary.py index 2d583504b..69ee96ed4 100755 --- a/examples/account_management/get_change_summary.py +++ b/examples/account_management/get_change_summary.py @@ -22,15 +22,15 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.google_ads_service.client import ( +from google.ads.googleads.v23.services.services.google_ads_service.client import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchGoogleAdsRequest, SearchPagedResponse, GoogleAdsRow, ) -from google.ads.googleads.v22.resources.types.change_status import ChangeStatus +from google.ads.googleads.v23.resources.types.change_status import ChangeStatus # [START get_change_summary] @@ -110,7 +110,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.customer_id) diff --git a/examples/account_management/invite_user_with_access_role.py b/examples/account_management/invite_user_with_access_role.py index e80c3e583..89d2407a7 100755 --- a/examples/account_management/invite_user_with_access_role.py +++ b/examples/account_management/invite_user_with_access_role.py @@ -23,18 +23,18 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.customer_user_access_invitation_service.client import ( +from google.ads.googleads.v23.services.services.customer_user_access_invitation_service.client import ( CustomerUserAccessInvitationServiceClient, ) -from google.ads.googleads.v22.services.types.customer_user_access_invitation_service import ( +from google.ads.googleads.v23.services.types.customer_user_access_invitation_service import ( CustomerUserAccessInvitationOperation, MutateCustomerUserAccessInvitationResponse, ) -from google.ads.googleads.v22.resources.types.customer_user_access_invitation import ( +from google.ads.googleads.v23.resources.types.customer_user_access_invitation import ( CustomerUserAccessInvitation, ) -# AccessRoleEnum is part of google.ads.googleads.v22.enums.types.access_role +# AccessRoleEnum is part of google.ads.googleads.v23.enums.types.access_role # but it's accessed via client.enums.AccessRoleEnum, so direct import for type hint might not be strictly needed for the parameter. # The field invitation.access_role expects an int (the enum value). @@ -115,7 +115,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main( diff --git a/examples/account_management/link_manager_to_client.py b/examples/account_management/link_manager_to_client.py index c69a1f8a2..25ec4e92b 100755 --- a/examples/account_management/link_manager_to_client.py +++ b/examples/account_management/link_manager_to_client.py @@ -22,31 +22,31 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.customer_client_link_service.client import ( +from google.ads.googleads.v23.services.services.customer_client_link_service.client import ( CustomerClientLinkServiceClient, ) -from google.ads.googleads.v22.services.types.customer_client_link_service import ( +from google.ads.googleads.v23.services.types.customer_client_link_service import ( CustomerClientLinkOperation, MutateCustomerClientLinkResponse, ) -from google.ads.googleads.v22.resources.types.customer_client_link import ( +from google.ads.googleads.v23.resources.types.customer_client_link import ( CustomerClientLink, ) -from google.ads.googleads.v22.services.services.google_ads_service.client import ( +from google.ads.googleads.v23.services.services.google_ads_service.client import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchPagedResponse, GoogleAdsRow, ) -from google.ads.googleads.v22.services.services.customer_manager_link_service.client import ( +from google.ads.googleads.v23.services.services.customer_manager_link_service.client import ( CustomerManagerLinkServiceClient, ) -from google.ads.googleads.v22.services.types.customer_manager_link_service import ( +from google.ads.googleads.v23.services.types.customer_manager_link_service import ( CustomerManagerLinkOperation, MutateCustomerManagerLinkResponse, ) -from google.ads.googleads.v22.resources.types.customer_manager_link import ( +from google.ads.googleads.v23.resources.types.customer_manager_link import ( CustomerManagerLink, ) @@ -179,7 +179,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.customer_id, args.manager_customer_id) except GoogleAdsException as ex: diff --git a/examples/account_management/list_accessible_customers.py b/examples/account_management/list_accessible_customers.py index 62bf6626d..5f0c5f4eb 100755 --- a/examples/account_management/list_accessible_customers.py +++ b/examples/account_management/list_accessible_customers.py @@ -26,10 +26,10 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.customer_service.client import ( +from google.ads.googleads.v23.services.services.customer_service.client import ( CustomerServiceClient, ) -from google.ads.googleads.v22.services.types.customer_service import ( +from google.ads.googleads.v23.services.types.customer_service import ( ListAccessibleCustomersResponse, ) @@ -55,7 +55,7 @@ def main(client: GoogleAdsClient) -> None: if __name__ == "__main__": # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client) diff --git a/examples/account_management/update_user_access.py b/examples/account_management/update_user_access.py index 05926d762..af0396e84 100755 --- a/examples/account_management/update_user_access.py +++ b/examples/account_management/update_user_access.py @@ -26,20 +26,20 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.google_ads_service.client import ( +from google.ads.googleads.v23.services.services.google_ads_service.client import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchGoogleAdsRequest, SearchPagedResponse, ) -from google.ads.googleads.v22.resources.types.customer_user_access import ( +from google.ads.googleads.v23.resources.types.customer_user_access import ( CustomerUserAccess, ) -from google.ads.googleads.v22.services.services.customer_user_access_service.client import ( +from google.ads.googleads.v23.services.services.customer_user_access_service.client import ( CustomerUserAccessServiceClient, ) -from google.ads.googleads.v22.services.types.customer_user_access_service import ( +from google.ads.googleads.v23.services.types.customer_user_access_service import ( CustomerUserAccessOperation, MutateCustomerUserAccessResponse, ) @@ -219,7 +219,7 @@ def modify_user_access( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main( googleads_client, diff --git a/examples/account_management/verify_advertiser_identity.py b/examples/account_management/verify_advertiser_identity.py index c666549cf..ce459889c 100755 --- a/examples/account_management/verify_advertiser_identity.py +++ b/examples/account_management/verify_advertiser_identity.py @@ -24,13 +24,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.enums.types.identity_verification_program_status import ( +from google.ads.googleads.v23.enums.types.identity_verification_program_status import ( IdentityVerificationProgramStatusEnum, ) -from google.ads.googleads.v22.services.services.identity_verification_service.client import ( +from google.ads.googleads.v23.services.services.identity_verification_service.client import ( IdentityVerificationServiceClient, ) -from google.ads.googleads.v22.services.types.identity_verification_service import ( +from google.ads.googleads.v23.services.types.identity_verification_service import ( GetIdentityVerificationResponse, IdentityVerification, IdentityVerificationProgress, @@ -183,7 +183,7 @@ def start_identity_verification( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.customer_id) diff --git a/examples/advanced_operations/add_ad_customizer.py b/examples/advanced_operations/add_ad_customizer.py index f47b9cedb..8b3f33c17 100755 --- a/examples/advanced_operations/add_ad_customizer.py +++ b/examples/advanced_operations/add_ad_customizer.py @@ -25,25 +25,25 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types import AdTextAsset -from google.ads.googleads.v22.resources.types import ( +from google.ads.googleads.v23.common.types import AdTextAsset +from google.ads.googleads.v23.resources.types import ( AdGroupAd, AdGroupCustomizer, CustomizerAttribute, ) -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_customizer_service import ( +from google.ads.googleads.v23.services.services.ad_group_customizer_service import ( AdGroupCustomizerServiceClient, ) -from google.ads.googleads.v22.services.services.customizer_attribute_service import ( +from google.ads.googleads.v23.services.services.customizer_attribute_service import ( CustomizerAttributeServiceClient, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types import ( +from google.ads.googleads.v23.services.types import ( AdGroupAdOperation, AdGroupCustomizerOperation, CustomizerAttributeOperation, @@ -342,7 +342,7 @@ def create_ad_with_customizations( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/add_ad_group_bid_modifier.py b/examples/advanced_operations/add_ad_group_bid_modifier.py index 37a4e9063..37fee7768 100755 --- a/examples/advanced_operations/add_ad_group_bid_modifier.py +++ b/examples/advanced_operations/add_ad_group_bid_modifier.py @@ -23,17 +23,17 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.enums.types.device import DeviceEnum -from google.ads.googleads.v22.resources.types.ad_group_bid_modifier import ( +from google.ads.googleads.v23.enums.types.device import DeviceEnum +from google.ads.googleads.v23.resources.types.ad_group_bid_modifier import ( AdGroupBidModifier, ) -from google.ads.googleads.v22.services.services.ad_group_bid_modifier_service import ( +from google.ads.googleads.v23.services.services.ad_group_bid_modifier_service import ( AdGroupBidModifierServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_bid_modifier_service import ( +from google.ads.googleads.v23.services.types.ad_group_bid_modifier_service import ( AdGroupBidModifierOperation, MutateAdGroupBidModifiersResponse, ) @@ -120,7 +120,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/add_app_campaign.py b/examples/advanced_operations/add_app_campaign.py index 6e2c7c8c3..197f040bc 100755 --- a/examples/advanced_operations/add_app_campaign.py +++ b/examples/advanced_operations/add_app_campaign.py @@ -30,36 +30,36 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types import AdTextAsset -from google.ads.googleads.v22.resources.types import ( +from google.ads.googleads.v23.common.types import AdTextAsset +from google.ads.googleads.v23.resources.types import ( AdGroup, AdGroupAd, Campaign, CampaignBudget, CampaignCriterion, ) -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_budget_service import ( +from google.ads.googleads.v23.services.services.campaign_budget_service import ( CampaignBudgetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_criterion_service import ( +from google.ads.googleads.v23.services.services.campaign_criterion_service import ( CampaignCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.services.geo_target_constant_service import ( +from google.ads.googleads.v23.services.services.geo_target_constant_service import ( GeoTargetConstantServiceClient, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types import * +from google.ads.googleads.v23.services.types import * def main(client: GoogleAdsClient, customer_id: str) -> None: @@ -184,8 +184,8 @@ def create_campaign( ) # Optional fields - campaign.start_date = (datetime.now() + timedelta(1)).strftime("%Y%m%d") - campaign.end_date = (datetime.now() + timedelta(365)).strftime("%Y%m%d") + campaign.start_date_time = (datetime.now() + timedelta(1)).strftime("%Y%m%d 00:00:00") + campaign.end_date_time = (datetime.now() + timedelta(365)).strftime("%Y%m%d 23:59:59") # Optional: If you select the # OPTIMIZE_IN_APP_CONVERSIONS_TARGET_INSTALL_COST goal type, then also # specify your in-app conversion types so the Google Ads API can focus @@ -392,7 +392,7 @@ def create_ad_text_asset(client: GoogleAdsClient, text: str) -> AdTextAsset: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/add_bidding_data_exclusion.py b/examples/advanced_operations/add_bidding_data_exclusion.py index c537cf1c2..e65e2ae53 100755 --- a/examples/advanced_operations/add_bidding_data_exclusion.py +++ b/examples/advanced_operations/add_bidding_data_exclusion.py @@ -28,13 +28,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.bidding_data_exclusion import ( +from google.ads.googleads.v23.resources.types.bidding_data_exclusion import ( BiddingDataExclusion, ) -from google.ads.googleads.v22.services.services.bidding_data_exclusion_service import ( +from google.ads.googleads.v23.services.services.bidding_data_exclusion_service import ( BiddingDataExclusionServiceClient, ) -from google.ads.googleads.v22.services.types.bidding_data_exclusion_service import ( +from google.ads.googleads.v23.services.types.bidding_data_exclusion_service import ( BiddingDataExclusionOperation, MutateBiddingDataExclusionsResponse, ) @@ -131,7 +131,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/add_bidding_seasonality_adjustment.py b/examples/advanced_operations/add_bidding_seasonality_adjustment.py index 9690944fa..56656dc52 100755 --- a/examples/advanced_operations/add_bidding_seasonality_adjustment.py +++ b/examples/advanced_operations/add_bidding_seasonality_adjustment.py @@ -28,13 +28,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.bidding_seasonality_adjustment import ( +from google.ads.googleads.v23.resources.types.bidding_seasonality_adjustment import ( BiddingSeasonalityAdjustment, ) -from google.ads.googleads.v22.services.services.bidding_seasonality_adjustment_service import ( +from google.ads.googleads.v23.services.services.bidding_seasonality_adjustment_service import ( BiddingSeasonalityAdjustmentServiceClient, ) -from google.ads.googleads.v22.services.types.bidding_seasonality_adjustment_service import ( +from google.ads.googleads.v23.services.types.bidding_seasonality_adjustment_service import ( BiddingSeasonalityAdjustmentOperation, MutateBiddingSeasonalityAdjustmentsResponse, ) @@ -150,7 +150,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/add_call_ad.py b/examples/advanced_operations/add_call_ad.py deleted file mode 100755 index cfb0db2ee..000000000 --- a/examples/advanced_operations/add_call_ad.py +++ /dev/null @@ -1,191 +0,0 @@ -#!/usr/bin/env python -# Copyright 2022 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""This example adds a call ad to a given ad group. - -More information about call ads can be found at: -https://support.google.com/google-ads/answer/6341403. - -To get ad group IDs, run basic_operations/get_ad_groups.py. -""" - - -import argparse -import sys -from typing import Optional - -from google.ads.googleads.client import GoogleAdsClient -from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad import Ad -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( - AdGroupAdServiceClient, -) -from google.ads.googleads.v22.services.services.google_ads_service import ( - GoogleAdsServiceClient, -) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( - AdGroupAdOperation, - MutateAdGroupAdsResponse, -) - -# Country code is a two-letter ISO-3166 code, for a list of all codes see: -# https://developers.google.com/google-ads/api/reference/data/codes-formats#expandable-17 -_DEFAULT_PHONE_COUNTRY: str = "US" - - -def main( - client: GoogleAdsClient, - customer_id: str, - ad_group_id: str, - phone_number: str, - phone_country: str, - conversion_action_id: Optional[str], -) -> None: - """The main method that creates all necessary entities for the example. - - Args: - client: an initialized GoogleAdsClient instance. - customer_id: a client customer ID. - ad_group_id: an ad group ID. - phone_number: a phone number for your business, e.g. '(800) 555-0100'. - phone_country: a two-letter ISO-3166 code. - conversion_action_id: an ID for a conversion action. - """ - googleads_service: GoogleAdsServiceClient = client.get_service( - "GoogleAdsService" - ) - operation: AdGroupAdOperation = client.get_type("AdGroupAdOperation") - ad_group_ad: AdGroupAd = operation.create - ad_group_ad.ad_group = googleads_service.ad_group_path( - customer_id, ad_group_id - ) - ad_group_ad.status = client.enums.AdGroupAdStatusEnum.PAUSED - ad: Ad = ad_group_ad.ad - # The URL of the webpage to refer to. - ad.final_urls.append("https://www.example.com") - # Sets basic information. - ad.call_ad.business_name = "Google" - ad.call_ad.headline1 = "Travel" - ad.call_ad.headline2 = "Discover" - ad.call_ad.description1 = "Travel the World" - ad.call_ad.description2 = "Travel the Universe" - # Sets the country code and phone number of the business to call. - ad.call_ad.country_code = phone_country - ad.call_ad.phone_number = phone_number - # Sets the verification URL to a webpage that includes the phone number. - ad.call_ad.phone_number_verification_url = "https://www.example.com/contact" - - # The fields below are optional. - # Configures call tracking and reporting. - ad.call_ad.call_tracked = True - ad.call_ad.disable_call_conversion = False - # Sets path parts to append for display. - ad.call_ad.path1 = "services" - ad.call_ad.path2 = "travels" - - # Sets the conversion action ID if provided. - if conversion_action_id: - ad.call_ad.conversion_action = googleads_service.conversion_action_path( - customer_id, conversion_action_id - ) - ad.call_ad.conversion_reporting_state = ( - client.enums.CallConversionReportingStateEnum.USE_RESOURCE_LEVEL_CALL_CONVERSION_ACTION - ) - - # Issues a mutate request to add the ad group ad. - ad_group_ad_service: AdGroupAdServiceClient = client.get_service( - "AdGroupAdService" - ) - response: MutateAdGroupAdsResponse = ( - ad_group_ad_service.mutate_ad_group_ads( - customer_id=customer_id, operations=[operation] - ) - ) - resource_name: str = response.results[0].resource_name - print(f"Created ad group ad with resource name: '{resource_name}'") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description=("Adds a call extension to a specific account.") - ) - # The following argument(s) should be provided to run the example. - parser.add_argument( - "-c", - "--customer_id", - type=str, - required=True, - help="The Google Ads customer ID.", - ) - parser.add_argument( - "-a", - "--ad_group_id", - type=str, - required=True, - help="An ad group ID.", - ) - parser.add_argument( - "-n", - "--phone_number", - type=str, - required=True, - help=("A phone number for your business, e.g. '(800) 555-0100'"), - ) - parser.add_argument( - "-p", - "--phone_country", - type=str, - default=_DEFAULT_PHONE_COUNTRY, - help=( - "A two-letter ISO-3166 code representing a country code, for a " - "list of all codes see: " - "https://developers.google.com/google-ads/api/reference/data/codes-formats#expandable-17" - ), - ) - parser.add_argument( - "-v", - "--conversion_action_id", - type=str, - help=("An optional conversion action ID to attribute conversions to."), - ) - - args: argparse.Namespace = parser.parse_args() - - # GoogleAdsClient will read the google-ads.yaml configuration file in the - # home directory if none is specified. - googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" - ) - - try: - main( - googleads_client, - args.customer_id, - args.ad_group_id, - args.phone_number, - args.phone_country, - args.conversion_action_id, - ) - except GoogleAdsException as ex: - print( - f'Request with ID "{ex.request_id}" failed with status ' - f'"{ex.error.code().name}" and includes the following errors:' - ) - for error in ex.failure.errors: - print(f'Error with message "{error.message}".') - if error.location: - for field_path_element in error.location.field_path_elements: - print(f"\t\tOn field: {field_path_element.field_name}") - sys.exit(1) diff --git a/examples/advanced_operations/add_demand_gen_campaign.py b/examples/advanced_operations/add_demand_gen_campaign.py index e7812b07f..3ef6b955e 100644 --- a/examples/advanced_operations/add_demand_gen_campaign.py +++ b/examples/advanced_operations/add_demand_gen_campaign.py @@ -25,13 +25,13 @@ from examples.utils.example_helpers import get_image_bytes_from_url from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types import ( +from google.ads.googleads.v23.common.types import ( AdImageAsset, AdTextAsset, AdVideoAsset, DemandGenVideoResponsiveAdInfo, ) -from google.ads.googleads.v22.resources.types import ( +from google.ads.googleads.v23.resources.types import ( Ad, AdGroup, AdGroupAd, @@ -39,10 +39,10 @@ Campaign, CampaignBudget, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types import ( +from google.ads.googleads.v23.services.types import ( AdGroupAdOperation, AdGroupOperation, AssetOperation, @@ -430,7 +430,7 @@ def create_video_asset_operation( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/add_display_upload_ad.py b/examples/advanced_operations/add_display_upload_ad.py index 6210f35bc..5802561e4 100644 --- a/examples/advanced_operations/add_display_upload_ad.py +++ b/examples/advanced_operations/add_display_upload_ad.py @@ -25,20 +25,20 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad import Ad -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.resources.types.ad import Ad +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.services.services.asset_service import ( +from google.ads.googleads.v23.services.services.asset_service import ( AssetServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, MutateAdGroupAdsResponse, ) -from google.ads.googleads.v22.services.types.asset_service import ( +from google.ads.googleads.v23.services.types.asset_service import ( AssetOperation, MutateAssetsResponse, ) @@ -197,7 +197,7 @@ def create_display_upload_ad_group_ad( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/add_dynamic_page_feed_asset.py b/examples/advanced_operations/add_dynamic_page_feed_asset.py index 8fee6d856..185e93f98 100755 --- a/examples/advanced_operations/add_dynamic_page_feed_asset.py +++ b/examples/advanced_operations/add_dynamic_page_feed_asset.py @@ -21,56 +21,56 @@ from examples.utils.example_helpers import get_printable_datetime from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.asset_types import PageFeedAsset -from google.ads.googleads.v22.common.types.criteria import WebpageConditionInfo -from google.ads.googleads.v22.resources.types.ad_group_criterion import ( +from google.ads.googleads.v23.common.types.asset_types import PageFeedAsset +from google.ads.googleads.v23.common.types.criteria import WebpageConditionInfo +from google.ads.googleads.v23.resources.types.ad_group_criterion import ( AdGroupCriterion, ) -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.resources.types.asset_set import AssetSet -from google.ads.googleads.v22.resources.types.asset_set_asset import ( +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.resources.types.asset_set import AssetSet +from google.ads.googleads.v23.resources.types.asset_set_asset import ( AssetSetAsset, ) -from google.ads.googleads.v22.resources.types.campaign_asset_set import ( +from google.ads.googleads.v23.resources.types.campaign_asset_set import ( CampaignAssetSet, ) -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.asset_service import ( +from google.ads.googleads.v23.services.services.asset_service import ( AssetServiceClient, ) -from google.ads.googleads.v22.services.services.asset_set_asset_service import ( +from google.ads.googleads.v23.services.services.asset_set_asset_service import ( AssetSetAssetServiceClient, ) -from google.ads.googleads.v22.services.services.asset_set_service import ( +from google.ads.googleads.v23.services.services.asset_set_service import ( AssetSetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_asset_set_service import ( +from google.ads.googleads.v23.services.services.campaign_asset_set_service import ( CampaignAssetSetServiceClient, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, MutateAdGroupCriteriaResponse, ) -from google.ads.googleads.v22.services.types.asset_service import ( +from google.ads.googleads.v23.services.types.asset_service import ( AssetOperation, MutateAssetResult, MutateAssetsResponse, ) -from google.ads.googleads.v22.services.types.asset_set_asset_service import ( +from google.ads.googleads.v23.services.types.asset_set_asset_service import ( AssetSetAssetOperation, MutateAssetSetAssetResult, MutateAssetSetAssetsResponse, ) -from google.ads.googleads.v22.services.types.asset_set_service import ( +from google.ads.googleads.v23.services.types.asset_set_service import ( AssetSetOperation, MutateAssetSetsResponse, ) -from google.ads.googleads.v22.services.types.campaign_asset_set_service import ( +from google.ads.googleads.v23.services.types.campaign_asset_set_service import ( CampaignAssetSetOperation, MutateCampaignAssetSetsResponse, ) @@ -387,7 +387,7 @@ def add_dsa_target( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/add_dynamic_search_ads.py b/examples/advanced_operations/add_dynamic_search_ads.py index 5d78eb8e9..c1e744fd6 100755 --- a/examples/advanced_operations/add_dynamic_search_ads.py +++ b/examples/advanced_operations/add_dynamic_search_ads.py @@ -25,48 +25,48 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.criteria import WebpageConditionInfo -from google.ads.googleads.v22.resources.types.ad_group import AdGroup -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.resources.types.ad_group_criterion import ( +from google.ads.googleads.v23.common.types.criteria import WebpageConditionInfo +from google.ads.googleads.v23.resources.types.ad_group import AdGroup +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.resources.types.ad_group_criterion import ( AdGroupCriterion, ) -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.resources.types.campaign_budget import ( +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign_budget import ( CampaignBudget, ) -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_budget_service import ( +from google.ads.googleads.v23.services.services.campaign_budget_service import ( CampaignBudgetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, MutateAdGroupAdsResponse, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, MutateAdGroupCriteriaResponse, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, MutateAdGroupsResponse, ) -from google.ads.googleads.v22.services.types.campaign_budget_service import ( +from google.ads.googleads.v23.services.types.campaign_budget_service import ( CampaignBudgetOperation, MutateCampaignBudgetsResponse, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, MutateCampaignsResponse, ) @@ -171,10 +171,10 @@ def create_campaign( # Optional: Sets the start and end dates for the campaign, beginning one day # from now and ending a month from now. - campaign.start_date = (datetime.now() + timedelta(days=1)).strftime( - "%Y%m%d" + campaign.start_date_time = (datetime.now() + timedelta(days=1)).strftime( + "%Y%m%d 00:00:00" ) - campaign.end_date = (datetime.now() + timedelta(days=30)).strftime("%Y%m%d") + campaign.end_date_time = (datetime.now() + timedelta(days=30)).strftime("%Y%m%d 23:59:59") # Retrieve the campaign service. campaign_service: CampaignServiceClient = client.get_service( @@ -364,7 +364,7 @@ def add_webpage_criterion( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/add_performance_max_campaign.py b/examples/advanced_operations/add_performance_max_campaign.py index 6c980068d..8753ce203 100644 --- a/examples/advanced_operations/add_performance_max_campaign.py +++ b/examples/advanced_operations/add_performance_max_campaign.py @@ -38,46 +38,46 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException from google.ads.googleads.util import convert_snake_case_to_upper_case -from google.ads.googleads.v22.enums.types.asset_field_type import ( +from google.ads.googleads.v23.enums.types.asset_field_type import ( AssetFieldTypeEnum, ) -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.resources.types.asset_group import AssetGroup -from google.ads.googleads.v22.resources.types.asset_group_asset import ( +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.resources.types.asset_group import AssetGroup +from google.ads.googleads.v23.resources.types.asset_group_asset import ( AssetGroupAsset, ) -from google.ads.googleads.v22.resources.types.asset_group_signal import ( +from google.ads.googleads.v23.resources.types.asset_group_signal import ( AssetGroupSignal, ) -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.resources.types.campaign_asset import ( +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign_asset import ( CampaignAsset, ) -from google.ads.googleads.v22.resources.types.campaign_budget import ( +from google.ads.googleads.v23.resources.types.campaign_budget import ( CampaignBudget, ) -from google.ads.googleads.v22.resources.types.campaign_criterion import ( +from google.ads.googleads.v23.resources.types.campaign_criterion import ( CampaignCriterion, ) -from google.ads.googleads.v22.services.services.asset_group_service import ( +from google.ads.googleads.v23.services.services.asset_group_service import ( AssetGroupServiceClient, ) -from google.ads.googleads.v22.services.services.asset_service import ( +from google.ads.googleads.v23.services.services.asset_service import ( AssetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.services.geo_target_constant_service import ( +from google.ads.googleads.v23.services.services.geo_target_constant_service import ( GeoTargetConstantServiceClient, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_budget_service import ( +from google.ads.googleads.v23.services.types.campaign_budget_service import ( CampaignBudgetOperation, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( MutateGoogleAdsResponse, MutateOperation, MutateOperationResponse, @@ -318,8 +318,8 @@ def create_performance_max_campaign_operation( ) # Optional fields - campaign.start_date = (datetime.now() + timedelta(1)).strftime("%Y%m%d") - campaign.end_date = (datetime.now() + timedelta(365)).strftime("%Y%m%d") + campaign.start_date_time = (datetime.now() + timedelta(1)).strftime("%Y%m%d 00:00:00") + campaign.end_date_time = (datetime.now() + timedelta(365)).strftime("%Y%m%d 23:59:59") # [START add_pmax_asset_automation_settings] # Configures the optional opt-in/out status for asset automation settings. @@ -969,7 +969,7 @@ def create_asset_group_signal_operations( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/add_responsive_search_ad_full.py b/examples/advanced_operations/add_responsive_search_ad_full.py index 93a20a072..da29511fc 100644 --- a/examples/advanced_operations/add_responsive_search_ad_full.py +++ b/examples/advanced_operations/add_responsive_search_ad_full.py @@ -29,88 +29,88 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.ad_asset import AdTextAsset -from google.ads.googleads.v22.enums.types.served_asset_field_type import ( +from google.ads.googleads.v23.common.types.ad_asset import AdTextAsset +from google.ads.googleads.v23.enums.types.served_asset_field_type import ( ServedAssetFieldTypeEnum, ) -from google.ads.googleads.v22.resources.types.ad_group import AdGroup -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.resources.types.ad_group_criterion import ( +from google.ads.googleads.v23.resources.types.ad_group import AdGroup +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.resources.types.ad_group_criterion import ( AdGroupCriterion, ) -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.resources.types.campaign_budget import ( +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign_budget import ( CampaignBudget, ) -from google.ads.googleads.v22.resources.types.campaign_criterion import ( +from google.ads.googleads.v23.resources.types.campaign_criterion import ( CampaignCriterion, ) -from google.ads.googleads.v22.resources.types.customer_customizer import ( +from google.ads.googleads.v23.resources.types.customer_customizer import ( CustomerCustomizer, ) -from google.ads.googleads.v22.resources.types.customizer_attribute import ( +from google.ads.googleads.v23.resources.types.customizer_attribute import ( CustomizerAttribute, ) -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_budget_service import ( +from google.ads.googleads.v23.services.services.campaign_budget_service import ( CampaignBudgetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_criterion_service import ( +from google.ads.googleads.v23.services.services.campaign_criterion_service import ( CampaignCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.services.customer_customizer_service import ( +from google.ads.googleads.v23.services.services.customer_customizer_service import ( CustomerCustomizerServiceClient, ) -from google.ads.googleads.v22.services.services.customizer_attribute_service import ( +from google.ads.googleads.v23.services.services.customizer_attribute_service import ( CustomizerAttributeServiceClient, ) -from google.ads.googleads.v22.services.services.geo_target_constant_service import ( +from google.ads.googleads.v23.services.services.geo_target_constant_service import ( GeoTargetConstantServiceClient, ) -from google.ads.googleads.v22.services.types.geo_target_constant_service import ( +from google.ads.googleads.v23.services.types.geo_target_constant_service import ( SuggestGeoTargetConstantsRequest, SuggestGeoTargetConstantsResponse, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, MutateAdGroupAdsResponse, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, MutateAdGroupCriteriaResponse, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, MutateAdGroupsResponse, ) -from google.ads.googleads.v22.services.types.campaign_budget_service import ( +from google.ads.googleads.v23.services.types.campaign_budget_service import ( CampaignBudgetOperation, MutateCampaignBudgetsResponse, ) -from google.ads.googleads.v22.services.types.campaign_criterion_service import ( +from google.ads.googleads.v23.services.types.campaign_criterion_service import ( CampaignCriterionOperation, MutateCampaignCriteriaResponse, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, MutateCampaignsResponse, ) -from google.ads.googleads.v22.services.types.customer_customizer_service import ( +from google.ads.googleads.v23.services.types.customer_customizer_service import ( CustomerCustomizerOperation, MutateCustomerCustomizersResponse, ) -from google.ads.googleads.v22.services.types.customizer_attribute_service import ( +from google.ads.googleads.v23.services.types.customizer_attribute_service import ( CustomizerAttributeOperation, MutateCustomizerAttributesResponse, ) @@ -397,11 +397,11 @@ def create_campaign( # # Optional: Set the start date. # start_time = datetime.date.today() + datetime.timedelta(days=1) - # campaign.start_date = datetime.date.strftime(start_time, _DATE_FORMAT) + # campaign.start_date_time = datetime.date.strftime(start_time, "%Y%m%d 00:00:00") # # Optional: Set the end date. # end_time = start_time + datetime.timedelta(weeks=4) - # campaign.end_date = datetime.date.strftime(end_time, _DATE_FORMAT) + # campaign.end_date_time = datetime.date.strftime(end_time, "%Y%m%d 23:59:59") # Add the campaign. campaign_response: MutateCampaignsResponse = ( @@ -748,7 +748,7 @@ def add_geo_targeting( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/add_smart_campaign.py b/examples/advanced_operations/add_smart_campaign.py index 2dd1ccaa7..221298abc 100755 --- a/examples/advanced_operations/add_smart_campaign.py +++ b/examples/advanced_operations/add_smart_campaign.py @@ -25,70 +25,70 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.ad_asset import AdTextAsset -from google.ads.googleads.v22.common.types.ad_type_infos import ( +from google.ads.googleads.v23.common.types.ad_asset import AdTextAsset +from google.ads.googleads.v23.common.types.ad_type_infos import ( SmartCampaignAdInfo, ) -from google.ads.googleads.v22.common.types.criteria import ( +from google.ads.googleads.v23.common.types.criteria import ( AdScheduleInfo, KeywordThemeInfo, LocationInfo, ) -from google.ads.googleads.v22.resources.types.ad_group import AdGroup -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.resources.types.campaign_budget import ( +from google.ads.googleads.v23.resources.types.ad_group import AdGroup +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign_budget import ( CampaignBudget, ) -from google.ads.googleads.v22.resources.types.campaign_criterion import ( +from google.ads.googleads.v23.resources.types.campaign_criterion import ( CampaignCriterion, ) -from google.ads.googleads.v22.resources.types.keyword_theme_constant import ( +from google.ads.googleads.v23.resources.types.keyword_theme_constant import ( KeywordThemeConstant, ) -from google.ads.googleads.v22.resources.types.smart_campaign_setting import ( +from google.ads.googleads.v23.resources.types.smart_campaign_setting import ( SmartCampaignSetting, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, ) -from google.ads.googleads.v22.services.types.campaign_budget_service import ( +from google.ads.googleads.v23.services.types.campaign_budget_service import ( CampaignBudgetOperation, ) -from google.ads.googleads.v22.services.types.campaign_criterion_service import ( +from google.ads.googleads.v23.services.types.campaign_criterion_service import ( CampaignCriterionOperation, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.enums.types.minute_of_hour import ( +from google.ads.googleads.v23.enums.types.minute_of_hour import ( MinuteOfHourEnum, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( MutateGoogleAdsResponse, MutateOperation, MutateOperationResponse, ) -from google.ads.googleads.v22.services.services.keyword_theme_constant_service import ( +from google.ads.googleads.v23.services.services.keyword_theme_constant_service import ( KeywordThemeConstantServiceClient, ) -from google.ads.googleads.v22.services.types.keyword_theme_constant_service import ( +from google.ads.googleads.v23.services.types.keyword_theme_constant_service import ( SuggestKeywordThemeConstantsRequest, SuggestKeywordThemeConstantsResponse, ) -from google.ads.googleads.v22.services.services.smart_campaign_suggest_service import ( +from google.ads.googleads.v23.services.services.smart_campaign_suggest_service import ( SmartCampaignSuggestServiceClient, ) -from google.ads.googleads.v22.services.types.smart_campaign_suggest_service import ( +from google.ads.googleads.v23.services.types.smart_campaign_suggest_service import ( SmartCampaignSuggestionInfo, SuggestKeywordThemesResponse, SuggestKeywordThemesRequest, @@ -97,7 +97,7 @@ SuggestSmartCampaignBudgetOptionsResponse, SuggestSmartCampaignBudgetOptionsRequest, ) -from google.ads.googleads.v22.services.types.smart_campaign_setting_service import ( +from google.ads.googleads.v23.services.types.smart_campaign_setting_service import ( SmartCampaignSettingOperation, ) from google.api_core import protobuf_helpers @@ -1064,7 +1064,7 @@ def print_response_details(response: MutateGoogleAdsResponse) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/create_and_attach_shared_keyword_set.py b/examples/advanced_operations/create_and_attach_shared_keyword_set.py index 09ba27b84..18341d038 100755 --- a/examples/advanced_operations/create_and_attach_shared_keyword_set.py +++ b/examples/advanced_operations/create_and_attach_shared_keyword_set.py @@ -25,36 +25,36 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.errors.types.errors import GoogleAdsError -from google.ads.googleads.v22.resources.types.campaign_shared_set import ( +from google.ads.googleads.v23.errors.types.errors import GoogleAdsError +from google.ads.googleads.v23.resources.types.campaign_shared_set import ( CampaignSharedSet, ) -from google.ads.googleads.v22.resources.types.shared_criterion import ( +from google.ads.googleads.v23.resources.types.shared_criterion import ( SharedCriterion, ) -from google.ads.googleads.v22.resources.types.shared_set import SharedSet -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.resources.types.shared_set import SharedSet +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_shared_set_service import ( +from google.ads.googleads.v23.services.services.campaign_shared_set_service import ( CampaignSharedSetServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_shared_set_service import ( +from google.ads.googleads.v23.services.types.campaign_shared_set_service import ( CampaignSharedSetOperation, MutateCampaignSharedSetsResponse, ) -from google.ads.googleads.v22.services.services.shared_criterion_service import ( +from google.ads.googleads.v23.services.services.shared_criterion_service import ( SharedCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.shared_set_service import ( +from google.ads.googleads.v23.services.services.shared_set_service import ( SharedSetServiceClient, ) -from google.ads.googleads.v22.services.types.shared_criterion_service import ( +from google.ads.googleads.v23.services.types.shared_criterion_service import ( MutateSharedCriteriaResponse, MutateSharedCriterionResult, SharedCriterionOperation, ) -from google.ads.googleads.v22.services.types.shared_set_service import ( +from google.ads.googleads.v23.services.types.shared_set_service import ( MutateSharedSetsResponse, SharedSetOperation, ) @@ -187,7 +187,7 @@ def handle_googleads_exception(exception: GoogleAdsException) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) main(googleads_client, args.customer_id, args.campaign_id) diff --git a/examples/advanced_operations/find_and_remove_criteria_from_shared_set.py b/examples/advanced_operations/find_and_remove_criteria_from_shared_set.py index e3eecad74..f8e1737d6 100755 --- a/examples/advanced_operations/find_and_remove_criteria_from_shared_set.py +++ b/examples/advanced_operations/find_and_remove_criteria_from_shared_set.py @@ -21,27 +21,27 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.criteria import KeywordInfo -from google.ads.googleads.v22.enums.types.criterion_type import ( +from google.ads.googleads.v23.common.types.criteria import KeywordInfo +from google.ads.googleads.v23.enums.types.criterion_type import ( CriterionTypeEnum, ) -from google.ads.googleads.v22.errors.types.errors import GoogleAdsError -from google.ads.googleads.v22.resources.types.shared_criterion import ( +from google.ads.googleads.v23.errors.types.errors import GoogleAdsError +from google.ads.googleads.v23.resources.types.shared_criterion import ( SharedCriterion, ) -from google.ads.googleads.v22.resources.types.shared_set import SharedSet -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.resources.types.shared_set import SharedSet +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.services.shared_criterion_service import ( +from google.ads.googleads.v23.services.services.shared_criterion_service import ( SharedCriterionServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( GoogleAdsRow, SearchGoogleAdsRequest, SearchGoogleAdsResponse, ) -from google.ads.googleads.v22.services.types.shared_criterion_service import ( +from google.ads.googleads.v23.services.types.shared_criterion_service import ( MutateSharedCriteriaResponse, MutateSharedCriterionResult, SharedCriterionOperation, @@ -189,7 +189,7 @@ def handle_googleads_exception(exception: GoogleAdsException) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) main(googleads_client, args.customer_id, args.campaign_id) diff --git a/examples/advanced_operations/get_ad_group_bid_modifiers.py b/examples/advanced_operations/get_ad_group_bid_modifiers.py index 229f761e9..faff1a433 100755 --- a/examples/advanced_operations/get_ad_group_bid_modifiers.py +++ b/examples/advanced_operations/get_ad_group_bid_modifiers.py @@ -21,13 +21,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad_group_bid_modifier import ( +from google.ads.googleads.v23.resources.types.ad_group_bid_modifier import ( AdGroupBidModifier, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( GoogleAdsRow, SearchGoogleAdsRequest, SearchGoogleAdsResponse, @@ -137,7 +137,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/use_cross_account_bidding_strategy.py b/examples/advanced_operations/use_cross_account_bidding_strategy.py index 3bcb96c68..a4730348a 100755 --- a/examples/advanced_operations/use_cross_account_bidding_strategy.py +++ b/examples/advanced_operations/use_cross_account_bidding_strategy.py @@ -28,32 +28,32 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.bidding import TargetSpend -from google.ads.googleads.v22.resources.types.accessible_bidding_strategy import ( +from google.ads.googleads.v23.common.types.bidding import TargetSpend +from google.ads.googleads.v23.resources.types.accessible_bidding_strategy import ( AccessibleBiddingStrategy, ) -from google.ads.googleads.v22.resources.types.bidding_strategy import ( +from google.ads.googleads.v23.resources.types.bidding_strategy import ( BiddingStrategy, ) -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.services.services.bidding_strategy_service import ( +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.services.services.bidding_strategy_service import ( BiddingStrategyServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.bidding_strategy_service import ( +from google.ads.googleads.v23.services.types.bidding_strategy_service import ( BiddingStrategyOperation, MutateBiddingStrategiesResponse, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, MutateCampaignsResponse, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( GoogleAdsRow, SearchGoogleAdsStreamResponse, ) @@ -311,7 +311,7 @@ def attach_cross_account_bidding_strategy_to_campaign( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/advanced_operations/use_portfolio_bidding_strategy.py b/examples/advanced_operations/use_portfolio_bidding_strategy.py index 2a18c4d94..6fe3d7fd8 100755 --- a/examples/advanced_operations/use_portfolio_bidding_strategy.py +++ b/examples/advanced_operations/use_portfolio_bidding_strategy.py @@ -21,32 +21,32 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.bidding import TargetSpend -from google.ads.googleads.v22.resources.types.bidding_strategy import ( +from google.ads.googleads.v23.common.types.bidding import TargetSpend +from google.ads.googleads.v23.resources.types.bidding_strategy import ( BiddingStrategy, ) -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.resources.types.campaign_budget import ( +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign_budget import ( CampaignBudget, ) -from google.ads.googleads.v22.services.services.bidding_strategy_service import ( +from google.ads.googleads.v23.services.services.bidding_strategy_service import ( BiddingStrategyServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_budget_service import ( +from google.ads.googleads.v23.services.services.campaign_budget_service import ( CampaignBudgetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.bidding_strategy_service import ( +from google.ads.googleads.v23.services.types.bidding_strategy_service import ( BiddingStrategyOperation, MutateBiddingStrategiesResponse, ) -from google.ads.googleads.v22.services.types.campaign_budget_service import ( +from google.ads.googleads.v23.services.types.campaign_budget_service import ( CampaignBudgetOperation, MutateCampaignBudgetsResponse, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, MutateCampaignsResponse, ) @@ -187,7 +187,7 @@ def handle_googleads_exception(exception: GoogleAdsException) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) main(googleads_client, args.customer_id) diff --git a/examples/assets/add_call.py b/examples/assets/add_call.py index 6894249ab..ac6687af1 100755 --- a/examples/assets/add_call.py +++ b/examples/assets/add_call.py @@ -21,13 +21,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.types.asset_service import AssetOperation -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.common.types.criteria import AdScheduleInfo -from google.ads.googleads.v22.services.types.customer_asset_service import ( +from google.ads.googleads.v23.services.types.asset_service import AssetOperation +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.common.types.criteria import AdScheduleInfo +from google.ads.googleads.v23.services.types.customer_asset_service import ( CustomerAssetOperation, ) -from google.ads.googleads.v22.resources.types.customer_asset import ( +from google.ads.googleads.v23.resources.types.customer_asset import ( CustomerAsset, ) @@ -184,7 +184,7 @@ def link_asset_to_account( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/assets/add_hotel_callout.py b/examples/assets/add_hotel_callout.py index 4bc8bc0aa..3f355fd3f 100755 --- a/examples/assets/add_hotel_callout.py +++ b/examples/assets/add_hotel_callout.py @@ -22,12 +22,12 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.types.asset_service import AssetOperation -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.services.types.customer_asset_service import ( +from google.ads.googleads.v23.services.types.asset_service import AssetOperation +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.services.types.customer_asset_service import ( CustomerAssetOperation, ) -from google.ads.googleads.v22.resources.types.customer_asset import ( +from google.ads.googleads.v23.resources.types.customer_asset import ( CustomerAsset, ) @@ -155,7 +155,7 @@ def link_asset_to_account( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/assets/add_lead_form_asset.py b/examples/assets/add_lead_form_asset.py index a72af2448..3dfd33789 100755 --- a/examples/assets/add_lead_form_asset.py +++ b/examples/assets/add_lead_form_asset.py @@ -24,17 +24,17 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.types.asset_service import AssetOperation -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.common.types.asset_types import LeadFormAsset -from google.ads.googleads.v22.common.types.asset_types import LeadFormField -from google.ads.googleads.v22.common.types.asset_types import ( +from google.ads.googleads.v23.services.types.asset_service import AssetOperation +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.common.types.asset_types import LeadFormAsset +from google.ads.googleads.v23.common.types.asset_types import LeadFormField +from google.ads.googleads.v23.common.types.asset_types import ( LeadFormDeliveryMethod, ) -from google.ads.googleads.v22.services.types.campaign_asset_service import ( +from google.ads.googleads.v23.services.types.campaign_asset_service import ( CampaignAssetOperation, ) -from google.ads.googleads.v22.resources.types.campaign_asset import ( +from google.ads.googleads.v23.resources.types.campaign_asset import ( CampaignAsset, ) @@ -219,7 +219,7 @@ def create_lead_form_campaign_asset( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/assets/add_prices.py b/examples/assets/add_prices.py index 74718593a..e9dcfe7f5 100644 --- a/examples/assets/add_prices.py +++ b/examples/assets/add_prices.py @@ -22,17 +22,17 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.types.asset_service import AssetOperation -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.common.types.asset_types import PriceAsset -from google.ads.googleads.v22.common.types.asset_types import PriceOffering -from google.ads.googleads.v22.enums.types.price_extension_price_unit import ( +from google.ads.googleads.v23.services.types.asset_service import AssetOperation +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.common.types.asset_types import PriceAsset +from google.ads.googleads.v23.common.types.asset_types import PriceOffering +from google.ads.googleads.v23.enums.types.price_extension_price_unit import ( PriceExtensionPriceUnitEnum, ) -from google.ads.googleads.v22.services.types.customer_asset_service import ( +from google.ads.googleads.v23.services.types.customer_asset_service import ( CustomerAssetOperation, ) -from google.ads.googleads.v22.resources.types.customer_asset import ( +from google.ads.googleads.v23.resources.types.customer_asset import ( CustomerAsset, ) @@ -216,7 +216,7 @@ def add_asset_to_account( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/assets/add_sitelinks.py b/examples/assets/add_sitelinks.py index 04414a70a..96deaa048 100755 --- a/examples/assets/add_sitelinks.py +++ b/examples/assets/add_sitelinks.py @@ -23,12 +23,12 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.types.asset_service import AssetOperation -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.services.types.campaign_asset_service import ( +from google.ads.googleads.v23.services.types.asset_service import AssetOperation +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.services.types.campaign_asset_service import ( CampaignAssetOperation, ) -from google.ads.googleads.v22.resources.types.campaign_asset import ( +from google.ads.googleads.v23.resources.types.campaign_asset import ( CampaignAsset, ) @@ -175,7 +175,7 @@ def link_sitelinks_to_campaign( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/assets/upload_image_asset.py b/examples/assets/upload_image_asset.py index 8ada15878..08aff07e5 100644 --- a/examples/assets/upload_image_asset.py +++ b/examples/assets/upload_image_asset.py @@ -24,8 +24,8 @@ from examples.utils.example_helpers import get_image_bytes_from_url from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.types.asset_service import AssetOperation -from google.ads.googleads.v22.resources.types.asset import Asset +from google.ads.googleads.v23.services.types.asset_service import AssetOperation +from google.ads.googleads.v23.resources.types.asset import Asset # [START upload_image_asset] @@ -79,7 +79,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/asyncio/async_add_campaigns.py b/examples/asyncio/async_add_campaigns.py index 69d8d9455..b06818833 100644 --- a/examples/asyncio/async_add_campaigns.py +++ b/examples/asyncio/async_add_campaigns.py @@ -24,23 +24,24 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.resources.types.campaign_budget import ( +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign_budget import ( CampaignBudget, ) -from google.ads.googleads.v22.services.types.campaign_budget_service import ( +from google.ads.googleads.v23.services.types.campaign_budget_service import ( CampaignBudgetOperation, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( MutateGoogleAdsResponse, MutateOperation, ) -_DATE_FORMAT: str = "%Y%m%d" +_START_DATE_FORMAT: str = "%Y%m%d 00:00:00" +_END_DATE_FORMAT: str = "%Y%m%d 23:59:59" async def main(client: GoogleAdsClient, customer_id: str) -> None: @@ -110,11 +111,11 @@ async def main(client: GoogleAdsClient, customer_id: str) -> None: start_time: datetime.date = datetime.date.today() + datetime.timedelta( days=1 ) - campaign.start_date = datetime.date.strftime(start_time, _DATE_FORMAT) + campaign.start_date_time = datetime.date.strftime(start_time, _START_DATE_FORMAT) # Optional: Set the end date. end_time: datetime.date = start_time + datetime.timedelta(weeks=4) - campaign.end_date = datetime.date.strftime(end_time, _DATE_FORMAT) + campaign.end_date_time = datetime.date.strftime(end_time, _END_DATE_FORMAT) # [END add_campaigns_1] mutate_operation_campaign: MutateOperation = client.get_type( @@ -151,7 +152,7 @@ async def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/asyncio/async_search.py b/examples/asyncio/async_search.py index c0524b023..9e6d0a60c 100755 --- a/examples/asyncio/async_search.py +++ b/examples/asyncio/async_search.py @@ -22,10 +22,10 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceAsyncClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( GoogleAdsRow, ) @@ -71,7 +71,7 @@ async def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/asyncio/async_search_stream.py b/examples/asyncio/async_search_stream.py index 913e0730a..1d1ef1edd 100755 --- a/examples/asyncio/async_search_stream.py +++ b/examples/asyncio/async_search_stream.py @@ -22,10 +22,10 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceAsyncClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( GoogleAdsRow, ) @@ -72,7 +72,7 @@ async def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/audience_insights/generate_audience_insights.py b/examples/audience_insights/generate_audience_insights.py index 31c9f820d..ea76a2a54 100644 --- a/examples/audience_insights/generate_audience_insights.py +++ b/examples/audience_insights/generate_audience_insights.py @@ -20,16 +20,16 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.enums.types import ( +from google.ads.googleads.v23.enums.types import ( AudienceInsightsDimensionEnum, ) -from google.ads.googleads.v22.services.services.audience_insights_service import ( +from google.ads.googleads.v23.services.services.audience_insights_service import ( AudienceInsightsServiceClient, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.audience_insights_service import ( +from google.ads.googleads.v23.services.types.audience_insights_service import ( GenerateAudienceCompositionInsightsRequest, GenerateAudienceCompositionInsightsResponse, GenerateSuggestedTargetingInsightsRequest, @@ -38,7 +38,7 @@ ListAudienceInsightsAttributesRequest, ListAudienceInsightsAttributesResponse, ) -from google.ads.googleads.v22.common.types import ( +from google.ads.googleads.v23.common.types import ( AudienceInsightsAttribute, LocationInfo, ) @@ -271,7 +271,7 @@ def list_audience_insights_attributes( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/basic_operations/add_ad_groups.py b/examples/basic_operations/add_ad_groups.py index af13d0904..ed78bdbc0 100755 --- a/examples/basic_operations/add_ad_groups.py +++ b/examples/basic_operations/add_ad_groups.py @@ -25,17 +25,17 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, MutateAdGroupsResponse, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.resources.types.ad_group import AdGroup +from google.ads.googleads.v23.resources.types.ad_group import AdGroup def main(client: GoogleAdsClient, customer_id: str, campaign_id: str) -> None: @@ -87,7 +87,7 @@ def main(client: GoogleAdsClient, customer_id: str, campaign_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/basic_operations/add_campaigns.py b/examples/basic_operations/add_campaigns.py index 78aebc365..20043136e 100755 --- a/examples/basic_operations/add_campaigns.py +++ b/examples/basic_operations/add_campaigns.py @@ -26,27 +26,28 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.campaign_budget_service import ( +from google.ads.googleads.v23.services.services.campaign_budget_service import ( CampaignBudgetServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_budget_service import ( +from google.ads.googleads.v23.services.types.campaign_budget_service import ( CampaignBudgetOperation, MutateCampaignBudgetsResponse, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, MutateCampaignsResponse, ) -from google.ads.googleads.v22.resources.types.campaign_budget import ( +from google.ads.googleads.v23.resources.types.campaign_budget import ( CampaignBudget, ) -from google.ads.googleads.v22.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign import Campaign -_DATE_FORMAT: str = "%Y%m%d" +_START_DATE_FORMAT: str = "%Y%m%d 00:00:00" +_END_DATE_FORMAT: str = "%Y%m%d 23:59:59" def main(client: GoogleAdsClient, customer_id: str) -> None: @@ -126,11 +127,11 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: start_time: datetime.date = datetime.date.today() + datetime.timedelta( days=1 ) - campaign.start_date = datetime.date.strftime(start_time, _DATE_FORMAT) + campaign.start_date_time = datetime.date.strftime(start_time, _START_DATE_FORMAT) # Optional: Set the end date. end_time: datetime.date = start_time + datetime.timedelta(weeks=4) - campaign.end_date = datetime.date.strftime(end_time, _DATE_FORMAT) + campaign.end_date_time = datetime.date.strftime(end_time, _END_DATE_FORMAT) # [END add_campaigns_1] # Add the campaign. @@ -175,7 +176,7 @@ def handle_googleads_exception(exception: GoogleAdsException) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) main(googleads_client, args.customer_id) diff --git a/examples/basic_operations/get_campaigns.py b/examples/basic_operations/get_campaigns.py index 798556541..d3844903d 100755 --- a/examples/basic_operations/get_campaigns.py +++ b/examples/basic_operations/get_campaigns.py @@ -24,10 +24,10 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchGoogleAdsStreamResponse, GoogleAdsRow, ) @@ -76,7 +76,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/basic_operations/get_responsive_search_ads.py b/examples/basic_operations/get_responsive_search_ads.py index 85e47cf45..d3e1ca8ac 100755 --- a/examples/basic_operations/get_responsive_search_ads.py +++ b/examples/basic_operations/get_responsive_search_ads.py @@ -24,12 +24,12 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.ad_asset import AdTextAsset -from google.ads.googleads.v22.resources.types.ad import Ad -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.common.types.ad_asset import AdTextAsset +from google.ads.googleads.v23.resources.types.ad import Ad +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchGoogleAdsRequest, SearchGoogleAdsResponse, ) @@ -123,7 +123,7 @@ def ad_text_assets_to_strs(assets: Sequence[AdTextAsset]) -> List[str]: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/basic_operations/pause_ad.py b/examples/basic_operations/pause_ad.py index f81abcee6..24629fd75 100755 --- a/examples/basic_operations/pause_ad.py +++ b/examples/basic_operations/pause_ad.py @@ -23,11 +23,11 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, MutateAdGroupAdsResponse, ) @@ -94,7 +94,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/basic_operations/remove_campaign.py b/examples/basic_operations/remove_campaign.py index 0f45f7bb9..fa467a78d 100755 --- a/examples/basic_operations/remove_campaign.py +++ b/examples/basic_operations/remove_campaign.py @@ -21,10 +21,10 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, MutateCampaignsResponse, ) @@ -73,7 +73,7 @@ def main(client: GoogleAdsClient, customer_id: str, campaign_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/basic_operations/search_for_google_ads_fields.py b/examples/basic_operations/search_for_google_ads_fields.py index 642eaf624..3edf56462 100755 --- a/examples/basic_operations/search_for_google_ads_fields.py +++ b/examples/basic_operations/search_for_google_ads_fields.py @@ -26,13 +26,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.google_ads_field import ( +from google.ads.googleads.v23.resources.types.google_ads_field import ( GoogleAdsField, ) -from google.ads.googleads.v22.services.services.google_ads_field_service import ( +from google.ads.googleads.v23.services.services.google_ads_field_service import ( GoogleAdsFieldServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_field_service import ( +from google.ads.googleads.v23.services.types.google_ads_field_service import ( SearchGoogleAdsFieldsRequest, SearchGoogleAdsFieldsResponse, ) @@ -124,7 +124,7 @@ def main(client: GoogleAdsClient, name_prefix: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/basic_operations/update_ad_group.py b/examples/basic_operations/update_ad_group.py index 5050fc874..db6f55286 100755 --- a/examples/basic_operations/update_ad_group.py +++ b/examples/basic_operations/update_ad_group.py @@ -26,14 +26,14 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad_group import AdGroup -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.resources.types.ad_group import AdGroup +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, MutateAdGroupsResponse, ) @@ -107,7 +107,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/basic_operations/update_campaign.py b/examples/basic_operations/update_campaign.py index 1288ebc40..b54b5e306 100755 --- a/examples/basic_operations/update_campaign.py +++ b/examples/basic_operations/update_campaign.py @@ -26,11 +26,11 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, MutateCampaignsResponse, ) @@ -89,7 +89,7 @@ def main(client: GoogleAdsClient, customer_id: str, campaign_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/basic_operations/update_responsive_search_ad.py b/examples/basic_operations/update_responsive_search_ad.py index d32b04bdf..959578c40 100755 --- a/examples/basic_operations/update_responsive_search_ad.py +++ b/examples/basic_operations/update_responsive_search_ad.py @@ -27,12 +27,12 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.ad_asset import AdTextAsset -from google.ads.googleads.v22.resources.types.ad import Ad -from google.ads.googleads.v22.services.services.ad_service import ( +from google.ads.googleads.v23.common.types.ad_asset import AdTextAsset +from google.ads.googleads.v23.resources.types.ad import Ad +from google.ads.googleads.v23.services.services.ad_service import ( AdServiceClient, ) -from google.ads.googleads.v22.services.types.ad_service import ( +from google.ads.googleads.v23.services.types.ad_service import ( AdOperation, MutateAdsResponse, ) @@ -112,7 +112,7 @@ def main(client: GoogleAdsClient, customer_id: str, ad_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/billing/add_account_budget_proposal.py b/examples/billing/add_account_budget_proposal.py index b9247cdb1..eb0007dde 100755 --- a/examples/billing/add_account_budget_proposal.py +++ b/examples/billing/add_account_budget_proposal.py @@ -100,7 +100,7 @@ def main(client: GoogleAdsClient, customer_id: str, billing_setup_id: str): # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.customer_id, args.billing_setup_id) diff --git a/examples/billing/add_billing_setup.py b/examples/billing/add_billing_setup.py index a75a792c0..1601d49e2 100755 --- a/examples/billing/add_billing_setup.py +++ b/examples/billing/add_billing_setup.py @@ -231,7 +231,7 @@ def set_billing_setup_date_times( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main( diff --git a/examples/billing/get_invoices.py b/examples/billing/get_invoices.py index e99257a40..024a7addb 100755 --- a/examples/billing/get_invoices.py +++ b/examples/billing/get_invoices.py @@ -128,7 +128,7 @@ def micros_to_currency(micros: Optional[int]) -> Optional[float]: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.customer_id, args.billing_setup_id) diff --git a/examples/campaign_management/add_campaign_labels.py b/examples/campaign_management/add_campaign_labels.py index 837546c35..07bd768fd 100755 --- a/examples/campaign_management/add_campaign_labels.py +++ b/examples/campaign_management/add_campaign_labels.py @@ -23,19 +23,19 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.campaign_label_service import ( +from google.ads.googleads.v23.services.services.campaign_label_service import ( CampaignLabelServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.services.label_service import ( +from google.ads.googleads.v23.services.services.label_service import ( LabelServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_label_service import ( +from google.ads.googleads.v23.services.types.campaign_label_service import ( MutateCampaignLabelsResponse, ) -from google.ads.googleads.v22.resources.types.campaign_label import ( +from google.ads.googleads.v23.resources.types.campaign_label import ( CampaignLabel, ) @@ -127,7 +127,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: main( diff --git a/examples/campaign_management/add_complete_campaigns_using_batch_job.py b/examples/campaign_management/add_complete_campaigns_using_batch_job.py index 4e9e9d1cc..aff7063b5 100755 --- a/examples/campaign_management/add_complete_campaigns_using_batch_job.py +++ b/examples/campaign_management/add_complete_campaigns_using_batch_job.py @@ -28,38 +28,38 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.batch_job_service import ( +from google.ads.googleads.v23.services.services.batch_job_service import ( BatchJobServiceClient, ) -from google.ads.googleads.v22.services.types.batch_job_service import ( +from google.ads.googleads.v23.services.types.batch_job_service import ( MutateBatchJobResponse, AddBatchJobOperationsResponse, ListBatchJobResultsRequest, ListBatchJobResultsResponse, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( MutateOperation, ) -from google.ads.googleads.v22.resources.types.batch_job import BatchJob -from google.ads.googleads.v22.services.types.campaign_budget_service import ( +from google.ads.googleads.v23.resources.types.batch_job import BatchJob +from google.ads.googleads.v23.services.types.campaign_budget_service import ( CampaignBudgetOperation, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, ) -from google.ads.googleads.v22.services.types.campaign_criterion_service import ( +from google.ads.googleads.v23.services.types.campaign_criterion_service import ( CampaignCriterionOperation, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, ) -from google.ads.googleads.v22.services.types.batch_job_service import ( +from google.ads.googleads.v23.services.types.batch_job_service import ( BatchJobOperation, ) @@ -780,7 +780,7 @@ def handle_googleads_exception(exception: GoogleAdsException) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) asyncio.run(main(googleads_client, args.customer_id)) diff --git a/examples/campaign_management/create_experiment.py b/examples/campaign_management/create_experiment.py index 1cd775f79..be0f0517f 100644 --- a/examples/campaign_management/create_experiment.py +++ b/examples/campaign_management/create_experiment.py @@ -28,32 +28,32 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.types.experiment_service import ( +from google.ads.googleads.v23.services.types.experiment_service import ( ExperimentOperation, MutateExperimentsResponse, ) -from google.ads.googleads.v22.services.types.experiment_arm_service import ( +from google.ads.googleads.v23.services.types.experiment_arm_service import ( ExperimentArmOperation, MutateExperimentArmsRequest, MutateExperimentArmsResponse, ) -from google.ads.googleads.v22.resources.types.experiment import Experiment -from google.ads.googleads.v22.resources.types.experiment_arm import ( +from google.ads.googleads.v23.resources.types.experiment import Experiment +from google.ads.googleads.v23.resources.types.experiment_arm import ( ExperimentArm, ) -from google.ads.googleads.v22.services.services.experiment_service import ( +from google.ads.googleads.v23.services.services.experiment_service import ( ExperimentServiceClient, ) -from google.ads.googleads.v22.services.services.experiment_arm_service import ( +from google.ads.googleads.v23.services.services.experiment_arm_service import ( ExperimentArmServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, ) -from google.ads.googleads.v22.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign import Campaign def main( @@ -264,7 +264,7 @@ def modify_draft_campaign( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/campaign_management/get_all_disapproved_ads.py b/examples/campaign_management/get_all_disapproved_ads.py index 7df6db428..d4e02b8a9 100755 --- a/examples/campaign_management/get_all_disapproved_ads.py +++ b/examples/campaign_management/get_all_disapproved_ads.py @@ -20,16 +20,16 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchGoogleAdsRequest, SearchGoogleAdsResponse, ) -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.resources.types.ad import Ad -from google.ads.googleads.v22.enums.types.policy_approval_status import ( +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.resources.types.ad import Ad +from google.ads.googleads.v23.enums.types.policy_approval_status import ( PolicyApprovalStatusEnum, ) @@ -117,7 +117,7 @@ def main(client: GoogleAdsClient, customer_id: str, campaign_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/campaign_management/set_ad_parameters.py b/examples/campaign_management/set_ad_parameters.py index 29fbf64d8..10ca698fa 100755 --- a/examples/campaign_management/set_ad_parameters.py +++ b/examples/campaign_management/set_ad_parameters.py @@ -21,17 +21,17 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.ad_parameter_service import ( +from google.ads.googleads.v23.services.services.ad_parameter_service import ( AdParameterServiceClient, ) -from google.ads.googleads.v22.services.types.ad_parameter_service import ( +from google.ads.googleads.v23.services.types.ad_parameter_service import ( AdParameterOperation, MutateAdParametersResponse, ) -from google.ads.googleads.v22.resources.types.ad_parameter import AdParameter +from google.ads.googleads.v23.resources.types.ad_parameter import AdParameter def main( @@ -155,7 +155,7 @@ def create_ad_parameter( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) main( diff --git a/examples/campaign_management/update_campaign_criterion_bid_modifier.py b/examples/campaign_management/update_campaign_criterion_bid_modifier.py index cad5ad8e2..74cbaad02 100755 --- a/examples/campaign_management/update_campaign_criterion_bid_modifier.py +++ b/examples/campaign_management/update_campaign_criterion_bid_modifier.py @@ -21,14 +21,14 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.campaign_criterion_service import ( +from google.ads.googleads.v23.services.services.campaign_criterion_service import ( CampaignCriterionServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_criterion_service import ( +from google.ads.googleads.v23.services.types.campaign_criterion_service import ( CampaignCriterionOperation, MutateCampaignCriteriaResponse, ) -from google.ads.googleads.v22.resources.types.campaign_criterion import ( +from google.ads.googleads.v23.resources.types.campaign_criterion import ( CampaignCriterion, ) @@ -110,7 +110,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/campaign_management/validate_ad.py b/examples/campaign_management/validate_ad.py index af5b302aa..6a44daff6 100755 --- a/examples/campaign_management/validate_ad.py +++ b/examples/campaign_management/validate_ad.py @@ -26,22 +26,22 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, MutateAdGroupAdsRequest, ) -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.common.types.ad_type_infos import AdTextAsset -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.common.types.ad_type_infos import AdTextAsset +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.errors.types.policy_finding_error import ( +from google.ads.googleads.v23.errors.types.policy_finding_error import ( PolicyFindingErrorEnum, ) -from google.ads.googleads.v22.common.types.policy import PolicyTopicEntry +from google.ads.googleads.v23.common.types.policy import PolicyTopicEntry def main(client: GoogleAdsClient, customer_id: str, ad_group_id: str) -> None: @@ -163,7 +163,7 @@ def main(client: GoogleAdsClient, customer_id: str, ad_group_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) main(googleads_client, args.customer_id, args.ad_group_id) diff --git a/examples/custom_logging_interceptor/get_campaigns.py b/examples/custom_logging_interceptor/get_campaigns.py index 54b5cc605..b51cb1670 100755 --- a/examples/custom_logging_interceptor/get_campaigns.py +++ b/examples/custom_logging_interceptor/get_campaigns.py @@ -23,13 +23,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchGoogleAdsStreamResponse, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( GoogleAdsRow, ) @@ -40,7 +40,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # Instantiate the GoogleAdsService object with a custom interceptor. ga_service: GoogleAdsServiceClient = client.get_service( "GoogleAdsService", - interceptors=[CloudLoggingInterceptor(api_version="v22")], + interceptors=[CloudLoggingInterceptor(api_version="v23")], ) query: str = """ @@ -82,7 +82,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/error_handling/handle_keyword_policy_violations.py b/examples/error_handling/handle_keyword_policy_violations.py index 2125e4b58..36f725a36 100755 --- a/examples/error_handling/handle_keyword_policy_violations.py +++ b/examples/error_handling/handle_keyword_policy_violations.py @@ -31,13 +31,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, ) -from google.ads.googleads.v22.common.types.policy import PolicyViolationKey +from google.ads.googleads.v23.common.types.policy import PolicyViolationKey def main( @@ -282,7 +282,7 @@ def request_exemption( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) main( diff --git a/examples/error_handling/handle_partial_failure.py b/examples/error_handling/handle_partial_failure.py index c8a43b624..2dce99a5b 100755 --- a/examples/error_handling/handle_partial_failure.py +++ b/examples/error_handling/handle_partial_failure.py @@ -22,13 +22,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, MutateAdGroupsResponse, MutateAdGroupsRequest, @@ -249,7 +249,7 @@ def print_results( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) main(googleads_client, args.customer_id, args.campaign_id) diff --git a/examples/error_handling/handle_rate_exceeded_error.py b/examples/error_handling/handle_rate_exceeded_error.py index 5ed7ed720..205cfdbb6 100755 --- a/examples/error_handling/handle_rate_exceeded_error.py +++ b/examples/error_handling/handle_rate_exceeded_error.py @@ -29,14 +29,14 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.errors.types.quota_error import QuotaErrorEnum -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.errors.types.quota_error import QuotaErrorEnum +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, MutateAdGroupCriteriaRequest, MutateAdGroupCriteriaResponse, @@ -231,7 +231,7 @@ def request_mutate_and_display_result( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) main(googleads_client, args.customer_id, args.ad_group_id) diff --git a/examples/error_handling/handle_responsive_search_ad_policy_violations.py b/examples/error_handling/handle_responsive_search_ad_policy_violations.py index 4b5b7aee7..3f4bdacb2 100755 --- a/examples/error_handling/handle_responsive_search_ad_policy_violations.py +++ b/examples/error_handling/handle_responsive_search_ad_policy_violations.py @@ -25,24 +25,24 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, MutateAdGroupAdsResponse, ) -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.common.types.ad_type_infos import ( +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.common.types.ad_type_infos import ( ResponsiveSearchAdInfo, ) -from google.ads.googleads.v22.common.types.ad_asset import ( +from google.ads.googleads.v23.common.types.ad_asset import ( AdTextAsset, ) -from google.ads.googleads.v22.errors.types.policy_finding_error import ( +from google.ads.googleads.v23.errors.types.policy_finding_error import ( PolicyFindingErrorEnum, ) @@ -264,7 +264,7 @@ def request_exemption( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/incentives/apply_incentive.py b/examples/incentives/apply_incentive.py new file mode 100644 index 000000000..8a9acfe20 --- /dev/null +++ b/examples/incentives/apply_incentive.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""This example applies an incentive to a user's account. + +This example is a no-op if the user already has an accepted incentive. If the +user attempts to apply a new incentive, the response will simply return the +existing incentive that has already been applied to the account. Use the +fetch_incentives.py example to get the available incentives. +""" + + +import argparse +import sys + +from google.ads.googleads.client import GoogleAdsClient +from google.ads.googleads.errors import GoogleAdsException +from google.ads.googleads.v23.services import ApplyIncentiveRequest, ApplyIncentiveResponse +from google.ads.googleads.v23.services.services.incentive_service.client import ( + IncentiveServiceClient, +) + + +def main( + client: GoogleAdsClient, + customer_id: str, + incentive_id: str, + country_code: str = None, +) -> None: + """Applies an incentive for the ads customer. + + Args: + client: An initialized GoogleAdsClient instance. + customer_id: The client customer ID. + country_code: The country code of the user. + incentive_id: The incentive ID to select. + """ + incentive_service: IncentiveServiceClient = client.get_service("IncentiveService") + apply_incentive_request: ApplyIncentiveRequest = client.get_type( + "ApplyIncentiveRequest" + ) + + apply_incentive_request.customer_id = customer_id + apply_incentive_request.selected_incentive_id = incentive_id + + if country_code: + apply_incentive_request.country_code = country_code + + response: ApplyIncentiveResponse = incentive_service.apply_incentive( + request=apply_incentive_request + ) + + print("Applied incentive.") + print(f"Coupon Code: {response.coupon_code}") + print(f"Creation Time: {response.creation_time}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Applies an incentive for the ads customer." + ) + # The following argument(s) should be provided to run the example. + parser.add_argument( + "-c", + "--customer_id", + type=str, + required=True, + help="The Google Ads customer ID.", + ) + parser.add_argument( + "-i", + "--incentive_id", + type=int, + required=True, + help="The incentive ID to select.", + ) + parser.add_argument( + "-k", + "--country_code", + type=str, + required=False, + help="The country code of the user (e.g. 'US').", + ) + args = parser.parse_args() + + # GoogleAdsClient will read the google-ads.yaml configuration file in the + # home directory if none is specified. + googleads_client = GoogleAdsClient.load_from_storage(version="v23") + + try: + main( + googleads_client, + args.customer_id, + args.incentive_id, + args.country_code, + ) + except GoogleAdsException as ex: + print( + f'Request with ID "{ex.request_id}" failed with status ' + f'"{ex.error.code().name}" and includes the following errors:' + ) + for error in ex.failure.errors: + print(f'\tError with message "{error.message}".') + if error.location: + for field_path_element in error.location.field_path_elements: + print(f"\t\tOn field: {field_path_element.field_name}") + sys.exit(1) \ No newline at end of file diff --git a/examples/incentives/fetch_incentives.py b/examples/incentives/fetch_incentives.py new file mode 100644 index 000000000..47151ac55 --- /dev/null +++ b/examples/incentives/fetch_incentives.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""This example returns incentives for a given user. + +To apply an incentive, use apply_incentive.py. +""" + + +import argparse +import sys + +from google.ads.googleads.client import GoogleAdsClient +from google.ads.googleads.errors import GoogleAdsException +from google.ads.googleads.v23.services import FetchIncentiveRequest, FetchIncentiveResponse +from google.ads.googleads.v23.services.services.incentive_service.client import ( + IncentiveServiceClient, +) + + +def main( + client: GoogleAdsClient, + email_address: str, + language_code: str, + country_code: str, +) -> None: + """Returns incentives for a given user. + + Args: + client: An initialized GoogleAdsClient instance. + email_address: The email of the user to fetch incentives for. + language_code: The language code of the user (e.g. 'en'). + country_code: The country code of the user (e.g. 'US'). + """ + incentive_service: IncentiveServiceClient = client.get_service( + "IncentiveService" + ) + fetch_incentive_request: FetchIncentiveRequest = client.get_type( + "FetchIncentiveRequest" + ) + + fetch_incentive_request.email = email_address + fetch_incentive_request.language_code = language_code + fetch_incentive_request.country_code = country_code + + response: FetchIncentiveResponse = incentive_service.fetch_incentive( + request=fetch_incentive_request + ) + + if response.incentive_offer and response.incentive_offer.cyo_incentives: + print("Fetched incentive.") + # If the offer type is CHOOSE_YOUR_OWN_INCENTIVE, there will be three + # incentives in the response. At the time this example was written, all + # incentive offers are CYO incentive offers. + cyo_incentives = response.incentive_offer.cyo_incentives + print(cyo_incentives.low_offer) + print(cyo_incentives.medium_offer) + print(cyo_incentives.high_offer) + else: + print("No incentives found.") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Returns incentives for a given user." + ) + # The following argument(s) should be provided to run the example. + parser.add_argument( + "-e", + "--email_address", + type=str, + required=True, + help="The email of the user to fetch incentives for.", + ) + parser.add_argument( + "-l", + "--language_code", + type=str, + required=False, + default="en", + help="The language code of the user (e.g. 'en').", + ) + parser.add_argument( + "-k", + "--country_code", + type=str, + required=False, + default="US", + help="The country code of the user (e.g. 'US').", + ) + args = parser.parse_args() + + # GoogleAdsClient will read the google-ads.yaml configuration file in the + # home directory if none is specified. + googleads_client = GoogleAdsClient.load_from_storage(version="v23") + + try: + main( + googleads_client, + args.email_address, + args.language_code, + args.country_code, + ) + except GoogleAdsException as ex: + print( + f'Request with ID "{ex.request_id}" failed with status ' + f'"{ex.error.code().name}" and includes the following errors:' + ) + for error in ex.failure.errors: + print(f'\tError with message "{error.message}".') + if error.location: + for field_path_element in error.location.field_path_elements: + print(f"\t\tOn field: {field_path_element.field_name}") + sys.exit(1) diff --git a/examples/misc/add_ad_group_image_asset.py b/examples/misc/add_ad_group_image_asset.py index 29ecedb1d..588af7ada 100644 --- a/examples/misc/add_ad_group_image_asset.py +++ b/examples/misc/add_ad_group_image_asset.py @@ -23,11 +23,11 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad_group_asset import AdGroupAsset -from google.ads.googleads.v22.services.services.ad_group_asset_service.client import ( +from google.ads.googleads.v23.resources.types.ad_group_asset import AdGroupAsset +from google.ads.googleads.v23.services.services.ad_group_asset_service.client import ( AdGroupAssetServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_asset_service import ( +from google.ads.googleads.v23.services.types.ad_group_asset_service import ( AdGroupAssetOperation, MutateAdGroupAssetResult, MutateAdGroupAssetsResponse, @@ -98,7 +98,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main( diff --git a/examples/misc/campaign_report_to_csv.py b/examples/misc/campaign_report_to_csv.py index 5700f90a2..bafcc62d6 100755 --- a/examples/misc/campaign_report_to_csv.py +++ b/examples/misc/campaign_report_to_csv.py @@ -34,10 +34,10 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( GoogleAdsRow, SearchGoogleAdsStreamRequest, SearchGoogleAdsStreamResponse, @@ -168,7 +168,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main( diff --git a/examples/misc/set_custom_client_timeouts.py b/examples/misc/set_custom_client_timeouts.py index a4b099ac8..c8f05812b 100755 --- a/examples/misc/set_custom_client_timeouts.py +++ b/examples/misc/set_custom_client_timeouts.py @@ -30,10 +30,10 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.google_ads_service.client import ( +from google.ads.googleads.v23.services.services.google_ads_service.client import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( GoogleAdsRow, SearchGoogleAdsRequest, SearchGoogleAdsStreamRequest, @@ -194,6 +194,6 @@ def make_unary_call(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") main(googleads_client, args.customer_id) diff --git a/examples/misc/upload_image_asset.py b/examples/misc/upload_image_asset.py index eb642436f..4ac5e6e06 100644 --- a/examples/misc/upload_image_asset.py +++ b/examples/misc/upload_image_asset.py @@ -24,11 +24,11 @@ from examples.utils.example_helpers import get_image_bytes_from_url from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.services.services.asset_service.client import ( +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.services.services.asset_service.client import ( AssetServiceClient, ) -from google.ads.googleads.v22.services.types.asset_service import ( +from google.ads.googleads.v23.services.types.asset_service import ( AssetOperation, MutateAssetResult, MutateAssetsResponse, @@ -85,7 +85,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.customer_id) diff --git a/examples/planning/forecast_reach.py b/examples/planning/forecast_reach.py index 683cb1ce1..12ff84aa5 100755 --- a/examples/planning/forecast_reach.py +++ b/examples/planning/forecast_reach.py @@ -20,19 +20,19 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.enums.types.reach_plan_age_range import ( +from google.ads.googleads.v23.enums.types.reach_plan_age_range import ( ReachPlanAgeRangeEnum, ) -from google.ads.googleads.v22.enums.types.gender_type import GenderTypeEnum -from google.ads.googleads.v22.enums.types.device import DeviceEnum -from google.ads.googleads.v22.common.types.criteria import ( +from google.ads.googleads.v23.enums.types.gender_type import GenderTypeEnum +from google.ads.googleads.v23.enums.types.device import DeviceEnum +from google.ads.googleads.v23.common.types.criteria import ( GenderInfo, DeviceInfo, ) -from google.ads.googleads.v22.services.services.reach_plan_service.client import ( +from google.ads.googleads.v23.services.services.reach_plan_service.client import ( ReachPlanServiceClient, ) -from google.ads.googleads.v22.services.types.reach_plan_service import ( +from google.ads.googleads.v23.services.types.reach_plan_service import ( ListPlannableLocationsResponse, PlannableLocation, ListPlannableProductsResponse, @@ -273,7 +273,7 @@ def forecast_manual_mix( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.customer_id) diff --git a/examples/planning/generate_forecast_metrics.py b/examples/planning/generate_forecast_metrics.py index 6c5094b17..c4aff4f84 100755 --- a/examples/planning/generate_forecast_metrics.py +++ b/examples/planning/generate_forecast_metrics.py @@ -24,16 +24,16 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.criteria import ( +from google.ads.googleads.v23.common.types.criteria import ( KeywordInfo, ) -from google.ads.googleads.v22.services.services.google_ads_service.client import ( +from google.ads.googleads.v23.services.services.google_ads_service.client import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.services.keyword_plan_idea_service.client import ( +from google.ads.googleads.v23.services.services.keyword_plan_idea_service.client import ( KeywordPlanIdeaServiceClient, ) -from google.ads.googleads.v22.services.types.keyword_plan_idea_service import ( +from google.ads.googleads.v23.services.types.keyword_plan_idea_service import ( CampaignToForecast, CriterionBidModifier, ForecastAdGroup, @@ -208,7 +208,7 @@ def generate_forecast_metrics( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.customer_id) diff --git a/examples/planning/generate_historical_metrics.py b/examples/planning/generate_historical_metrics.py index 6ec4596da..71de4c9ac 100755 --- a/examples/planning/generate_historical_metrics.py +++ b/examples/planning/generate_historical_metrics.py @@ -24,17 +24,17 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.keyword_plan_common import ( +from google.ads.googleads.v23.common.types.keyword_plan_common import ( KeywordPlanHistoricalMetrics, MonthlySearchVolume, ) -from google.ads.googleads.v22.services.services.google_ads_service.client import ( +from google.ads.googleads.v23.services.services.google_ads_service.client import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.services.keyword_plan_idea_service.client import ( +from google.ads.googleads.v23.services.services.keyword_plan_idea_service.client import ( KeywordPlanIdeaServiceClient, ) -from google.ads.googleads.v22.services.types.keyword_plan_idea_service import ( +from google.ads.googleads.v23.services.types.keyword_plan_idea_service import ( GenerateKeywordHistoricalMetricsRequest, GenerateKeywordHistoricalMetricsResponse, GenerateKeywordHistoricalMetricsResult, @@ -153,7 +153,7 @@ def generate_historical_metrics(client: GoogleAdsClient, customer_id: str): # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.customer_id) diff --git a/examples/planning/generate_keyword_ideas.py b/examples/planning/generate_keyword_ideas.py index 6bee3e93e..e1597fa3a 100755 --- a/examples/planning/generate_keyword_ideas.py +++ b/examples/planning/generate_keyword_ideas.py @@ -19,22 +19,22 @@ import sys from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.enums.types.keyword_plan_competition_level import ( +from google.ads.googleads.v23.enums.types.keyword_plan_competition_level import ( KeywordPlanCompetitionLevelEnum, ) -from google.ads.googleads.v22.enums.types.keyword_plan_network import ( +from google.ads.googleads.v23.enums.types.keyword_plan_network import ( KeywordPlanNetworkEnum, ) -from google.ads.googleads.v22.services.services.geo_target_constant_service.client import ( +from google.ads.googleads.v23.services.services.geo_target_constant_service.client import ( GeoTargetConstantServiceClient, ) -from google.ads.googleads.v22.services.services.google_ads_service.client import ( +from google.ads.googleads.v23.services.services.google_ads_service.client import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.services.keyword_plan_idea_service.client import ( +from google.ads.googleads.v23.services.services.keyword_plan_idea_service.client import ( KeywordPlanIdeaServiceClient, ) -from google.ads.googleads.v22.services.types.keyword_plan_idea_service import ( +from google.ads.googleads.v23.services.types.keyword_plan_idea_service import ( GenerateKeywordIdeasRequest, GenerateKeywordIdeaResult, ) @@ -205,7 +205,7 @@ def map_locations_ids_to_resource_names( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main( diff --git a/examples/planning/get_ad_group_criterion_cpc_bid_simulations.py b/examples/planning/get_ad_group_criterion_cpc_bid_simulations.py index db1b2cee9..7889e314e 100755 --- a/examples/planning/get_ad_group_criterion_cpc_bid_simulations.py +++ b/examples/planning/get_ad_group_criterion_cpc_bid_simulations.py @@ -23,16 +23,16 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad_group_criterion_simulation import ( +from google.ads.googleads.v23.resources.types.ad_group_criterion_simulation import ( AdGroupCriterionSimulation, ) -from google.ads.googleads.v22.common.types.simulation import ( +from google.ads.googleads.v23.common.types.simulation import ( CpcBidSimulationPoint, ) -from google.ads.googleads.v22.services.services.google_ads_service.client import ( +from google.ads.googleads.v23.services.services.google_ads_service.client import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchGoogleAdsStreamResponse, GoogleAdsRow, ) @@ -120,7 +120,7 @@ def main(client: GoogleAdsClient, customer_id: str, ad_group_id: str): # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main(googleads_client, args.customer_id, args.ad_group_id) diff --git a/examples/recommendations/detect_and_apply_recommendations.py b/examples/recommendations/detect_and_apply_recommendations.py index 5c71e64c5..295484da4 100755 --- a/examples/recommendations/detect_and_apply_recommendations.py +++ b/examples/recommendations/detect_and_apply_recommendations.py @@ -35,10 +35,10 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( GoogleAdsRow, ) -from google.ads.googleads.v22.services.types.recommendation_service import ( +from google.ads.googleads.v23.services.types.recommendation_service import ( ApplyRecommendationOperation, ApplyRecommendationResult, ) @@ -190,7 +190,7 @@ def apply_recommendations( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/recommendations/dismiss_recommendation.py b/examples/recommendations/dismiss_recommendation.py index 54e3921a2..cdfc61ee5 100755 --- a/examples/recommendations/dismiss_recommendation.py +++ b/examples/recommendations/dismiss_recommendation.py @@ -23,10 +23,10 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.recommendation_service import ( +from google.ads.googleads.v23.services.services.recommendation_service import ( RecommendationServiceClient, ) -from google.ads.googleads.v22.services.types.recommendation_service import ( +from google.ads.googleads.v23.services.types.recommendation_service import ( DismissRecommendationRequest, DismissRecommendationResponse, ) @@ -82,7 +82,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/recommendations/generate_budget_recommendations.py b/examples/recommendations/generate_budget_recommendations.py index ce959df53..a80884234 100644 --- a/examples/recommendations/generate_budget_recommendations.py +++ b/examples/recommendations/generate_budget_recommendations.py @@ -31,14 +31,14 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.recommendation_service import ( +from google.ads.googleads.v23.services.services.recommendation_service import ( RecommendationServiceClient, ) -from google.ads.googleads.v22.services.types.recommendation_service import ( +from google.ads.googleads.v23.services.types.recommendation_service import ( GenerateRecommendationsRequest, GenerateRecommendationsResponse, ) -from google.ads.googleads.v22.resources.types.recommendation import ( +from google.ads.googleads.v23.resources.types.recommendation import ( Recommendation, ) @@ -134,7 +134,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/recommendations/get_recommendation_impact_metrics.py b/examples/recommendations/get_recommendation_impact_metrics.py index 573ad359e..516724a45 100644 --- a/examples/recommendations/get_recommendation_impact_metrics.py +++ b/examples/recommendations/get_recommendation_impact_metrics.py @@ -31,14 +31,14 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.recommendation_service import ( +from google.ads.googleads.v23.services.services.recommendation_service import ( RecommendationServiceClient, ) -from google.ads.googleads.v22.services.types.recommendation_service import ( +from google.ads.googleads.v23.services.types.recommendation_service import ( GenerateRecommendationsRequest, GenerateRecommendationsResponse, ) -from google.ads.googleads.v22.resources.types.recommendation import ( +from google.ads.googleads.v23.resources.types.recommendation import ( Recommendation, ) @@ -143,7 +143,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/remarketing/add_conversion_action.py b/examples/remarketing/add_conversion_action.py index c410a6559..64bf59b4c 100755 --- a/examples/remarketing/add_conversion_action.py +++ b/examples/remarketing/add_conversion_action.py @@ -21,13 +21,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.conversion_action import ( +from google.ads.googleads.v23.resources.types.conversion_action import ( ConversionAction, ) -from google.ads.googleads.v22.services.services.conversion_action_service import ( +from google.ads.googleads.v23.services.services.conversion_action_service import ( ConversionActionServiceClient, ) -from google.ads.googleads.v22.services.types.conversion_action_service import ( +from google.ads.googleads.v23.services.types.conversion_action_service import ( ConversionActionOperation, MutateConversionActionsResponse, ) @@ -99,7 +99,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/remarketing/add_conversion_based_user_list.py b/examples/remarketing/add_conversion_based_user_list.py index 8c1dfc450..56eb0180b 100644 --- a/examples/remarketing/add_conversion_based_user_list.py +++ b/examples/remarketing/add_conversion_based_user_list.py @@ -26,15 +26,15 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.user_lists import UserListActionInfo -from google.ads.googleads.v22.resources.types.user_list import UserList -from google.ads.googleads.v22.services.services.conversion_action_service import ( +from google.ads.googleads.v23.common.types.user_lists import UserListActionInfo +from google.ads.googleads.v23.resources.types.user_list import UserList +from google.ads.googleads.v23.services.services.conversion_action_service import ( ConversionActionServiceClient, ) -from google.ads.googleads.v22.services.services.user_list_service import ( +from google.ads.googleads.v23.services.services.user_list_service import ( UserListServiceClient, ) -from google.ads.googleads.v22.services.types.user_list_service import ( +from google.ads.googleads.v23.services.types.user_list_service import ( UserListOperation, MutateUserListsResponse, ) @@ -127,7 +127,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/remarketing/add_custom_audience.py b/examples/remarketing/add_custom_audience.py index 4006e8277..9efc790ab 100755 --- a/examples/remarketing/add_custom_audience.py +++ b/examples/remarketing/add_custom_audience.py @@ -26,18 +26,18 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.enums.types.custom_audience_member_type import ( +from google.ads.googleads.v23.enums.types.custom_audience_member_type import ( CustomAudienceMemberTypeEnum, ) -from google.ads.googleads.v22.resources.types.custom_audience import ( +from google.ads.googleads.v23.resources.types.custom_audience import ( CustomAudience, CustomAudienceMember, ) -from google.ads.googleads.v22.services.types.custom_audience_service import ( +from google.ads.googleads.v23.services.types.custom_audience_service import ( CustomAudienceOperation, MutateCustomAudiencesResponse, ) -from google.ads.googleads.v22.services.services.custom_audience_service import ( +from google.ads.googleads.v23.services.services.custom_audience_service import ( CustomAudienceServiceClient, ) @@ -166,7 +166,7 @@ def create_custom_audience_member( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/remarketing/add_customer_match_user_list.py b/examples/remarketing/add_customer_match_user_list.py index a54757b27..7324003d2 100755 --- a/examples/remarketing/add_customer_match_user_list.py +++ b/examples/remarketing/add_customer_match_user_list.py @@ -37,40 +37,40 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.services.user_list_service import ( +from google.ads.googleads.v23.services.services.user_list_service import ( UserListServiceClient, ) -from google.ads.googleads.v22.services.services.offline_user_data_job_service import ( +from google.ads.googleads.v23.services.services.offline_user_data_job_service import ( OfflineUserDataJobServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchGoogleAdsStreamResponse, ) -from google.ads.googleads.v22.services.types.user_list_service import ( +from google.ads.googleads.v23.services.types.user_list_service import ( UserListOperation, MutateUserListsResponse, ) -from google.ads.googleads.v22.resources.types.user_list import UserList -from google.ads.googleads.v22.services.types.offline_user_data_job_service import ( +from google.ads.googleads.v23.resources.types.user_list import UserList +from google.ads.googleads.v23.services.types.offline_user_data_job_service import ( AddOfflineUserDataJobOperationsRequest, OfflineUserDataJobOperation, AddOfflineUserDataJobOperationsResponse, CreateOfflineUserDataJobResponse, ) -from google.ads.googleads.v22.resources.types.offline_user_data_job import ( +from google.ads.googleads.v23.resources.types.offline_user_data_job import ( OfflineUserDataJob, ) -from google.ads.googleads.v22.common.types.criteria import ( +from google.ads.googleads.v23.common.types.criteria import ( AddressInfo, ) -from google.ads.googleads.v22.common.types.offline_user_data import ( +from google.ads.googleads.v23.common.types.offline_user_data import ( UserData, UserIdentifier, ) -from google.ads.googleads.v22.errors.types.errors import ( +from google.ads.googleads.v23.errors.types.errors import ( GoogleAdsFailure, GoogleAdsError, ) @@ -623,7 +623,7 @@ def normalize_and_hash(s: str, remove_all_whitespace: bool) -> str: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) parser: argparse.ArgumentParser = argparse.ArgumentParser( diff --git a/examples/remarketing/add_dynamic_remarketing_asset.py b/examples/remarketing/add_dynamic_remarketing_asset.py index 0c8404634..14d0db826 100755 --- a/examples/remarketing/add_dynamic_remarketing_asset.py +++ b/examples/remarketing/add_dynamic_remarketing_asset.py @@ -21,46 +21,46 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.asset_types import ( +from google.ads.googleads.v23.common.types.asset_types import ( DynamicEducationAsset, ) -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.resources.types.asset_set import AssetSet -from google.ads.googleads.v22.resources.types.asset_set_asset import ( +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.resources.types.asset_set import AssetSet +from google.ads.googleads.v23.resources.types.asset_set_asset import ( AssetSetAsset, ) -from google.ads.googleads.v22.resources.types.campaign_asset_set import ( +from google.ads.googleads.v23.resources.types.campaign_asset_set import ( CampaignAssetSet, ) -from google.ads.googleads.v22.services.services.asset_service import ( +from google.ads.googleads.v23.services.services.asset_service import ( AssetServiceClient, ) -from google.ads.googleads.v22.services.types.asset_service import ( +from google.ads.googleads.v23.services.types.asset_service import ( AssetOperation, MutateAssetsResponse, ) -from google.ads.googleads.v22.services.services.asset_set_service import ( +from google.ads.googleads.v23.services.services.asset_set_service import ( AssetSetServiceClient, ) -from google.ads.googleads.v22.services.types.asset_set_service import ( +from google.ads.googleads.v23.services.types.asset_set_service import ( AssetSetOperation, MutateAssetSetsResponse, ) -from google.ads.googleads.v22.services.services.asset_set_asset_service import ( +from google.ads.googleads.v23.services.services.asset_set_asset_service import ( AssetSetAssetServiceClient, ) -from google.ads.googleads.v22.services.types.asset_set_asset_service import ( +from google.ads.googleads.v23.services.types.asset_set_asset_service import ( AssetSetAssetOperation, MutateAssetSetAssetsResponse, ) -from google.ads.googleads.v22.services.services.campaign_asset_set_service import ( +from google.ads.googleads.v23.services.services.campaign_asset_set_service import ( CampaignAssetSetServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_asset_set_service import ( +from google.ads.googleads.v23.services.types.campaign_asset_set_service import ( CampaignAssetSetOperation, MutateCampaignAssetSetsResponse, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) @@ -279,7 +279,7 @@ def link_asset_set_to_campaign( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/remarketing/add_flexible_rule_user_list.py b/examples/remarketing/add_flexible_rule_user_list.py index c28314fe3..9a271866a 100644 --- a/examples/remarketing/add_flexible_rule_user_list.py +++ b/examples/remarketing/add_flexible_rule_user_list.py @@ -24,7 +24,7 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.user_lists import ( +from google.ads.googleads.v23.common.types.user_lists import ( FlexibleRuleOperandInfo, FlexibleRuleUserListInfo, RuleBasedUserListInfo, @@ -32,11 +32,11 @@ UserListRuleItemGroupInfo, UserListRuleItemInfo, ) -from google.ads.googleads.v22.resources.types.user_list import UserList -from google.ads.googleads.v22.services.services.user_list_service import ( +from google.ads.googleads.v23.resources.types.user_list import UserList +from google.ads.googleads.v23.services.services.user_list_service import ( UserListServiceClient, ) -from google.ads.googleads.v22.services.types.user_list_service import ( +from google.ads.googleads.v23.services.types.user_list_service import ( UserListOperation, MutateUserListsResponse, ) @@ -208,7 +208,7 @@ def create_user_list_rule_info_from_url( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/remarketing/add_logical_user_list.py b/examples/remarketing/add_logical_user_list.py index 558c7b8e1..b8a1ef1f8 100644 --- a/examples/remarketing/add_logical_user_list.py +++ b/examples/remarketing/add_logical_user_list.py @@ -25,15 +25,15 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.user_lists import ( +from google.ads.googleads.v23.common.types.user_lists import ( LogicalUserListOperandInfo, UserListLogicalRuleInfo, ) -from google.ads.googleads.v22.resources.types.user_list import UserList -from google.ads.googleads.v22.services.services.user_list_service import ( +from google.ads.googleads.v23.resources.types.user_list import UserList +from google.ads.googleads.v23.services.services.user_list_service import ( UserListServiceClient, ) -from google.ads.googleads.v22.services.types.user_list_service import ( +from google.ads.googleads.v23.services.types.user_list_service import ( UserListOperation, MutateUserListsResponse, ) @@ -130,7 +130,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/remarketing/add_merchant_center_dynamic_remarketing_campaign.py b/examples/remarketing/add_merchant_center_dynamic_remarketing_campaign.py index 02e0283bd..a8cd6cb56 100644 --- a/examples/remarketing/add_merchant_center_dynamic_remarketing_campaign.py +++ b/examples/remarketing/add_merchant_center_dynamic_remarketing_campaign.py @@ -26,53 +26,53 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad_group import AdGroup -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.resources.types.ad_group_criterion import ( +from google.ads.googleads.v23.resources.types.ad_group import AdGroup +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.resources.types.ad_group_criterion import ( AdGroupCriterion, ) -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.services.asset_service import ( +from google.ads.googleads.v23.services.services.asset_service import ( AssetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, MutateAdGroupAdsResponse, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, MutateAdGroupCriteriaResponse, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, MutateAdGroupsResponse, ) -from google.ads.googleads.v22.services.types.asset_service import ( +from google.ads.googleads.v23.services.types.asset_service import ( AssetOperation, MutateAssetsResponse, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, MutateCampaignsResponse, ) -from google.ads.googleads.v22.common.types.ad_asset import ( +from google.ads.googleads.v23.common.types.ad_asset import ( AdImageAsset, AdTextAsset, ) -from google.ads.googleads.v22.common.types.ad_type_infos import ( +from google.ads.googleads.v23.common.types.ad_type_infos import ( ResponsiveDisplayAdInfo, ) @@ -427,7 +427,7 @@ def attach_user_list( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/remarketing/set_up_advanced_remarketing.py b/examples/remarketing/set_up_advanced_remarketing.py index a29bf1cb7..ea138961a 100644 --- a/examples/remarketing/set_up_advanced_remarketing.py +++ b/examples/remarketing/set_up_advanced_remarketing.py @@ -25,7 +25,7 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.user_lists import ( +from google.ads.googleads.v23.common.types.user_lists import ( FlexibleRuleOperandInfo, FlexibleRuleUserListInfo, RuleBasedUserListInfo, @@ -35,14 +35,14 @@ UserListNumberRuleItemInfo, UserListStringRuleItemInfo, ) -from google.ads.googleads.v22.enums.types.user_list_date_rule_item_operator import ( +from google.ads.googleads.v23.enums.types.user_list_date_rule_item_operator import ( UserListDateRuleItemOperatorEnum, ) -from google.ads.googleads.v22.resources.types.user_list import UserList -from google.ads.googleads.v22.services.services.user_list_service import ( +from google.ads.googleads.v23.resources.types.user_list import UserList +from google.ads.googleads.v23.services.services.user_list_service import ( UserListServiceClient, ) -from google.ads.googleads.v22.services.types.user_list_service import ( +from google.ads.googleads.v23.services.types.user_list_service import ( MutateUserListsResponse, UserListOperation, ) @@ -246,7 +246,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/remarketing/set_up_remarketing.py b/examples/remarketing/set_up_remarketing.py index 15b363f41..77f1c0fe1 100755 --- a/examples/remarketing/set_up_remarketing.py +++ b/examples/remarketing/set_up_remarketing.py @@ -34,45 +34,45 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.user_lists import ( +from google.ads.googleads.v23.common.types.user_lists import ( FlexibleRuleOperandInfo, FlexibleRuleUserListInfo, UserListRuleItemGroupInfo, UserListRuleItemInfo, ) -from google.ads.googleads.v22.resources.types.ad_group_criterion import ( +from google.ads.googleads.v23.resources.types.ad_group_criterion import ( AdGroupCriterion, ) -from google.ads.googleads.v22.resources.types.campaign_criterion import ( +from google.ads.googleads.v23.resources.types.campaign_criterion import ( CampaignCriterion, ) -from google.ads.googleads.v22.resources.types.user_list import UserList -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.resources.types.user_list import UserList +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_criterion_service import ( +from google.ads.googleads.v23.services.services.campaign_criterion_service import ( CampaignCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.services.user_list_service import ( +from google.ads.googleads.v23.services.services.user_list_service import ( UserListServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, MutateAdGroupCriteriaResponse, ) -from google.ads.googleads.v22.services.types.campaign_criterion_service import ( +from google.ads.googleads.v23.services.types.campaign_criterion_service import ( CampaignCriterionOperation, MutateCampaignCriteriaResponse, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( GoogleAdsRow, SearchGoogleAdsRequest, SearchGoogleAdsResponse, ) -from google.ads.googleads.v22.services.types.user_list_service import ( +from google.ads.googleads.v23.services.types.user_list_service import ( MutateUserListsResponse, UserListOperation, ) @@ -524,7 +524,7 @@ def modify_campaign_bids( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/remarketing/update_audience_target_restriction.py b/examples/remarketing/update_audience_target_restriction.py index d3d39a7dd..0af4faaaf 100644 --- a/examples/remarketing/update_audience_target_restriction.py +++ b/examples/remarketing/update_audience_target_restriction.py @@ -20,25 +20,25 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.targeting_setting import ( +from google.ads.googleads.v23.common.types.targeting_setting import ( TargetingSetting, TargetRestriction, ) -from google.ads.googleads.v22.enums.types.targeting_dimension import ( +from google.ads.googleads.v23.enums.types.targeting_dimension import ( TargetingDimensionEnum, ) -from google.ads.googleads.v22.resources.types.ad_group import AdGroup -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.resources.types.ad_group import AdGroup +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, MutateAdGroupsResponse, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchGoogleAdsResponse, ) from google.api_core import protobuf_helpers @@ -230,7 +230,7 @@ def update_targeting_setting( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/remarketing/upload_call_conversion.py b/examples/remarketing/upload_call_conversion.py index e6472effc..850f575ad 100644 --- a/examples/remarketing/upload_call_conversion.py +++ b/examples/remarketing/upload_call_conversion.py @@ -24,10 +24,10 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.conversion_upload_service import ( +from google.ads.googleads.v23.services.services.conversion_upload_service import ( ConversionUploadServiceClient, ) -from google.ads.googleads.v22.services.types.conversion_upload_service import ( +from google.ads.googleads.v23.services.types.conversion_upload_service import ( CallConversion, CustomVariable, UploadCallConversionsResponse, @@ -151,7 +151,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) parser = argparse.ArgumentParser( diff --git a/examples/remarketing/upload_conversion_adjustment.py b/examples/remarketing/upload_conversion_adjustment.py index 55e179a94..fe0511ac0 100644 --- a/examples/remarketing/upload_conversion_adjustment.py +++ b/examples/remarketing/upload_conversion_adjustment.py @@ -26,20 +26,20 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.enums.types.conversion_adjustment_type import ( +from google.ads.googleads.v23.enums.types.conversion_adjustment_type import ( ConversionAdjustmentTypeEnum, ) -from google.ads.googleads.v22.errors.types.errors import ( +from google.ads.googleads.v23.errors.types.errors import ( GoogleAdsError, GoogleAdsFailure, ) -from google.ads.googleads.v22.services.services.conversion_action_service import ( +from google.ads.googleads.v23.services.services.conversion_action_service import ( ConversionActionServiceClient, ) -from google.ads.googleads.v22.services.services.conversion_adjustment_upload_service import ( +from google.ads.googleads.v23.services.services.conversion_adjustment_upload_service import ( ConversionAdjustmentUploadServiceClient, ) -from google.ads.googleads.v22.services.types.conversion_adjustment_upload_service import ( +from google.ads.googleads.v23.services.types.conversion_adjustment_upload_service import ( ConversionAdjustment, ConversionAdjustmentResult, UploadConversionAdjustmentsRequest, @@ -176,7 +176,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) parser: argparse.ArgumentParser = argparse.ArgumentParser( diff --git a/examples/remarketing/upload_enhanced_conversions_for_leads.py b/examples/remarketing/upload_enhanced_conversions_for_leads.py index 419b056d9..ddcd632ea 100644 --- a/examples/remarketing/upload_enhanced_conversions_for_leads.py +++ b/examples/remarketing/upload_enhanced_conversions_for_leads.py @@ -29,16 +29,16 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.offline_user_data import ( +from google.ads.googleads.v23.common.types.offline_user_data import ( UserIdentifier, ) -from google.ads.googleads.v22.services.services.conversion_action_service import ( +from google.ads.googleads.v23.services.services.conversion_action_service import ( ConversionActionServiceClient, ) -from google.ads.googleads.v22.services.services.conversion_upload_service import ( +from google.ads.googleads.v23.services.services.conversion_upload_service import ( ConversionUploadServiceClient, ) -from google.ads.googleads.v22.services.types.conversion_upload_service import ( +from google.ads.googleads.v23.services.types.conversion_upload_service import ( ClickConversion, ClickConversionResult, SessionAttributeKeyValuePair, @@ -284,7 +284,7 @@ def normalize_and_hash(s: str) -> str: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) parser: argparse.ArgumentParser = argparse.ArgumentParser( diff --git a/examples/remarketing/upload_enhanced_conversions_for_web.py b/examples/remarketing/upload_enhanced_conversions_for_web.py index 8f599a2e3..024c62b33 100644 --- a/examples/remarketing/upload_enhanced_conversions_for_web.py +++ b/examples/remarketing/upload_enhanced_conversions_for_web.py @@ -306,7 +306,7 @@ def normalize_and_hash(s): # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. - googleads_client = GoogleAdsClient.load_from_storage(version="v22") + googleads_client = GoogleAdsClient.load_from_storage(version="v23") try: main( diff --git a/examples/remarketing/upload_offline_conversion.py b/examples/remarketing/upload_offline_conversion.py index 8f9f9f5a4..6cd2a0633 100644 --- a/examples/remarketing/upload_offline_conversion.py +++ b/examples/remarketing/upload_offline_conversion.py @@ -26,13 +26,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.services.services.conversion_action_service import ( +from google.ads.googleads.v23.services.services.conversion_action_service import ( ConversionActionServiceClient, ) -from google.ads.googleads.v22.services.services.conversion_upload_service import ( +from google.ads.googleads.v23.services.services.conversion_upload_service import ( ConversionUploadServiceClient, ) -from google.ads.googleads.v22.services.types.conversion_upload_service import ( +from google.ads.googleads.v23.services.types.conversion_upload_service import ( ClickConversion, ClickConversionResult, CustomVariable, @@ -161,7 +161,7 @@ def main( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) parser: argparse.ArgumentParser = argparse.ArgumentParser( diff --git a/examples/remarketing/upload_store_sales_transactions.py b/examples/remarketing/upload_store_sales_transactions.py index 9f556dd91..3f10ffe8a 100644 --- a/examples/remarketing/upload_store_sales_transactions.py +++ b/examples/remarketing/upload_store_sales_transactions.py @@ -29,36 +29,36 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.offline_user_data import ( +from google.ads.googleads.v23.common.types.offline_user_data import ( ItemAttribute, StoreSalesMetadata, StoreSalesThirdPartyMetadata, UserData, UserIdentifier, ) -from google.ads.googleads.v22.enums.types.offline_user_data_job_status import ( +from google.ads.googleads.v23.enums.types.offline_user_data_job_status import ( OfflineUserDataJobStatusEnum, ) -from google.ads.googleads.v22.enums.types.offline_user_data_job_type import ( +from google.ads.googleads.v23.enums.types.offline_user_data_job_type import ( OfflineUserDataJobTypeEnum, ) -from google.ads.googleads.v22.errors.types.errors import ( +from google.ads.googleads.v23.errors.types.errors import ( GoogleAdsError, GoogleAdsFailure, ) -from google.ads.googleads.v22.resources.types.offline_user_data_job import ( +from google.ads.googleads.v23.resources.types.offline_user_data_job import ( OfflineUserDataJob, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.services.offline_user_data_job_service import ( +from google.ads.googleads.v23.services.services.offline_user_data_job_service import ( OfflineUserDataJobServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( GoogleAdsRow, ) -from google.ads.googleads.v22.services.types.offline_user_data_job_service import ( +from google.ads.googleads.v23.services.types.offline_user_data_job_service import ( AddOfflineUserDataJobOperationsRequest, AddOfflineUserDataJobOperationsResponse, CreateOfflineUserDataJobResponse, @@ -670,7 +670,7 @@ def check_job_status( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) parser: argparse.ArgumentParser = argparse.ArgumentParser( diff --git a/examples/reporting/parallel_report_download.py b/examples/reporting/parallel_report_download.py index c604604a7..29daf6b34 100644 --- a/examples/reporting/parallel_report_download.py +++ b/examples/reporting/parallel_report_download.py @@ -27,14 +27,14 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.errors.types import ( +from google.ads.googleads.v23.errors.types import ( ErrorLocation, GoogleAdsError, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types import ( +from google.ads.googleads.v23.services.types import ( GoogleAdsRow, SearchGoogleAdsStreamResponse, ) @@ -224,7 +224,7 @@ def generate_inputs( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) # Override the login_customer_id on the GoogleAdsClient, if specified. if args.login_customer_id is not None: diff --git a/examples/shopping_ads/add_listing_scope.py b/examples/shopping_ads/add_listing_scope.py index 4782bf330..8b80b5f3e 100755 --- a/examples/shopping_ads/add_listing_scope.py +++ b/examples/shopping_ads/add_listing_scope.py @@ -33,25 +33,25 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.criteria import ( +from google.ads.googleads.v23.common.types.criteria import ( ListingDimensionInfo, ) -from google.ads.googleads.v22.enums.types.product_custom_attribute_index import ( +from google.ads.googleads.v23.enums.types.product_custom_attribute_index import ( ProductCustomAttributeIndexEnum, ) -from google.ads.googleads.v22.enums.types.product_type_level import ( +from google.ads.googleads.v23.enums.types.product_type_level import ( ProductTypeLevelEnum, ) -from google.ads.googleads.v22.resources.types.campaign_criterion import ( +from google.ads.googleads.v23.resources.types.campaign_criterion import ( CampaignCriterion, ) -from google.ads.googleads.v22.services.services.campaign_criterion_service import ( +from google.ads.googleads.v23.services.services.campaign_criterion_service import ( CampaignCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_criterion_service import ( +from google.ads.googleads.v23.services.types.campaign_criterion_service import ( CampaignCriterionOperation, MutateCampaignCriteriaResponse, ) @@ -154,7 +154,7 @@ def main(client: GoogleAdsClient, customer_id: str, campaign_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/shopping_ads/add_performance_max_product_listing_group_tree.py b/examples/shopping_ads/add_performance_max_product_listing_group_tree.py index c85c7cfa1..9e6a8ec18 100644 --- a/examples/shopping_ads/add_performance_max_product_listing_group_tree.py +++ b/examples/shopping_ads/add_performance_max_product_listing_group_tree.py @@ -29,21 +29,21 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.asset_group_listing_group_filter import ( +from google.ads.googleads.v23.resources.types.asset_group_listing_group_filter import ( ListingGroupFilterDimension, ) -from google.ads.googleads.v22.resources.types.asset_group_listing_group_filter import ( +from google.ads.googleads.v23.resources.types.asset_group_listing_group_filter import ( AssetGroupListingGroupFilter, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( MutateGoogleAdsResponse, SearchGoogleAdsRequest, SearchGoogleAdsResponse, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( MutateOperation, ) @@ -663,7 +663,7 @@ def print_response_details( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/shopping_ads/add_performance_max_retail_campaign.py b/examples/shopping_ads/add_performance_max_retail_campaign.py index e5dda1bda..c9c67e9c6 100644 --- a/examples/shopping_ads/add_performance_max_retail_campaign.py +++ b/examples/shopping_ads/add_performance_max_retail_campaign.py @@ -47,64 +47,64 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException from google.ads.googleads.util import convert_snake_case_to_upper_case -from google.ads.googleads.v22.enums.types.conversion_action_category import ( +from google.ads.googleads.v23.enums.types.conversion_action_category import ( ConversionActionCategoryEnum, ) -from google.ads.googleads.v22.enums.types.conversion_origin import ( +from google.ads.googleads.v23.enums.types.conversion_origin import ( ConversionOriginEnum, ) -from google.ads.googleads.v22.enums.types.asset_field_type import ( +from google.ads.googleads.v23.enums.types.asset_field_type import ( AssetFieldTypeEnum, ) -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.resources.types.asset_group import AssetGroup -from google.ads.googleads.v22.resources.types.asset_group_asset import ( +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.resources.types.asset_group import AssetGroup +from google.ads.googleads.v23.resources.types.asset_group_asset import ( AssetGroupAsset, ) -from google.ads.googleads.v22.resources.types.asset_group_listing_group_filter import ( +from google.ads.googleads.v23.resources.types.asset_group_listing_group_filter import ( AssetGroupListingGroupFilter, ) -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.resources.types.campaign_asset import ( +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign_asset import ( CampaignAsset, ) -from google.ads.googleads.v22.resources.types.campaign_budget import ( +from google.ads.googleads.v23.resources.types.campaign_budget import ( CampaignBudget, ) -from google.ads.googleads.v22.resources.types.campaign_conversion_goal import ( +from google.ads.googleads.v23.resources.types.campaign_conversion_goal import ( CampaignConversionGoal, ) -from google.ads.googleads.v22.resources.types.campaign_criterion import ( +from google.ads.googleads.v23.resources.types.campaign_criterion import ( CampaignCriterion, ) -from google.ads.googleads.v22.services.services.asset_group_service import ( +from google.ads.googleads.v23.services.services.asset_group_service import ( AssetGroupServiceClient, ) -from google.ads.googleads.v22.services.services.asset_service import ( +from google.ads.googleads.v23.services.services.asset_service import ( AssetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_budget_service import ( +from google.ads.googleads.v23.services.services.campaign_budget_service import ( CampaignBudgetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_conversion_goal_service import ( +from google.ads.googleads.v23.services.services.campaign_conversion_goal_service import ( CampaignConversionGoalServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.services.geo_target_constant_service import ( +from google.ads.googleads.v23.services.services.geo_target_constant_service import ( GeoTargetConstantServiceClient, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( MutateGoogleAdsResponse, MutateOperationResponse, SearchGoogleAdsRequest, SearchGoogleAdsResponse, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( MutateOperation, ) @@ -390,8 +390,8 @@ def create_performance_max_campaign_operation( ) # Optional fields - campaign.start_date = (datetime.now() + timedelta(1)).strftime("%Y%m%d") - campaign.end_date = (datetime.now() + timedelta(365)).strftime("%Y%m%d") + campaign.start_date_time = (datetime.now() + timedelta(1)).strftime("%Y%m%d 00:00:00") + campaign.end_date_time = (datetime.now() + timedelta(365)).strftime("%Y%m%d 23:59:59") # Configures the optional opt-in/out status for asset automation settings. for asset_automation_type_enum in [ @@ -1251,7 +1251,7 @@ def print_response_details(response: MutateGoogleAdsResponse) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/shopping_ads/add_shopping_product_ad.py b/examples/shopping_ads/add_shopping_product_ad.py index 84a8ab24c..a9d78dcf8 100755 --- a/examples/shopping_ads/add_shopping_product_ad.py +++ b/examples/shopping_ads/add_shopping_product_ad.py @@ -31,43 +31,43 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad_group import AdGroup -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.resources.types.ad_group_criterion import ( +from google.ads.googleads.v23.resources.types.ad_group import AdGroup +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.resources.types.ad_group_criterion import ( AdGroupCriterion, ) -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.resources.types.campaign_budget import ( +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign_budget import ( CampaignBudget, ) -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_budget_service import ( +from google.ads.googleads.v23.services.services.campaign_budget_service import ( CampaignBudgetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, ) -from google.ads.googleads.v22.services.types.campaign_budget_service import ( +from google.ads.googleads.v23.services.types.campaign_budget_service import ( CampaignBudgetOperation, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, ) @@ -361,7 +361,7 @@ def add_default_shopping_listing_group( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/shopping_ads/add_shopping_product_listing_group_tree.py b/examples/shopping_ads/add_shopping_product_listing_group_tree.py index d1557af8c..e8191f049 100644 --- a/examples/shopping_ads/add_shopping_product_listing_group_tree.py +++ b/examples/shopping_ads/add_shopping_product_listing_group_tree.py @@ -31,29 +31,29 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.criteria import ( +from google.ads.googleads.v23.common.types.criteria import ( ListingDimensionInfo, ListingGroupInfo, ) -from google.ads.googleads.v22.enums.types.product_condition import ( +from google.ads.googleads.v23.enums.types.product_condition import ( ProductConditionEnum, ) -from google.ads.googleads.v22.resources.types.ad_group_criterion import ( +from google.ads.googleads.v23.resources.types.ad_group_criterion import ( AdGroupCriterion, ) -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( MutateGoogleAdsResponse, SearchGoogleAdsResponse, ) @@ -485,7 +485,7 @@ def create_listing_group_unit_biddable( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/shopping_ads/get_product_category_constants.py b/examples/shopping_ads/get_product_category_constants.py index 128d162b8..bee906b12 100755 --- a/examples/shopping_ads/get_product_category_constants.py +++ b/examples/shopping_ads/get_product_category_constants.py @@ -22,13 +22,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.product_category_constant import ( +from google.ads.googleads.v23.resources.types.product_category_constant import ( ProductCategoryConstant, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( SearchGoogleAdsStreamRequest, SearchGoogleAdsStreamResponse, ) @@ -154,7 +154,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/targeting/add_campaign_targeting_criteria.py b/examples/targeting/add_campaign_targeting_criteria.py index bfd0d49d7..31020cc25 100755 --- a/examples/targeting/add_campaign_targeting_criteria.py +++ b/examples/targeting/add_campaign_targeting_criteria.py @@ -21,22 +21,22 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.criteria import ( +from google.ads.googleads.v23.common.types.criteria import ( KeywordInfo, ) -from google.ads.googleads.v22.resources.types.campaign_criterion import ( +from google.ads.googleads.v23.resources.types.campaign_criterion import ( CampaignCriterion, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_criterion_service import ( +from google.ads.googleads.v23.services.services.campaign_criterion_service import ( CampaignCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.geo_target_constant_service import ( +from google.ads.googleads.v23.services.services.geo_target_constant_service import ( GeoTargetConstantServiceClient, ) -from google.ads.googleads.v22.services.types.campaign_criterion_service import ( +from google.ads.googleads.v23.services.types.campaign_criterion_service import ( CampaignCriterionOperation, MutateCampaignCriteriaResponse, ) @@ -205,7 +205,7 @@ def create_proximity_op( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/targeting/add_customer_negative_criteria.py b/examples/targeting/add_customer_negative_criteria.py index f842c07aa..1fe9ce17d 100755 --- a/examples/targeting/add_customer_negative_criteria.py +++ b/examples/targeting/add_customer_negative_criteria.py @@ -23,13 +23,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.customer_negative_criterion import ( +from google.ads.googleads.v23.resources.types.customer_negative_criterion import ( CustomerNegativeCriterion, ) -from google.ads.googleads.v22.services.services.customer_negative_criterion_service import ( +from google.ads.googleads.v23.services.services.customer_negative_criterion_service import ( CustomerNegativeCriterionServiceClient, ) -from google.ads.googleads.v22.services.types.customer_negative_criterion_service import ( +from google.ads.googleads.v23.services.types.customer_negative_criterion_service import ( CustomerNegativeCriterionOperation, MutateCustomerNegativeCriteriaResponse, ) @@ -100,7 +100,7 @@ def main(client: GoogleAdsClient, customer_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/targeting/add_demographic_targeting_criteria.py b/examples/targeting/add_demographic_targeting_criteria.py index bc1b13fcf..5faacd6a8 100755 --- a/examples/targeting/add_demographic_targeting_criteria.py +++ b/examples/targeting/add_demographic_targeting_criteria.py @@ -22,16 +22,16 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad_group_criterion import ( +from google.ads.googleads.v23.resources.types.ad_group_criterion import ( AdGroupCriterion, ) -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, MutateAdGroupCriteriaResponse, ) @@ -109,7 +109,7 @@ def main(client: GoogleAdsClient, customer_id: str, ad_group_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/targeting/get_geo_target_constants_by_names.py b/examples/targeting/get_geo_target_constants_by_names.py index 368b636d1..3eac3d753 100755 --- a/examples/targeting/get_geo_target_constants_by_names.py +++ b/examples/targeting/get_geo_target_constants_by_names.py @@ -19,13 +19,13 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.geo_target_constant import ( +from google.ads.googleads.v23.resources.types.geo_target_constant import ( GeoTargetConstant, ) -from google.ads.googleads.v22.services.services.geo_target_constant_service import ( +from google.ads.googleads.v23.services.services.geo_target_constant_service import ( GeoTargetConstantServiceClient, ) -from google.ads.googleads.v22.services.types.geo_target_constant_service import ( +from google.ads.googleads.v23.services.types.geo_target_constant_service import ( GeoTargetConstantSuggestion, SuggestGeoTargetConstantsRequest, SuggestGeoTargetConstantsResponse, @@ -83,7 +83,7 @@ def main(client: GoogleAdsClient) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/travel/add_hotel_ad.py b/examples/travel/add_hotel_ad.py index f4059eb03..1550e0665 100755 --- a/examples/travel/add_hotel_ad.py +++ b/examples/travel/add_hotel_ad.py @@ -27,37 +27,37 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad_group import AdGroup -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.resources.types.campaign_budget import ( +from google.ads.googleads.v23.resources.types.ad_group import AdGroup +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign_budget import ( CampaignBudget, ) -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_budget_service import ( +from google.ads.googleads.v23.services.services.campaign_budget_service import ( CampaignBudgetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, MutateAdGroupAdsResponse, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, MutateAdGroupsResponse, ) -from google.ads.googleads.v22.services.types.campaign_budget_service import ( +from google.ads.googleads.v23.services.types.campaign_budget_service import ( CampaignBudgetOperation, MutateCampaignBudgetsResponse, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, MutateCampaignsResponse, ) @@ -291,7 +291,7 @@ def add_hotel_campaign( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/travel/add_hotel_ad_group_bid_modifiers.py b/examples/travel/add_hotel_ad_group_bid_modifiers.py index a7cb68906..131de4474 100755 --- a/examples/travel/add_hotel_ad_group_bid_modifiers.py +++ b/examples/travel/add_hotel_ad_group_bid_modifiers.py @@ -23,17 +23,17 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.criteria import HotelLengthOfStayInfo -from google.ads.googleads.v22.resources.types.ad_group_bid_modifier import ( +from google.ads.googleads.v23.common.types.criteria import HotelLengthOfStayInfo +from google.ads.googleads.v23.resources.types.ad_group_bid_modifier import ( AdGroupBidModifier, ) -from google.ads.googleads.v22.services.services.ad_group_bid_modifier_service import ( +from google.ads.googleads.v23.services.services.ad_group_bid_modifier_service import ( AdGroupBidModifierServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_bid_modifier_service import ( +from google.ads.googleads.v23.services.types.ad_group_bid_modifier_service import ( AdGroupBidModifierOperation, MutateAdGroupBidModifierResult, MutateAdGroupBidModifiersResponse, @@ -123,7 +123,7 @@ def main(client: GoogleAdsClient, customer_id: str, ad_group_id: str) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/travel/add_hotel_listing_group_tree.py b/examples/travel/add_hotel_listing_group_tree.py index 6a9f0b535..4e6ca9561 100755 --- a/examples/travel/add_hotel_listing_group_tree.py +++ b/examples/travel/add_hotel_listing_group_tree.py @@ -35,20 +35,20 @@ from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.common.types.criteria import ( +from google.ads.googleads.v23.common.types.criteria import ( ListingDimensionInfo, ListingGroupInfo, ) -from google.ads.googleads.v22.enums.types.listing_group_type import ( +from google.ads.googleads.v23.enums.types.listing_group_type import ( ListingGroupTypeEnum, ) -from google.ads.googleads.v22.resources.types.ad_group_criterion import ( +from google.ads.googleads.v23.resources.types.ad_group_criterion import ( AdGroupCriterion, ) -from google.ads.googleads.v22.services.services.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.services.ad_group_criterion_service import ( AdGroupCriterionServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_criterion_service import ( +from google.ads.googleads.v23.services.types.ad_group_criterion_service import ( AdGroupCriterionOperation, MutateAdGroupCriteriaResponse, MutateAdGroupCriterionResult, @@ -532,7 +532,7 @@ def create_ad_group_criterion( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/travel/add_performance_max_for_travel_goals_campaign.py b/examples/travel/add_performance_max_for_travel_goals_campaign.py index dae7b3e92..ac5b1a4dd 100644 --- a/examples/travel/add_performance_max_for_travel_goals_campaign.py +++ b/examples/travel/add_performance_max_for_travel_goals_campaign.py @@ -47,45 +47,45 @@ ) from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.enums.types.asset_field_type import ( +from google.ads.googleads.v23.enums.types.asset_field_type import ( AssetFieldTypeEnum, ) -from google.ads.googleads.v22.enums.types.hotel_asset_suggestion_status import ( +from google.ads.googleads.v23.enums.types.hotel_asset_suggestion_status import ( HotelAssetSuggestionStatusEnum, ) -from google.ads.googleads.v22.resources.types import CampaignBudget -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.resources.types.asset import Asset -from google.ads.googleads.v22.resources.types.asset_group import AssetGroup -from google.ads.googleads.v22.resources.types.asset_group_asset import ( +from google.ads.googleads.v23.resources.types import CampaignBudget +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.asset import Asset +from google.ads.googleads.v23.resources.types.asset_group import AssetGroup +from google.ads.googleads.v23.resources.types.asset_group_asset import ( AssetGroupAsset, ) -from google.ads.googleads.v22.services.services.google_ads_service import ( +from google.ads.googleads.v23.services.services.google_ads_service import ( GoogleAdsServiceClient, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( MutateGoogleAdsResponse, MutateOperation, ) -from google.ads.googleads.v22.services.types.google_ads_service import ( +from google.ads.googleads.v23.services.types.google_ads_service import ( MutateOperationResponse, ) -from google.ads.googleads.v22.resources.types.asset_set import AssetSet -from google.ads.googleads.v22.resources.types.asset_set_asset import ( +from google.ads.googleads.v23.resources.types.asset_set import AssetSet +from google.ads.googleads.v23.resources.types.asset_set_asset import ( AssetSetAsset, ) -from google.ads.googleads.v22.services.services.asset_set_service import ( +from google.ads.googleads.v23.services.services.asset_set_service import ( AssetSetServiceClient, ) -from google.ads.googleads.v22.services.types.asset_set_service import ( +from google.ads.googleads.v23.services.types.asset_set_service import ( AssetSetOperation, MutateAssetSetsResponse, ) -from google.ads.googleads.v22.services.services.travel_asset_suggestion_service import ( +from google.ads.googleads.v23.services.services.travel_asset_suggestion_service import ( TravelAssetSuggestionServiceClient, ) -from google.ads.googleads.v22.services.types.travel_asset_suggestion_service import ( +from google.ads.googleads.v23.services.types.travel_asset_suggestion_service import ( HotelAssetSuggestion, SuggestTravelAssetsRequest, SuggestTravelAssetsResponse, @@ -1110,7 +1110,7 @@ def print_response_details(mutate_response: MutateGoogleAdsResponse) -> None: # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/examples/travel/add_things_to_do_ad.py b/examples/travel/add_things_to_do_ad.py index c0ce6e81f..4f61816bc 100755 --- a/examples/travel/add_things_to_do_ad.py +++ b/examples/travel/add_things_to_do_ad.py @@ -26,37 +26,37 @@ from examples.utils.example_helpers import get_printable_datetime from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException -from google.ads.googleads.v22.resources.types.ad_group import AdGroup -from google.ads.googleads.v22.resources.types.ad_group_ad import AdGroupAd -from google.ads.googleads.v22.resources.types.campaign import Campaign -from google.ads.googleads.v22.resources.types.campaign_budget import ( +from google.ads.googleads.v23.resources.types.ad_group import AdGroup +from google.ads.googleads.v23.resources.types.ad_group_ad import AdGroupAd +from google.ads.googleads.v23.resources.types.campaign import Campaign +from google.ads.googleads.v23.resources.types.campaign_budget import ( CampaignBudget, ) -from google.ads.googleads.v22.services.services.ad_group_ad_service import ( +from google.ads.googleads.v23.services.services.ad_group_ad_service import ( AdGroupAdServiceClient, ) -from google.ads.googleads.v22.services.services.ad_group_service import ( +from google.ads.googleads.v23.services.services.ad_group_service import ( AdGroupServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_budget_service import ( +from google.ads.googleads.v23.services.services.campaign_budget_service import ( CampaignBudgetServiceClient, ) -from google.ads.googleads.v22.services.services.campaign_service import ( +from google.ads.googleads.v23.services.services.campaign_service import ( CampaignServiceClient, ) -from google.ads.googleads.v22.services.types.ad_group_ad_service import ( +from google.ads.googleads.v23.services.types.ad_group_ad_service import ( AdGroupAdOperation, MutateAdGroupAdsResponse, ) -from google.ads.googleads.v22.services.types.ad_group_service import ( +from google.ads.googleads.v23.services.types.ad_group_service import ( AdGroupOperation, MutateAdGroupsResponse, ) -from google.ads.googleads.v22.services.types.campaign_budget_service import ( +from google.ads.googleads.v23.services.types.campaign_budget_service import ( CampaignBudgetOperation, MutateCampaignBudgetsResponse, ) -from google.ads.googleads.v22.services.types.campaign_service import ( +from google.ads.googleads.v23.services.types.campaign_service import ( CampaignOperation, MutateCampaignsResponse, ) @@ -319,7 +319,7 @@ def add_ad_group_ad( # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( - version="v22" + version="v23" ) try: diff --git a/google/ads/googleads/__init__.py b/google/ads/googleads/__init__.py index 4d77c0913..0826212b4 100644 --- a/google/ads/googleads/__init__.py +++ b/google/ads/googleads/__init__.py @@ -19,7 +19,7 @@ import google.ads.googleads.errors import google.ads.googleads.util -VERSION = "28.4.1" +VERSION = "29.0.0" # Checks if the current runtime is Python 3.9. if sys.version_info.major == 3 and sys.version_info.minor <= 9: diff --git a/google/ads/googleads/client.py b/google/ads/googleads/client.py index 3b14af127..58b3bfa22 100644 --- a/google/ads/googleads/client.py +++ b/google/ads/googleads/client.py @@ -45,7 +45,7 @@ _SERVICE_CLIENT_TEMPLATE = "{}Client" _ASYNC_SERVICE_CLIENT_TEMPLATE = "{}AsyncClient" -_VALID_API_VERSIONS = ["v22", "v21", "v20", "v19"] +_VALID_API_VERSIONS = ["v23", "v22", "v21", "v20"] _MESSAGE_TYPES = ["common", "enums", "errors", "resources", "services"] _DEFAULT_VERSION = _VALID_API_VERSIONS[0] diff --git a/google/ads/googleads/v19/__init__.py b/google/ads/googleads/v19/__init__.py deleted file mode 100644 index 659bc6a70..000000000 --- a/google/ads/googleads/v19/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.ads.googleads.v19 import gapic_version as package_version - -__version__ = package_version.__version__ - -from . import common -from . import enums -from . import errors -from . import resources -from . import services - - -__all__ = ( - "common", - "enums", - "errors", - "resources", - "services", -) diff --git a/google/ads/googleads/v19/common/__init__.py b/google/ads/googleads/v19/common/__init__.py deleted file mode 100644 index 704756805..000000000 --- a/google/ads/googleads/v19/common/__init__.py +++ /dev/null @@ -1,643 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.ads.googleads.v19 import gapic_version as package_version - -__version__ = package_version.__version__ - - -from .types.ad_asset import AdAppDeepLinkAsset -from .types.ad_asset import AdCallToActionAsset -from .types.ad_asset import AdDemandGenCarouselCardAsset -from .types.ad_asset import AdImageAsset -from .types.ad_asset import AdMediaBundleAsset -from .types.ad_asset import AdTextAsset -from .types.ad_asset import AdVideoAsset -from .types.ad_asset import AdVideoAssetInfo -from .types.ad_asset import AdVideoAssetInventoryPreferences -from .types.ad_type_infos import AppAdInfo -from .types.ad_type_infos import AppEngagementAdInfo -from .types.ad_type_infos import AppPreRegistrationAdInfo -from .types.ad_type_infos import CallAdInfo -from .types.ad_type_infos import DemandGenCarouselAdInfo -from .types.ad_type_infos import DemandGenMultiAssetAdInfo -from .types.ad_type_infos import DemandGenProductAdInfo -from .types.ad_type_infos import DemandGenVideoResponsiveAdInfo -from .types.ad_type_infos import DisplayUploadAdInfo -from .types.ad_type_infos import ExpandedDynamicSearchAdInfo -from .types.ad_type_infos import ExpandedTextAdInfo -from .types.ad_type_infos import HotelAdInfo -from .types.ad_type_infos import ImageAdInfo -from .types.ad_type_infos import InFeedVideoAdInfo -from .types.ad_type_infos import LegacyAppInstallAdInfo -from .types.ad_type_infos import LegacyResponsiveDisplayAdInfo -from .types.ad_type_infos import LocalAdInfo -from .types.ad_type_infos import ResponsiveDisplayAdControlSpec -from .types.ad_type_infos import ResponsiveDisplayAdInfo -from .types.ad_type_infos import ResponsiveSearchAdInfo -from .types.ad_type_infos import ShoppingComparisonListingAdInfo -from .types.ad_type_infos import ShoppingProductAdInfo -from .types.ad_type_infos import ShoppingSmartAdInfo -from .types.ad_type_infos import SmartCampaignAdInfo -from .types.ad_type_infos import TextAdInfo -from .types.ad_type_infos import TravelAdInfo -from .types.ad_type_infos import VideoAdInfo -from .types.ad_type_infos import VideoBumperInStreamAdInfo -from .types.ad_type_infos import VideoNonSkippableInStreamAdInfo -from .types.ad_type_infos import VideoOutstreamAdInfo -from .types.ad_type_infos import VideoResponsiveAdInfo -from .types.ad_type_infos import VideoTrueViewInStreamAdInfo -from .types.ad_type_infos import YouTubeAudioAdInfo -from .types.asset_policy import AdAssetPolicySummary -from .types.asset_policy import AssetDisapproved -from .types.asset_policy import AssetLinkPrimaryStatusDetails -from .types.asset_set_types import BusinessProfileBusinessNameFilter -from .types.asset_set_types import BusinessProfileLocationGroup -from .types.asset_set_types import BusinessProfileLocationSet -from .types.asset_set_types import ChainFilter -from .types.asset_set_types import ChainLocationGroup -from .types.asset_set_types import ChainSet -from .types.asset_set_types import DynamicBusinessProfileLocationGroupFilter -from .types.asset_set_types import LocationSet -from .types.asset_set_types import MapsLocationInfo -from .types.asset_set_types import MapsLocationSet -from .types.asset_types import AppDeepLinkAsset -from .types.asset_types import BookOnGoogleAsset -from .types.asset_types import BusinessMessageAsset -from .types.asset_types import BusinessMessageCallToActionInfo -from .types.asset_types import BusinessProfileLocation -from .types.asset_types import CallAsset -from .types.asset_types import CalloutAsset -from .types.asset_types import CallToActionAsset -from .types.asset_types import DemandGenCarouselCardAsset -from .types.asset_types import DynamicCustomAsset -from .types.asset_types import DynamicEducationAsset -from .types.asset_types import DynamicFlightsAsset -from .types.asset_types import DynamicHotelsAndRentalsAsset -from .types.asset_types import DynamicJobsAsset -from .types.asset_types import DynamicLocalAsset -from .types.asset_types import DynamicRealEstateAsset -from .types.asset_types import DynamicTravelAsset -from .types.asset_types import HotelCalloutAsset -from .types.asset_types import HotelPropertyAsset -from .types.asset_types import ImageAsset -from .types.asset_types import ImageDimension -from .types.asset_types import LeadFormAsset -from .types.asset_types import LeadFormCustomQuestionField -from .types.asset_types import LeadFormDeliveryMethod -from .types.asset_types import LeadFormField -from .types.asset_types import LeadFormSingleChoiceAnswers -from .types.asset_types import LocationAsset -from .types.asset_types import MediaBundleAsset -from .types.asset_types import MobileAppAsset -from .types.asset_types import PageFeedAsset -from .types.asset_types import PriceAsset -from .types.asset_types import PriceOffering -from .types.asset_types import PromotionAsset -from .types.asset_types import SitelinkAsset -from .types.asset_types import StructuredSnippetAsset -from .types.asset_types import TextAsset -from .types.asset_types import WebhookDelivery -from .types.asset_types import WhatsappBusinessMessageInfo -from .types.asset_types import YoutubeVideoAsset -from .types.asset_usage import AssetUsage -from .types.audience_insights_attribute import AudienceInsightsAttribute -from .types.audience_insights_attribute import AudienceInsightsAttributeMetadata -from .types.audience_insights_attribute import AudienceInsightsCategory -from .types.audience_insights_attribute import AudienceInsightsDynamicLineup -from .types.audience_insights_attribute import AudienceInsightsEntity -from .types.audience_insights_attribute import AudienceInsightsTopic -from .types.audience_insights_attribute import DynamicLineupAttributeMetadata -from .types.audience_insights_attribute import KnowledgeGraphAttributeMetadata -from .types.audience_insights_attribute import LocationAttributeMetadata -from .types.audience_insights_attribute import UserInterestAttributeMetadata -from .types.audience_insights_attribute import YouTubeChannelAttributeMetadata -from .types.audience_insights_attribute import YouTubeVideoAttributeMetadata -from .types.audiences import AgeDimension -from .types.audiences import AgeSegment -from .types.audiences import AudienceDimension -from .types.audiences import AudienceExclusionDimension -from .types.audiences import AudienceSegment -from .types.audiences import AudienceSegmentDimension -from .types.audiences import CustomAudienceSegment -from .types.audiences import DetailedDemographicSegment -from .types.audiences import ExclusionSegment -from .types.audiences import GenderDimension -from .types.audiences import HouseholdIncomeDimension -from .types.audiences import LifeEventSegment -from .types.audiences import ParentalStatusDimension -from .types.audiences import UserInterestSegment -from .types.audiences import UserListSegment -from .types.bidding import Commission -from .types.bidding import EnhancedCpc -from .types.bidding import FixedCpm -from .types.bidding import FixedCpmTargetFrequencyGoalInfo -from .types.bidding import ManualCpa -from .types.bidding import ManualCpc -from .types.bidding import ManualCpm -from .types.bidding import ManualCpv -from .types.bidding import MaximizeConversions -from .types.bidding import MaximizeConversionValue -from .types.bidding import PercentCpc -from .types.bidding import TargetCpa -from .types.bidding import TargetCpm -from .types.bidding import TargetCpmTargetFrequencyGoal -from .types.bidding import TargetCpv -from .types.bidding import TargetImpressionShare -from .types.bidding import TargetRoas -from .types.bidding import TargetSpend -from .types.click_location import ClickLocation -from .types.consent import Consent -from .types.criteria import ActivityCityInfo -from .types.criteria import ActivityCountryInfo -from .types.criteria import ActivityIdInfo -from .types.criteria import ActivityRatingInfo -from .types.criteria import ActivityStateInfo -from .types.criteria import AddressInfo -from .types.criteria import AdScheduleInfo -from .types.criteria import AgeRangeInfo -from .types.criteria import AppPaymentModelInfo -from .types.criteria import AudienceInfo -from .types.criteria import BrandInfo -from .types.criteria import BrandListInfo -from .types.criteria import CarrierInfo -from .types.criteria import CombinedAudienceInfo -from .types.criteria import ContentLabelInfo -from .types.criteria import CustomAffinityInfo -from .types.criteria import CustomAudienceInfo -from .types.criteria import CustomIntentInfo -from .types.criteria import DeviceInfo -from .types.criteria import GenderInfo -from .types.criteria import GeoPointInfo -from .types.criteria import HotelAdvanceBookingWindowInfo -from .types.criteria import HotelCheckInDateRangeInfo -from .types.criteria import HotelCheckInDayInfo -from .types.criteria import HotelCityInfo -from .types.criteria import HotelClassInfo -from .types.criteria import HotelCountryRegionInfo -from .types.criteria import HotelDateSelectionTypeInfo -from .types.criteria import HotelIdInfo -from .types.criteria import HotelLengthOfStayInfo -from .types.criteria import HotelStateInfo -from .types.criteria import IncomeRangeInfo -from .types.criteria import InteractionTypeInfo -from .types.criteria import IpBlockInfo -from .types.criteria import KeywordInfo -from .types.criteria import KeywordThemeInfo -from .types.criteria import LanguageInfo -from .types.criteria import ListingDimensionInfo -from .types.criteria import ListingDimensionPath -from .types.criteria import ListingGroupInfo -from .types.criteria import ListingScopeInfo -from .types.criteria import LocalServiceIdInfo -from .types.criteria import LocationGroupInfo -from .types.criteria import LocationInfo -from .types.criteria import MobileAppCategoryInfo -from .types.criteria import MobileApplicationInfo -from .types.criteria import MobileDeviceInfo -from .types.criteria import NegativeKeywordListInfo -from .types.criteria import OperatingSystemVersionInfo -from .types.criteria import ParentalStatusInfo -from .types.criteria import PlacementInfo -from .types.criteria import ProductBrandInfo -from .types.criteria import ProductCategoryInfo -from .types.criteria import ProductChannelExclusivityInfo -from .types.criteria import ProductChannelInfo -from .types.criteria import ProductConditionInfo -from .types.criteria import ProductCustomAttributeInfo -from .types.criteria import ProductGroupingInfo -from .types.criteria import ProductItemIdInfo -from .types.criteria import ProductLabelsInfo -from .types.criteria import ProductLegacyConditionInfo -from .types.criteria import ProductTypeFullInfo -from .types.criteria import ProductTypeInfo -from .types.criteria import ProximityInfo -from .types.criteria import SearchThemeInfo -from .types.criteria import TopicInfo -from .types.criteria import UnknownListingDimensionInfo -from .types.criteria import UserInterestInfo -from .types.criteria import UserListInfo -from .types.criteria import WebpageConditionInfo -from .types.criteria import WebpageInfo -from .types.criteria import WebpageSampleInfo -from .types.criteria import YouTubeChannelInfo -from .types.criteria import YouTubeVideoInfo -from .types.criterion_category_availability import CriterionCategoryAvailability -from .types.criterion_category_availability import ( - CriterionCategoryChannelAvailability, -) -from .types.criterion_category_availability import ( - CriterionCategoryLocaleAvailability, -) -from .types.custom_parameter import CustomParameter -from .types.customizer_value import CustomizerValue -from .types.dates import DateRange -from .types.dates import YearMonth -from .types.dates import YearMonthRange -from .types.extensions import CallFeedItem -from .types.extensions import CalloutFeedItem -from .types.extensions import SitelinkFeedItem -from .types.feed_common import Money -from .types.final_app_url import FinalAppUrl -from .types.frequency_cap import FrequencyCapEntry -from .types.frequency_cap import FrequencyCapKey -from .types.keyword_plan_common import ConceptGroup -from .types.keyword_plan_common import HistoricalMetricsOptions -from .types.keyword_plan_common import KeywordAnnotations -from .types.keyword_plan_common import KeywordConcept -from .types.keyword_plan_common import KeywordPlanAggregateMetricResults -from .types.keyword_plan_common import KeywordPlanAggregateMetrics -from .types.keyword_plan_common import KeywordPlanDeviceSearches -from .types.keyword_plan_common import KeywordPlanHistoricalMetrics -from .types.keyword_plan_common import MonthlySearchVolume -from .types.lifecycle_goals import LifecycleGoalValueSettings -from .types.local_services import LocalServicesDocumentReadOnly -from .types.metric_goal import MetricGoal -from .types.metrics import Metrics -from .types.metrics import SearchVolumeRange -from .types.offline_user_data import CustomerMatchUserListMetadata -from .types.offline_user_data import EventAttribute -from .types.offline_user_data import EventItemAttribute -from .types.offline_user_data import ItemAttribute -from .types.offline_user_data import OfflineUserAddressInfo -from .types.offline_user_data import ShoppingLoyalty -from .types.offline_user_data import StoreAttribute -from .types.offline_user_data import StoreSalesMetadata -from .types.offline_user_data import StoreSalesThirdPartyMetadata -from .types.offline_user_data import TransactionAttribute -from .types.offline_user_data import UserAttribute -from .types.offline_user_data import UserData -from .types.offline_user_data import UserIdentifier -from .types.policy import PolicyTopicConstraint -from .types.policy import PolicyTopicEntry -from .types.policy import PolicyTopicEvidence -from .types.policy import PolicyValidationParameter -from .types.policy import PolicyViolationKey -from .types.policy_summary import PolicySummary -from .types.real_time_bidding_setting import RealTimeBiddingSetting -from .types.segments import AssetInteractionTarget -from .types.segments import BudgetCampaignAssociationStatus -from .types.segments import Keyword -from .types.segments import Segments -from .types.segments import SkAdNetworkSourceApp -from .types.simulation import BudgetSimulationPoint -from .types.simulation import BudgetSimulationPointList -from .types.simulation import CpcBidSimulationPoint -from .types.simulation import CpcBidSimulationPointList -from .types.simulation import CpvBidSimulationPoint -from .types.simulation import CpvBidSimulationPointList -from .types.simulation import PercentCpcBidSimulationPoint -from .types.simulation import PercentCpcBidSimulationPointList -from .types.simulation import TargetCpaSimulationPoint -from .types.simulation import TargetCpaSimulationPointList -from .types.simulation import TargetImpressionShareSimulationPoint -from .types.simulation import TargetImpressionShareSimulationPointList -from .types.simulation import TargetRoasSimulationPoint -from .types.simulation import TargetRoasSimulationPointList -from .types.tag_snippet import TagSnippet -from .types.targeting_setting import TargetingSetting -from .types.targeting_setting import TargetRestriction -from .types.targeting_setting import TargetRestrictionOperation -from .types.text_label import TextLabel -from .types.url_collection import UrlCollection -from .types.user_lists import BasicUserListInfo -from .types.user_lists import CrmBasedUserListInfo -from .types.user_lists import FlexibleRuleOperandInfo -from .types.user_lists import FlexibleRuleUserListInfo -from .types.user_lists import LogicalUserListInfo -from .types.user_lists import LogicalUserListOperandInfo -from .types.user_lists import LookalikeUserListInfo -from .types.user_lists import RuleBasedUserListInfo -from .types.user_lists import SimilarUserListInfo -from .types.user_lists import UserListActionInfo -from .types.user_lists import UserListDateRuleItemInfo -from .types.user_lists import UserListLogicalRuleInfo -from .types.user_lists import UserListNumberRuleItemInfo -from .types.user_lists import UserListRuleInfo -from .types.user_lists import UserListRuleItemGroupInfo -from .types.user_lists import UserListRuleItemInfo -from .types.user_lists import UserListStringRuleItemInfo -from .types.value import Value - -__all__ = ( - "ActivityCityInfo", - "ActivityCountryInfo", - "ActivityIdInfo", - "ActivityRatingInfo", - "ActivityStateInfo", - "AdAppDeepLinkAsset", - "AdAssetPolicySummary", - "AdCallToActionAsset", - "AdDemandGenCarouselCardAsset", - "AdImageAsset", - "AdMediaBundleAsset", - "AdScheduleInfo", - "AdTextAsset", - "AdVideoAsset", - "AdVideoAssetInfo", - "AdVideoAssetInventoryPreferences", - "AddressInfo", - "AgeDimension", - "AgeRangeInfo", - "AgeSegment", - "AppAdInfo", - "AppDeepLinkAsset", - "AppEngagementAdInfo", - "AppPaymentModelInfo", - "AppPreRegistrationAdInfo", - "AssetDisapproved", - "AssetInteractionTarget", - "AssetLinkPrimaryStatusDetails", - "AssetUsage", - "AudienceDimension", - "AudienceExclusionDimension", - "AudienceInfo", - "AudienceInsightsAttribute", - "AudienceInsightsAttributeMetadata", - "AudienceInsightsCategory", - "AudienceInsightsDynamicLineup", - "AudienceInsightsEntity", - "AudienceInsightsTopic", - "AudienceSegment", - "AudienceSegmentDimension", - "BasicUserListInfo", - "BookOnGoogleAsset", - "BrandInfo", - "BrandListInfo", - "BudgetCampaignAssociationStatus", - "BudgetSimulationPoint", - "BudgetSimulationPointList", - "BusinessMessageAsset", - "BusinessMessageCallToActionInfo", - "BusinessProfileBusinessNameFilter", - "BusinessProfileLocation", - "BusinessProfileLocationGroup", - "BusinessProfileLocationSet", - "CallAdInfo", - "CallAsset", - "CallFeedItem", - "CallToActionAsset", - "CalloutAsset", - "CalloutFeedItem", - "CarrierInfo", - "ChainFilter", - "ChainLocationGroup", - "ChainSet", - "ClickLocation", - "CombinedAudienceInfo", - "Commission", - "ConceptGroup", - "Consent", - "ContentLabelInfo", - "CpcBidSimulationPoint", - "CpcBidSimulationPointList", - "CpvBidSimulationPoint", - "CpvBidSimulationPointList", - "CriterionCategoryAvailability", - "CriterionCategoryChannelAvailability", - "CriterionCategoryLocaleAvailability", - "CrmBasedUserListInfo", - "CustomAffinityInfo", - "CustomAudienceInfo", - "CustomAudienceSegment", - "CustomIntentInfo", - "CustomParameter", - "CustomerMatchUserListMetadata", - "CustomizerValue", - "DateRange", - "DemandGenCarouselAdInfo", - "DemandGenCarouselCardAsset", - "DemandGenMultiAssetAdInfo", - "DemandGenProductAdInfo", - "DemandGenVideoResponsiveAdInfo", - "DetailedDemographicSegment", - "DeviceInfo", - "DisplayUploadAdInfo", - "DynamicBusinessProfileLocationGroupFilter", - "DynamicCustomAsset", - "DynamicEducationAsset", - "DynamicFlightsAsset", - "DynamicHotelsAndRentalsAsset", - "DynamicJobsAsset", - "DynamicLineupAttributeMetadata", - "DynamicLocalAsset", - "DynamicRealEstateAsset", - "DynamicTravelAsset", - "EnhancedCpc", - "EventAttribute", - "EventItemAttribute", - "ExclusionSegment", - "ExpandedDynamicSearchAdInfo", - "ExpandedTextAdInfo", - "FinalAppUrl", - "FixedCpm", - "FixedCpmTargetFrequencyGoalInfo", - "FlexibleRuleOperandInfo", - "FlexibleRuleUserListInfo", - "FrequencyCapEntry", - "FrequencyCapKey", - "GenderDimension", - "GenderInfo", - "GeoPointInfo", - "HistoricalMetricsOptions", - "HotelAdInfo", - "HotelAdvanceBookingWindowInfo", - "HotelCalloutAsset", - "HotelCheckInDateRangeInfo", - "HotelCheckInDayInfo", - "HotelCityInfo", - "HotelClassInfo", - "HotelCountryRegionInfo", - "HotelDateSelectionTypeInfo", - "HotelIdInfo", - "HotelLengthOfStayInfo", - "HotelPropertyAsset", - "HotelStateInfo", - "HouseholdIncomeDimension", - "ImageAdInfo", - "ImageAsset", - "ImageDimension", - "InFeedVideoAdInfo", - "IncomeRangeInfo", - "InteractionTypeInfo", - "IpBlockInfo", - "ItemAttribute", - "Keyword", - "KeywordAnnotations", - "KeywordConcept", - "KeywordInfo", - "KeywordPlanAggregateMetricResults", - "KeywordPlanAggregateMetrics", - "KeywordPlanDeviceSearches", - "KeywordPlanHistoricalMetrics", - "KeywordThemeInfo", - "KnowledgeGraphAttributeMetadata", - "LanguageInfo", - "LeadFormAsset", - "LeadFormCustomQuestionField", - "LeadFormDeliveryMethod", - "LeadFormField", - "LeadFormSingleChoiceAnswers", - "LegacyAppInstallAdInfo", - "LegacyResponsiveDisplayAdInfo", - "LifeEventSegment", - "LifecycleGoalValueSettings", - "ListingDimensionInfo", - "ListingDimensionPath", - "ListingGroupInfo", - "ListingScopeInfo", - "LocalAdInfo", - "LocalServiceIdInfo", - "LocalServicesDocumentReadOnly", - "LocationAsset", - "LocationAttributeMetadata", - "LocationGroupInfo", - "LocationInfo", - "LocationSet", - "LogicalUserListInfo", - "LogicalUserListOperandInfo", - "LookalikeUserListInfo", - "ManualCpa", - "ManualCpc", - "ManualCpm", - "ManualCpv", - "MapsLocationInfo", - "MapsLocationSet", - "MaximizeConversionValue", - "MaximizeConversions", - "MediaBundleAsset", - "MetricGoal", - "Metrics", - "MobileAppAsset", - "MobileAppCategoryInfo", - "MobileApplicationInfo", - "MobileDeviceInfo", - "Money", - "MonthlySearchVolume", - "NegativeKeywordListInfo", - "OfflineUserAddressInfo", - "OperatingSystemVersionInfo", - "PageFeedAsset", - "ParentalStatusDimension", - "ParentalStatusInfo", - "PercentCpc", - "PercentCpcBidSimulationPoint", - "PercentCpcBidSimulationPointList", - "PlacementInfo", - "PolicySummary", - "PolicyTopicConstraint", - "PolicyTopicEntry", - "PolicyTopicEvidence", - "PolicyValidationParameter", - "PolicyViolationKey", - "PriceAsset", - "PriceOffering", - "ProductBrandInfo", - "ProductCategoryInfo", - "ProductChannelExclusivityInfo", - "ProductChannelInfo", - "ProductConditionInfo", - "ProductCustomAttributeInfo", - "ProductGroupingInfo", - "ProductItemIdInfo", - "ProductLabelsInfo", - "ProductLegacyConditionInfo", - "ProductTypeFullInfo", - "ProductTypeInfo", - "PromotionAsset", - "ProximityInfo", - "RealTimeBiddingSetting", - "ResponsiveDisplayAdControlSpec", - "ResponsiveDisplayAdInfo", - "ResponsiveSearchAdInfo", - "RuleBasedUserListInfo", - "SearchThemeInfo", - "SearchVolumeRange", - "Segments", - "ShoppingComparisonListingAdInfo", - "ShoppingLoyalty", - "ShoppingProductAdInfo", - "ShoppingSmartAdInfo", - "SimilarUserListInfo", - "SitelinkAsset", - "SitelinkFeedItem", - "SkAdNetworkSourceApp", - "SmartCampaignAdInfo", - "StoreAttribute", - "StoreSalesMetadata", - "StoreSalesThirdPartyMetadata", - "StructuredSnippetAsset", - "TagSnippet", - "TargetCpa", - "TargetCpaSimulationPoint", - "TargetCpaSimulationPointList", - "TargetCpm", - "TargetCpmTargetFrequencyGoal", - "TargetCpv", - "TargetImpressionShare", - "TargetImpressionShareSimulationPoint", - "TargetImpressionShareSimulationPointList", - "TargetRestriction", - "TargetRestrictionOperation", - "TargetRoas", - "TargetRoasSimulationPoint", - "TargetRoasSimulationPointList", - "TargetSpend", - "TargetingSetting", - "TextAdInfo", - "TextAsset", - "TextLabel", - "TopicInfo", - "TransactionAttribute", - "TravelAdInfo", - "UnknownListingDimensionInfo", - "UrlCollection", - "UserAttribute", - "UserData", - "UserIdentifier", - "UserInterestAttributeMetadata", - "UserInterestInfo", - "UserInterestSegment", - "UserListActionInfo", - "UserListDateRuleItemInfo", - "UserListInfo", - "UserListLogicalRuleInfo", - "UserListNumberRuleItemInfo", - "UserListRuleInfo", - "UserListRuleItemGroupInfo", - "UserListRuleItemInfo", - "UserListSegment", - "UserListStringRuleItemInfo", - "Value", - "VideoAdInfo", - "VideoBumperInStreamAdInfo", - "VideoNonSkippableInStreamAdInfo", - "VideoOutstreamAdInfo", - "VideoResponsiveAdInfo", - "VideoTrueViewInStreamAdInfo", - "WebhookDelivery", - "WebpageConditionInfo", - "WebpageInfo", - "WebpageSampleInfo", - "WhatsappBusinessMessageInfo", - "YearMonth", - "YearMonthRange", - "YouTubeAudioAdInfo", - "YouTubeChannelAttributeMetadata", - "YouTubeChannelInfo", - "YouTubeVideoAttributeMetadata", - "YouTubeVideoInfo", - "YoutubeVideoAsset", -) diff --git a/google/ads/googleads/v19/common/types/__init__.py b/google/ads/googleads/v19/common/types/__init__.py deleted file mode 100644 index 4aa2c9b6c..000000000 --- a/google/ads/googleads/v19/common/types/__init__.py +++ /dev/null @@ -1,708 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .ad_asset import ( - AdAppDeepLinkAsset, - AdCallToActionAsset, - AdDemandGenCarouselCardAsset, - AdImageAsset, - AdMediaBundleAsset, - AdTextAsset, - AdVideoAsset, - AdVideoAssetInfo, - AdVideoAssetInventoryPreferences, -) -from .ad_type_infos import ( - AppAdInfo, - AppEngagementAdInfo, - AppPreRegistrationAdInfo, - CallAdInfo, - DemandGenCarouselAdInfo, - DemandGenMultiAssetAdInfo, - DemandGenProductAdInfo, - DemandGenVideoResponsiveAdInfo, - DisplayUploadAdInfo, - ExpandedDynamicSearchAdInfo, - ExpandedTextAdInfo, - HotelAdInfo, - ImageAdInfo, - InFeedVideoAdInfo, - LegacyAppInstallAdInfo, - LegacyResponsiveDisplayAdInfo, - LocalAdInfo, - ResponsiveDisplayAdControlSpec, - ResponsiveDisplayAdInfo, - ResponsiveSearchAdInfo, - ShoppingComparisonListingAdInfo, - ShoppingProductAdInfo, - ShoppingSmartAdInfo, - SmartCampaignAdInfo, - TextAdInfo, - TravelAdInfo, - VideoAdInfo, - VideoBumperInStreamAdInfo, - VideoNonSkippableInStreamAdInfo, - VideoOutstreamAdInfo, - VideoResponsiveAdInfo, - VideoTrueViewInStreamAdInfo, - YouTubeAudioAdInfo, -) -from .asset_policy import ( - AdAssetPolicySummary, - AssetDisapproved, - AssetLinkPrimaryStatusDetails, -) -from .asset_set_types import ( - BusinessProfileBusinessNameFilter, - BusinessProfileLocationGroup, - BusinessProfileLocationSet, - ChainFilter, - ChainLocationGroup, - ChainSet, - DynamicBusinessProfileLocationGroupFilter, - LocationSet, - MapsLocationInfo, - MapsLocationSet, -) -from .asset_types import ( - AppDeepLinkAsset, - BookOnGoogleAsset, - BusinessMessageAsset, - BusinessMessageCallToActionInfo, - BusinessProfileLocation, - CallAsset, - CalloutAsset, - CallToActionAsset, - DemandGenCarouselCardAsset, - DynamicCustomAsset, - DynamicEducationAsset, - DynamicFlightsAsset, - DynamicHotelsAndRentalsAsset, - DynamicJobsAsset, - DynamicLocalAsset, - DynamicRealEstateAsset, - DynamicTravelAsset, - HotelCalloutAsset, - HotelPropertyAsset, - ImageAsset, - ImageDimension, - LeadFormAsset, - LeadFormCustomQuestionField, - LeadFormDeliveryMethod, - LeadFormField, - LeadFormSingleChoiceAnswers, - LocationAsset, - MediaBundleAsset, - MobileAppAsset, - PageFeedAsset, - PriceAsset, - PriceOffering, - PromotionAsset, - SitelinkAsset, - StructuredSnippetAsset, - TextAsset, - WebhookDelivery, - WhatsappBusinessMessageInfo, - YoutubeVideoAsset, -) -from .asset_usage import ( - AssetUsage, -) -from .audience_insights_attribute import ( - AudienceInsightsAttribute, - AudienceInsightsAttributeMetadata, - AudienceInsightsCategory, - AudienceInsightsDynamicLineup, - AudienceInsightsEntity, - AudienceInsightsTopic, - DynamicLineupAttributeMetadata, - KnowledgeGraphAttributeMetadata, - LocationAttributeMetadata, - UserInterestAttributeMetadata, - YouTubeChannelAttributeMetadata, - YouTubeVideoAttributeMetadata, -) -from .audiences import ( - AgeDimension, - AgeSegment, - AudienceDimension, - AudienceExclusionDimension, - AudienceSegment, - AudienceSegmentDimension, - CustomAudienceSegment, - DetailedDemographicSegment, - ExclusionSegment, - GenderDimension, - HouseholdIncomeDimension, - LifeEventSegment, - ParentalStatusDimension, - UserInterestSegment, - UserListSegment, -) -from .bidding import ( - Commission, - EnhancedCpc, - FixedCpm, - FixedCpmTargetFrequencyGoalInfo, - ManualCpa, - ManualCpc, - ManualCpm, - ManualCpv, - MaximizeConversions, - MaximizeConversionValue, - PercentCpc, - TargetCpa, - TargetCpm, - TargetCpmTargetFrequencyGoal, - TargetCpv, - TargetImpressionShare, - TargetRoas, - TargetSpend, -) -from .click_location import ( - ClickLocation, -) -from .consent import ( - Consent, -) -from .criteria import ( - ActivityCityInfo, - ActivityCountryInfo, - ActivityIdInfo, - ActivityRatingInfo, - ActivityStateInfo, - AddressInfo, - AdScheduleInfo, - AgeRangeInfo, - AppPaymentModelInfo, - AudienceInfo, - BrandInfo, - BrandListInfo, - CarrierInfo, - CombinedAudienceInfo, - ContentLabelInfo, - CustomAffinityInfo, - CustomAudienceInfo, - CustomIntentInfo, - DeviceInfo, - GenderInfo, - GeoPointInfo, - HotelAdvanceBookingWindowInfo, - HotelCheckInDateRangeInfo, - HotelCheckInDayInfo, - HotelCityInfo, - HotelClassInfo, - HotelCountryRegionInfo, - HotelDateSelectionTypeInfo, - HotelIdInfo, - HotelLengthOfStayInfo, - HotelStateInfo, - IncomeRangeInfo, - InteractionTypeInfo, - IpBlockInfo, - KeywordInfo, - KeywordThemeInfo, - LanguageInfo, - ListingDimensionInfo, - ListingDimensionPath, - ListingGroupInfo, - ListingScopeInfo, - LocalServiceIdInfo, - LocationGroupInfo, - LocationInfo, - MobileAppCategoryInfo, - MobileApplicationInfo, - MobileDeviceInfo, - NegativeKeywordListInfo, - OperatingSystemVersionInfo, - ParentalStatusInfo, - PlacementInfo, - ProductBrandInfo, - ProductCategoryInfo, - ProductChannelExclusivityInfo, - ProductChannelInfo, - ProductConditionInfo, - ProductCustomAttributeInfo, - ProductGroupingInfo, - ProductItemIdInfo, - ProductLabelsInfo, - ProductLegacyConditionInfo, - ProductTypeFullInfo, - ProductTypeInfo, - ProximityInfo, - SearchThemeInfo, - TopicInfo, - UnknownListingDimensionInfo, - UserInterestInfo, - UserListInfo, - WebpageConditionInfo, - WebpageInfo, - WebpageSampleInfo, - YouTubeChannelInfo, - YouTubeVideoInfo, -) -from .criterion_category_availability import ( - CriterionCategoryAvailability, - CriterionCategoryChannelAvailability, - CriterionCategoryLocaleAvailability, -) -from .custom_parameter import ( - CustomParameter, -) -from .customizer_value import ( - CustomizerValue, -) -from .dates import ( - DateRange, - YearMonth, - YearMonthRange, -) -from .extensions import ( - CallFeedItem, - CalloutFeedItem, - SitelinkFeedItem, -) -from .feed_common import ( - Money, -) -from .final_app_url import ( - FinalAppUrl, -) -from .frequency_cap import ( - FrequencyCapEntry, - FrequencyCapKey, -) -from .keyword_plan_common import ( - ConceptGroup, - HistoricalMetricsOptions, - KeywordAnnotations, - KeywordConcept, - KeywordPlanAggregateMetricResults, - KeywordPlanAggregateMetrics, - KeywordPlanDeviceSearches, - KeywordPlanHistoricalMetrics, - MonthlySearchVolume, -) -from .lifecycle_goals import ( - LifecycleGoalValueSettings, -) -from .local_services import ( - LocalServicesDocumentReadOnly, -) -from .metric_goal import ( - MetricGoal, -) -from .metrics import ( - Metrics, - SearchVolumeRange, -) -from .offline_user_data import ( - CustomerMatchUserListMetadata, - EventAttribute, - EventItemAttribute, - ItemAttribute, - OfflineUserAddressInfo, - ShoppingLoyalty, - StoreAttribute, - StoreSalesMetadata, - StoreSalesThirdPartyMetadata, - TransactionAttribute, - UserAttribute, - UserData, - UserIdentifier, -) -from .policy import ( - PolicyTopicConstraint, - PolicyTopicEntry, - PolicyTopicEvidence, - PolicyValidationParameter, - PolicyViolationKey, -) -from .policy_summary import ( - PolicySummary, -) -from .real_time_bidding_setting import ( - RealTimeBiddingSetting, -) -from .segments import ( - AssetInteractionTarget, - BudgetCampaignAssociationStatus, - Keyword, - Segments, - SkAdNetworkSourceApp, -) -from .simulation import ( - BudgetSimulationPoint, - BudgetSimulationPointList, - CpcBidSimulationPoint, - CpcBidSimulationPointList, - CpvBidSimulationPoint, - CpvBidSimulationPointList, - PercentCpcBidSimulationPoint, - PercentCpcBidSimulationPointList, - TargetCpaSimulationPoint, - TargetCpaSimulationPointList, - TargetImpressionShareSimulationPoint, - TargetImpressionShareSimulationPointList, - TargetRoasSimulationPoint, - TargetRoasSimulationPointList, -) -from .tag_snippet import ( - TagSnippet, -) -from .targeting_setting import ( - TargetingSetting, - TargetRestriction, - TargetRestrictionOperation, -) -from .text_label import ( - TextLabel, -) -from .url_collection import ( - UrlCollection, -) -from .user_lists import ( - BasicUserListInfo, - CrmBasedUserListInfo, - FlexibleRuleOperandInfo, - FlexibleRuleUserListInfo, - LogicalUserListInfo, - LogicalUserListOperandInfo, - LookalikeUserListInfo, - RuleBasedUserListInfo, - SimilarUserListInfo, - UserListActionInfo, - UserListDateRuleItemInfo, - UserListLogicalRuleInfo, - UserListNumberRuleItemInfo, - UserListRuleInfo, - UserListRuleItemGroupInfo, - UserListRuleItemInfo, - UserListStringRuleItemInfo, -) -from .value import ( - Value, -) - -__all__ = ( - "AdAppDeepLinkAsset", - "AdCallToActionAsset", - "AdDemandGenCarouselCardAsset", - "AdImageAsset", - "AdMediaBundleAsset", - "AdTextAsset", - "AdVideoAsset", - "AdVideoAssetInfo", - "AdVideoAssetInventoryPreferences", - "AppAdInfo", - "AppEngagementAdInfo", - "AppPreRegistrationAdInfo", - "CallAdInfo", - "DemandGenCarouselAdInfo", - "DemandGenMultiAssetAdInfo", - "DemandGenProductAdInfo", - "DemandGenVideoResponsiveAdInfo", - "DisplayUploadAdInfo", - "ExpandedDynamicSearchAdInfo", - "ExpandedTextAdInfo", - "HotelAdInfo", - "ImageAdInfo", - "InFeedVideoAdInfo", - "LegacyAppInstallAdInfo", - "LegacyResponsiveDisplayAdInfo", - "LocalAdInfo", - "ResponsiveDisplayAdControlSpec", - "ResponsiveDisplayAdInfo", - "ResponsiveSearchAdInfo", - "ShoppingComparisonListingAdInfo", - "ShoppingProductAdInfo", - "ShoppingSmartAdInfo", - "SmartCampaignAdInfo", - "TextAdInfo", - "TravelAdInfo", - "VideoAdInfo", - "VideoBumperInStreamAdInfo", - "VideoNonSkippableInStreamAdInfo", - "VideoOutstreamAdInfo", - "VideoResponsiveAdInfo", - "VideoTrueViewInStreamAdInfo", - "YouTubeAudioAdInfo", - "AdAssetPolicySummary", - "AssetDisapproved", - "AssetLinkPrimaryStatusDetails", - "BusinessProfileBusinessNameFilter", - "BusinessProfileLocationGroup", - "BusinessProfileLocationSet", - "ChainFilter", - "ChainLocationGroup", - "ChainSet", - "DynamicBusinessProfileLocationGroupFilter", - "LocationSet", - "MapsLocationInfo", - "MapsLocationSet", - "AppDeepLinkAsset", - "BookOnGoogleAsset", - "BusinessMessageAsset", - "BusinessMessageCallToActionInfo", - "BusinessProfileLocation", - "CallAsset", - "CalloutAsset", - "CallToActionAsset", - "DemandGenCarouselCardAsset", - "DynamicCustomAsset", - "DynamicEducationAsset", - "DynamicFlightsAsset", - "DynamicHotelsAndRentalsAsset", - "DynamicJobsAsset", - "DynamicLocalAsset", - "DynamicRealEstateAsset", - "DynamicTravelAsset", - "HotelCalloutAsset", - "HotelPropertyAsset", - "ImageAsset", - "ImageDimension", - "LeadFormAsset", - "LeadFormCustomQuestionField", - "LeadFormDeliveryMethod", - "LeadFormField", - "LeadFormSingleChoiceAnswers", - "LocationAsset", - "MediaBundleAsset", - "MobileAppAsset", - "PageFeedAsset", - "PriceAsset", - "PriceOffering", - "PromotionAsset", - "SitelinkAsset", - "StructuredSnippetAsset", - "TextAsset", - "WebhookDelivery", - "WhatsappBusinessMessageInfo", - "YoutubeVideoAsset", - "AssetUsage", - "AudienceInsightsAttribute", - "AudienceInsightsAttributeMetadata", - "AudienceInsightsCategory", - "AudienceInsightsDynamicLineup", - "AudienceInsightsEntity", - "AudienceInsightsTopic", - "DynamicLineupAttributeMetadata", - "KnowledgeGraphAttributeMetadata", - "LocationAttributeMetadata", - "UserInterestAttributeMetadata", - "YouTubeChannelAttributeMetadata", - "YouTubeVideoAttributeMetadata", - "AgeDimension", - "AgeSegment", - "AudienceDimension", - "AudienceExclusionDimension", - "AudienceSegment", - "AudienceSegmentDimension", - "CustomAudienceSegment", - "DetailedDemographicSegment", - "ExclusionSegment", - "GenderDimension", - "HouseholdIncomeDimension", - "LifeEventSegment", - "ParentalStatusDimension", - "UserInterestSegment", - "UserListSegment", - "Commission", - "EnhancedCpc", - "FixedCpm", - "FixedCpmTargetFrequencyGoalInfo", - "ManualCpa", - "ManualCpc", - "ManualCpm", - "ManualCpv", - "MaximizeConversions", - "MaximizeConversionValue", - "PercentCpc", - "TargetCpa", - "TargetCpm", - "TargetCpmTargetFrequencyGoal", - "TargetCpv", - "TargetImpressionShare", - "TargetRoas", - "TargetSpend", - "ClickLocation", - "Consent", - "ActivityCityInfo", - "ActivityCountryInfo", - "ActivityIdInfo", - "ActivityRatingInfo", - "ActivityStateInfo", - "AddressInfo", - "AdScheduleInfo", - "AgeRangeInfo", - "AppPaymentModelInfo", - "AudienceInfo", - "BrandInfo", - "BrandListInfo", - "CarrierInfo", - "CombinedAudienceInfo", - "ContentLabelInfo", - "CustomAffinityInfo", - "CustomAudienceInfo", - "CustomIntentInfo", - "DeviceInfo", - "GenderInfo", - "GeoPointInfo", - "HotelAdvanceBookingWindowInfo", - "HotelCheckInDateRangeInfo", - "HotelCheckInDayInfo", - "HotelCityInfo", - "HotelClassInfo", - "HotelCountryRegionInfo", - "HotelDateSelectionTypeInfo", - "HotelIdInfo", - "HotelLengthOfStayInfo", - "HotelStateInfo", - "IncomeRangeInfo", - "InteractionTypeInfo", - "IpBlockInfo", - "KeywordInfo", - "KeywordThemeInfo", - "LanguageInfo", - "ListingDimensionInfo", - "ListingDimensionPath", - "ListingGroupInfo", - "ListingScopeInfo", - "LocalServiceIdInfo", - "LocationGroupInfo", - "LocationInfo", - "MobileAppCategoryInfo", - "MobileApplicationInfo", - "MobileDeviceInfo", - "NegativeKeywordListInfo", - "OperatingSystemVersionInfo", - "ParentalStatusInfo", - "PlacementInfo", - "ProductBrandInfo", - "ProductCategoryInfo", - "ProductChannelExclusivityInfo", - "ProductChannelInfo", - "ProductConditionInfo", - "ProductCustomAttributeInfo", - "ProductGroupingInfo", - "ProductItemIdInfo", - "ProductLabelsInfo", - "ProductLegacyConditionInfo", - "ProductTypeFullInfo", - "ProductTypeInfo", - "ProximityInfo", - "SearchThemeInfo", - "TopicInfo", - "UnknownListingDimensionInfo", - "UserInterestInfo", - "UserListInfo", - "WebpageConditionInfo", - "WebpageInfo", - "WebpageSampleInfo", - "YouTubeChannelInfo", - "YouTubeVideoInfo", - "CriterionCategoryAvailability", - "CriterionCategoryChannelAvailability", - "CriterionCategoryLocaleAvailability", - "CustomParameter", - "CustomizerValue", - "DateRange", - "YearMonth", - "YearMonthRange", - "CallFeedItem", - "CalloutFeedItem", - "SitelinkFeedItem", - "Money", - "FinalAppUrl", - "FrequencyCapEntry", - "FrequencyCapKey", - "ConceptGroup", - "HistoricalMetricsOptions", - "KeywordAnnotations", - "KeywordConcept", - "KeywordPlanAggregateMetricResults", - "KeywordPlanAggregateMetrics", - "KeywordPlanDeviceSearches", - "KeywordPlanHistoricalMetrics", - "MonthlySearchVolume", - "LifecycleGoalValueSettings", - "LocalServicesDocumentReadOnly", - "MetricGoal", - "Metrics", - "SearchVolumeRange", - "CustomerMatchUserListMetadata", - "EventAttribute", - "EventItemAttribute", - "ItemAttribute", - "OfflineUserAddressInfo", - "ShoppingLoyalty", - "StoreAttribute", - "StoreSalesMetadata", - "StoreSalesThirdPartyMetadata", - "TransactionAttribute", - "UserAttribute", - "UserData", - "UserIdentifier", - "PolicyTopicConstraint", - "PolicyTopicEntry", - "PolicyTopicEvidence", - "PolicyValidationParameter", - "PolicyViolationKey", - "PolicySummary", - "RealTimeBiddingSetting", - "AssetInteractionTarget", - "BudgetCampaignAssociationStatus", - "Keyword", - "Segments", - "SkAdNetworkSourceApp", - "BudgetSimulationPoint", - "BudgetSimulationPointList", - "CpcBidSimulationPoint", - "CpcBidSimulationPointList", - "CpvBidSimulationPoint", - "CpvBidSimulationPointList", - "PercentCpcBidSimulationPoint", - "PercentCpcBidSimulationPointList", - "TargetCpaSimulationPoint", - "TargetCpaSimulationPointList", - "TargetImpressionShareSimulationPoint", - "TargetImpressionShareSimulationPointList", - "TargetRoasSimulationPoint", - "TargetRoasSimulationPointList", - "TagSnippet", - "TargetingSetting", - "TargetRestriction", - "TargetRestrictionOperation", - "TextLabel", - "UrlCollection", - "BasicUserListInfo", - "CrmBasedUserListInfo", - "FlexibleRuleOperandInfo", - "FlexibleRuleUserListInfo", - "LogicalUserListInfo", - "LogicalUserListOperandInfo", - "LookalikeUserListInfo", - "RuleBasedUserListInfo", - "SimilarUserListInfo", - "UserListActionInfo", - "UserListDateRuleItemInfo", - "UserListLogicalRuleInfo", - "UserListNumberRuleItemInfo", - "UserListRuleInfo", - "UserListRuleItemGroupInfo", - "UserListRuleItemInfo", - "UserListStringRuleItemInfo", - "Value", -) diff --git a/google/ads/googleads/v19/common/types/audience_insights_attribute.py b/google/ads/googleads/v19/common/types/audience_insights_attribute.py deleted file mode 100644 index 5e861d836..000000000 --- a/google/ads/googleads/v19/common/types/audience_insights_attribute.py +++ /dev/null @@ -1,575 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -from typing import MutableSequence - -import proto # type: ignore - -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.enums.types import audience_insights_dimension -from google.ads.googleads.v19.enums.types import ( - insights_knowledge_graph_entity_capabilities, -) - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", - manifest={ - "AudienceInsightsAttributeMetadata", - "AudienceInsightsAttribute", - "AudienceInsightsTopic", - "AudienceInsightsEntity", - "AudienceInsightsCategory", - "AudienceInsightsDynamicLineup", - "YouTubeChannelAttributeMetadata", - "YouTubeVideoAttributeMetadata", - "DynamicLineupAttributeMetadata", - "LocationAttributeMetadata", - "UserInterestAttributeMetadata", - "KnowledgeGraphAttributeMetadata", - }, -) - - -class AudienceInsightsAttributeMetadata(proto.Message): - r"""An audience attribute, with metadata about it, returned in - response to a search. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - dimension (google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension): - The type of the attribute. - attribute (google.ads.googleads.v19.common.types.AudienceInsightsAttribute): - The attribute itself. - display_name (str): - The human-readable name of the attribute. - display_info (str): - A string that supplements the display_name to identify the - attribute. If the dimension is TOPIC, this is a brief - description of the Knowledge Graph entity, such as "American - singer-songwriter". If the dimension is CATEGORY, this is - the complete path to the category in The Product & Service - taxonomy, for example "/Apparel/Clothing/Outerwear". - potential_youtube_reach (int): - An estimate of the number of reachable - YouTube users matching this attribute in the - requested location, or zero if that information - is not available for this attribute. This field - is not populated in every response. - subscriber_share (float): - The share of subscribers within this - attribute, between and including 0 and - 1. This field is not populated in every - response. - viewer_share (float): - The share of viewers within this attribute, - between and including 0 and - 1. This field is not populated in every - response. - youtube_channel_metadata (google.ads.googleads.v19.common.types.YouTubeChannelAttributeMetadata): - Special metadata for a YouTube channel. - - This field is a member of `oneof`_ ``dimension_metadata``. - youtube_video_metadata (google.ads.googleads.v19.common.types.YouTubeVideoAttributeMetadata): - Special metadata for a YouTube video. - - This field is a member of `oneof`_ ``dimension_metadata``. - dynamic_attribute_metadata (google.ads.googleads.v19.common.types.DynamicLineupAttributeMetadata): - Special metadata for a YouTube Dynamic - Lineup. - - This field is a member of `oneof`_ ``dimension_metadata``. - location_attribute_metadata (google.ads.googleads.v19.common.types.LocationAttributeMetadata): - Special metadata for a Location. - - This field is a member of `oneof`_ ``dimension_metadata``. - user_interest_attribute_metadata (google.ads.googleads.v19.common.types.UserInterestAttributeMetadata): - Special metadata for a User Interest. - - This field is a member of `oneof`_ ``dimension_metadata``. - knowledge_graph_attribute_metadata (google.ads.googleads.v19.common.types.KnowledgeGraphAttributeMetadata): - Special metadata for a Knowledge Graph - Entity. - - This field is a member of `oneof`_ ``dimension_metadata``. - """ - - dimension: ( - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ) = proto.Field( - proto.ENUM, - number=1, - enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, - ) - attribute: "AudienceInsightsAttribute" = proto.Field( - proto.MESSAGE, - number=2, - message="AudienceInsightsAttribute", - ) - display_name: str = proto.Field( - proto.STRING, - number=3, - ) - display_info: str = proto.Field( - proto.STRING, - number=4, - ) - potential_youtube_reach: int = proto.Field( - proto.INT64, - number=8, - ) - subscriber_share: float = proto.Field( - proto.DOUBLE, - number=9, - ) - viewer_share: float = proto.Field( - proto.DOUBLE, - number=13, - ) - youtube_channel_metadata: "YouTubeChannelAttributeMetadata" = proto.Field( - proto.MESSAGE, - number=5, - oneof="dimension_metadata", - message="YouTubeChannelAttributeMetadata", - ) - youtube_video_metadata: "YouTubeVideoAttributeMetadata" = proto.Field( - proto.MESSAGE, - number=10, - oneof="dimension_metadata", - message="YouTubeVideoAttributeMetadata", - ) - dynamic_attribute_metadata: "DynamicLineupAttributeMetadata" = proto.Field( - proto.MESSAGE, - number=6, - oneof="dimension_metadata", - message="DynamicLineupAttributeMetadata", - ) - location_attribute_metadata: "LocationAttributeMetadata" = proto.Field( - proto.MESSAGE, - number=7, - oneof="dimension_metadata", - message="LocationAttributeMetadata", - ) - user_interest_attribute_metadata: "UserInterestAttributeMetadata" = ( - proto.Field( - proto.MESSAGE, - number=11, - oneof="dimension_metadata", - message="UserInterestAttributeMetadata", - ) - ) - knowledge_graph_attribute_metadata: "KnowledgeGraphAttributeMetadata" = ( - proto.Field( - proto.MESSAGE, - number=12, - oneof="dimension_metadata", - message="KnowledgeGraphAttributeMetadata", - ) - ) - - -class AudienceInsightsAttribute(proto.Message): - r"""An audience attribute that can be used to request insights - about the audience. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - age_range (google.ads.googleads.v19.common.types.AgeRangeInfo): - An audience attribute defined by an age - range. - - This field is a member of `oneof`_ ``attribute``. - gender (google.ads.googleads.v19.common.types.GenderInfo): - An audience attribute defined by a gender. - - This field is a member of `oneof`_ ``attribute``. - location (google.ads.googleads.v19.common.types.LocationInfo): - An audience attribute defined by a geographic - location. - - This field is a member of `oneof`_ ``attribute``. - user_interest (google.ads.googleads.v19.common.types.UserInterestInfo): - An Affinity or In-Market audience. - - This field is a member of `oneof`_ ``attribute``. - entity (google.ads.googleads.v19.common.types.AudienceInsightsEntity): - An audience attribute defined by interest in - a topic represented by a Knowledge Graph entity. - - This field is a member of `oneof`_ ``attribute``. - category (google.ads.googleads.v19.common.types.AudienceInsightsCategory): - An audience attribute defined by interest in - a Product & Service category. - - This field is a member of `oneof`_ ``attribute``. - dynamic_lineup (google.ads.googleads.v19.common.types.AudienceInsightsDynamicLineup): - A YouTube Dynamic Lineup. - - This field is a member of `oneof`_ ``attribute``. - parental_status (google.ads.googleads.v19.common.types.ParentalStatusInfo): - A Parental Status value (parent, or not a - parent). - - This field is a member of `oneof`_ ``attribute``. - income_range (google.ads.googleads.v19.common.types.IncomeRangeInfo): - A household income percentile range. - - This field is a member of `oneof`_ ``attribute``. - youtube_channel (google.ads.googleads.v19.common.types.YouTubeChannelInfo): - A YouTube channel. - - This field is a member of `oneof`_ ``attribute``. - youtube_video (google.ads.googleads.v19.common.types.YouTubeVideoInfo): - A YouTube video. - - This field is a member of `oneof`_ ``attribute``. - """ - - age_range: criteria.AgeRangeInfo = proto.Field( - proto.MESSAGE, - number=1, - oneof="attribute", - message=criteria.AgeRangeInfo, - ) - gender: criteria.GenderInfo = proto.Field( - proto.MESSAGE, - number=2, - oneof="attribute", - message=criteria.GenderInfo, - ) - location: criteria.LocationInfo = proto.Field( - proto.MESSAGE, - number=3, - oneof="attribute", - message=criteria.LocationInfo, - ) - user_interest: criteria.UserInterestInfo = proto.Field( - proto.MESSAGE, - number=4, - oneof="attribute", - message=criteria.UserInterestInfo, - ) - entity: "AudienceInsightsEntity" = proto.Field( - proto.MESSAGE, - number=5, - oneof="attribute", - message="AudienceInsightsEntity", - ) - category: "AudienceInsightsCategory" = proto.Field( - proto.MESSAGE, - number=6, - oneof="attribute", - message="AudienceInsightsCategory", - ) - dynamic_lineup: "AudienceInsightsDynamicLineup" = proto.Field( - proto.MESSAGE, - number=7, - oneof="attribute", - message="AudienceInsightsDynamicLineup", - ) - parental_status: criteria.ParentalStatusInfo = proto.Field( - proto.MESSAGE, - number=8, - oneof="attribute", - message=criteria.ParentalStatusInfo, - ) - income_range: criteria.IncomeRangeInfo = proto.Field( - proto.MESSAGE, - number=9, - oneof="attribute", - message=criteria.IncomeRangeInfo, - ) - youtube_channel: criteria.YouTubeChannelInfo = proto.Field( - proto.MESSAGE, - number=10, - oneof="attribute", - message=criteria.YouTubeChannelInfo, - ) - youtube_video: criteria.YouTubeVideoInfo = proto.Field( - proto.MESSAGE, - number=11, - oneof="attribute", - message=criteria.YouTubeVideoInfo, - ) - - -class AudienceInsightsTopic(proto.Message): - r"""An entity or category representing a topic that defines an - audience. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - entity (google.ads.googleads.v19.common.types.AudienceInsightsEntity): - A Knowledge Graph entity - - This field is a member of `oneof`_ ``topic``. - category (google.ads.googleads.v19.common.types.AudienceInsightsCategory): - A Product & Service category - - This field is a member of `oneof`_ ``topic``. - """ - - entity: "AudienceInsightsEntity" = proto.Field( - proto.MESSAGE, - number=1, - oneof="topic", - message="AudienceInsightsEntity", - ) - category: "AudienceInsightsCategory" = proto.Field( - proto.MESSAGE, - number=2, - oneof="topic", - message="AudienceInsightsCategory", - ) - - -class AudienceInsightsEntity(proto.Message): - r"""A Knowledge Graph entity, represented by its machine id. - - Attributes: - knowledge_graph_machine_id (str): - Required. The machine ID (mid) of the - Knowledge Graph entity. - """ - - knowledge_graph_machine_id: str = proto.Field( - proto.STRING, - number=1, - ) - - -class AudienceInsightsCategory(proto.Message): - r"""A Product and Service category. - - Attributes: - category_id (str): - Required. The criterion ID of the category. - """ - - category_id: str = proto.Field( - proto.STRING, - number=1, - ) - - -class AudienceInsightsDynamicLineup(proto.Message): - r"""A YouTube Dynamic Lineup. - - Attributes: - dynamic_lineup_id (str): - Required. The numeric ID of the dynamic - lineup. - """ - - dynamic_lineup_id: str = proto.Field( - proto.STRING, - number=1, - ) - - -class YouTubeChannelAttributeMetadata(proto.Message): - r"""Metadata associated with a YouTube channel attribute. - - Attributes: - subscriber_count (int): - The approximate number of subscribers to the - YouTube channel. - """ - - subscriber_count: int = proto.Field( - proto.INT64, - number=1, - ) - - -class YouTubeVideoAttributeMetadata(proto.Message): - r"""Metadata for a YouTube video attribute. - - Attributes: - thumbnail_url (str): - The URL of the video thumbnail, prefixed by - "https://img.youtube.com/". - video_url (str): - The URL of the video, prefixed by - "https://www.youtube.com/". - """ - - thumbnail_url: str = proto.Field( - proto.STRING, - number=1, - ) - video_url: str = proto.Field( - proto.STRING, - number=2, - ) - - -class DynamicLineupAttributeMetadata(proto.Message): - r"""Metadata associated with a Dynamic Lineup attribute. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - inventory_country (google.ads.googleads.v19.common.types.LocationInfo): - The national market associated with the - lineup. - median_monthly_inventory (int): - The median number of impressions per month on - this lineup. - - This field is a member of `oneof`_ ``_median_monthly_inventory``. - channel_count_lower_bound (int): - The lower end of a range containing the - number of channels in the lineup. - - This field is a member of `oneof`_ ``_channel_count_lower_bound``. - channel_count_upper_bound (int): - The upper end of a range containing the - number of channels in the lineup. - - This field is a member of `oneof`_ ``_channel_count_upper_bound``. - sample_channels (MutableSequence[google.ads.googleads.v19.common.types.DynamicLineupAttributeMetadata.SampleChannel]): - Examples of channels that are included in the - lineup. - """ - - class SampleChannel(proto.Message): - r"""A YouTube channel returned as an example of the content in a - lineup. - - Attributes: - youtube_channel (google.ads.googleads.v19.common.types.YouTubeChannelInfo): - A YouTube channel. - display_name (str): - The name of the sample channel. - youtube_channel_metadata (google.ads.googleads.v19.common.types.YouTubeChannelAttributeMetadata): - Metadata for the sample channel. - """ - - youtube_channel: criteria.YouTubeChannelInfo = proto.Field( - proto.MESSAGE, - number=1, - message=criteria.YouTubeChannelInfo, - ) - display_name: str = proto.Field( - proto.STRING, - number=2, - ) - youtube_channel_metadata: "YouTubeChannelAttributeMetadata" = ( - proto.Field( - proto.MESSAGE, - number=3, - message="YouTubeChannelAttributeMetadata", - ) - ) - - inventory_country: criteria.LocationInfo = proto.Field( - proto.MESSAGE, - number=1, - message=criteria.LocationInfo, - ) - median_monthly_inventory: int = proto.Field( - proto.INT64, - number=2, - optional=True, - ) - channel_count_lower_bound: int = proto.Field( - proto.INT64, - number=3, - optional=True, - ) - channel_count_upper_bound: int = proto.Field( - proto.INT64, - number=4, - optional=True, - ) - sample_channels: MutableSequence[SampleChannel] = proto.RepeatedField( - proto.MESSAGE, - number=5, - message=SampleChannel, - ) - - -class LocationAttributeMetadata(proto.Message): - r"""Metadata associated with a Location attribute. - - Attributes: - country_location (google.ads.googleads.v19.common.types.LocationInfo): - The country location that this attribute’s - sub country location is located in. - """ - - country_location: criteria.LocationInfo = proto.Field( - proto.MESSAGE, - number=1, - message=criteria.LocationInfo, - ) - - -class UserInterestAttributeMetadata(proto.Message): - r"""Metadata associated with a User Interest attribute. - - Attributes: - user_interest_description (str): - English language text description of the user - interest category (200 characters max). - """ - - user_interest_description: str = proto.Field( - proto.STRING, - number=1, - ) - - -class KnowledgeGraphAttributeMetadata(proto.Message): - r"""Metadata associated with a Knowledge Graph Entity attribute. - - Attributes: - entity_capabilities (MutableSequence[google.ads.googleads.v19.enums.types.InsightsKnowledgeGraphEntityCapabilitiesEnum.InsightsKnowledgeGraphEntityCapabilities]): - The capabilities of the entity used in - [ContentCreatorInsightsService][]. - """ - - entity_capabilities: MutableSequence[ - insights_knowledge_graph_entity_capabilities.InsightsKnowledgeGraphEntityCapabilitiesEnum.InsightsKnowledgeGraphEntityCapabilities - ] = proto.RepeatedField( - proto.ENUM, - number=1, - enum=insights_knowledge_graph_entity_capabilities.InsightsKnowledgeGraphEntityCapabilitiesEnum.InsightsKnowledgeGraphEntityCapabilities, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/__init__.py b/google/ads/googleads/v19/enums/__init__.py deleted file mode 100644 index 247a72cae..000000000 --- a/google/ads/googleads/v19/enums/__init__.py +++ /dev/null @@ -1,879 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.ads.googleads.v19 import gapic_version as package_version - -__version__ = package_version.__version__ - - -from .types.access_invitation_status import AccessInvitationStatusEnum -from .types.access_reason import AccessReasonEnum -from .types.access_role import AccessRoleEnum -from .types.account_budget_proposal_status import ( - AccountBudgetProposalStatusEnum, -) -from .types.account_budget_proposal_type import AccountBudgetProposalTypeEnum -from .types.account_budget_status import AccountBudgetStatusEnum -from .types.account_link_status import AccountLinkStatusEnum -from .types.ad_destination_type import AdDestinationTypeEnum -from .types.ad_format_type import AdFormatTypeEnum -from .types.ad_group_ad_primary_status import AdGroupAdPrimaryStatusEnum -from .types.ad_group_ad_primary_status_reason import ( - AdGroupAdPrimaryStatusReasonEnum, -) -from .types.ad_group_ad_rotation_mode import AdGroupAdRotationModeEnum -from .types.ad_group_ad_status import AdGroupAdStatusEnum -from .types.ad_group_criterion_approval_status import ( - AdGroupCriterionApprovalStatusEnum, -) -from .types.ad_group_criterion_primary_status import ( - AdGroupCriterionPrimaryStatusEnum, -) -from .types.ad_group_criterion_primary_status_reason import ( - AdGroupCriterionPrimaryStatusReasonEnum, -) -from .types.ad_group_criterion_status import AdGroupCriterionStatusEnum -from .types.ad_group_primary_status import AdGroupPrimaryStatusEnum -from .types.ad_group_primary_status_reason import AdGroupPrimaryStatusReasonEnum -from .types.ad_group_status import AdGroupStatusEnum -from .types.ad_group_type import AdGroupTypeEnum -from .types.ad_network_type import AdNetworkTypeEnum -from .types.ad_serving_optimization_status import ( - AdServingOptimizationStatusEnum, -) -from .types.ad_strength import AdStrengthEnum -from .types.ad_strength_action_item_type import AdStrengthActionItemTypeEnum -from .types.ad_type import AdTypeEnum -from .types.advertising_channel_sub_type import AdvertisingChannelSubTypeEnum -from .types.advertising_channel_type import AdvertisingChannelTypeEnum -from .types.age_range_type import AgeRangeTypeEnum -from .types.android_privacy_interaction_type import ( - AndroidPrivacyInteractionTypeEnum, -) -from .types.android_privacy_network_type import AndroidPrivacyNetworkTypeEnum -from .types.app_bidding_goal import AppBiddingGoalEnum -from .types.app_campaign_app_store import AppCampaignAppStoreEnum -from .types.app_campaign_bidding_strategy_goal_type import ( - AppCampaignBiddingStrategyGoalTypeEnum, -) -from .types.app_payment_model_type import AppPaymentModelTypeEnum -from .types.app_url_operating_system_type import AppUrlOperatingSystemTypeEnum -from .types.asset_automation_status import AssetAutomationStatusEnum -from .types.asset_automation_type import AssetAutomationTypeEnum -from .types.asset_coverage_video_aspect_ratio_requirement import ( - AssetCoverageVideoAspectRatioRequirementEnum, -) -from .types.asset_field_type import AssetFieldTypeEnum -from .types.asset_group_primary_status import AssetGroupPrimaryStatusEnum -from .types.asset_group_primary_status_reason import ( - AssetGroupPrimaryStatusReasonEnum, -) -from .types.asset_group_signal_approval_status import ( - AssetGroupSignalApprovalStatusEnum, -) -from .types.asset_group_status import AssetGroupStatusEnum -from .types.asset_link_primary_status import AssetLinkPrimaryStatusEnum -from .types.asset_link_primary_status_reason import ( - AssetLinkPrimaryStatusReasonEnum, -) -from .types.asset_link_status import AssetLinkStatusEnum -from .types.asset_offline_evaluation_error_reasons import ( - AssetOfflineEvaluationErrorReasonsEnum, -) -from .types.asset_performance_label import AssetPerformanceLabelEnum -from .types.asset_set_asset_status import AssetSetAssetStatusEnum -from .types.asset_set_link_status import AssetSetLinkStatusEnum -from .types.asset_set_status import AssetSetStatusEnum -from .types.asset_set_type import AssetSetTypeEnum -from .types.asset_source import AssetSourceEnum -from .types.asset_type import AssetTypeEnum -from .types.async_action_status import AsyncActionStatusEnum -from .types.attribution_model import AttributionModelEnum -from .types.audience_insights_dimension import AudienceInsightsDimensionEnum -from .types.audience_insights_marketing_objective import ( - AudienceInsightsMarketingObjectiveEnum, -) -from .types.audience_scope import AudienceScopeEnum -from .types.audience_status import AudienceStatusEnum -from .types.batch_job_status import BatchJobStatusEnum -from .types.bid_modifier_source import BidModifierSourceEnum -from .types.bidding_source import BiddingSourceEnum -from .types.bidding_strategy_status import BiddingStrategyStatusEnum -from .types.bidding_strategy_system_status import ( - BiddingStrategySystemStatusEnum, -) -from .types.bidding_strategy_type import BiddingStrategyTypeEnum -from .types.billing_setup_status import BillingSetupStatusEnum -from .types.brand_request_rejection_reason import ( - BrandRequestRejectionReasonEnum, -) -from .types.brand_safety_suitability import BrandSafetySuitabilityEnum -from .types.brand_state import BrandStateEnum -from .types.budget_campaign_association_status import ( - BudgetCampaignAssociationStatusEnum, -) -from .types.budget_delivery_method import BudgetDeliveryMethodEnum -from .types.budget_period import BudgetPeriodEnum -from .types.budget_status import BudgetStatusEnum -from .types.budget_type import BudgetTypeEnum -from .types.business_message_call_to_action_type import ( - BusinessMessageCallToActionTypeEnum, -) -from .types.business_message_provider import BusinessMessageProviderEnum -from .types.call_conversion_reporting_state import ( - CallConversionReportingStateEnum, -) -from .types.call_to_action_type import CallToActionTypeEnum -from .types.call_tracking_display_location import ( - CallTrackingDisplayLocationEnum, -) -from .types.call_type import CallTypeEnum -from .types.campaign_criterion_status import CampaignCriterionStatusEnum -from .types.campaign_draft_status import CampaignDraftStatusEnum -from .types.campaign_experiment_type import CampaignExperimentTypeEnum -from .types.campaign_group_status import CampaignGroupStatusEnum -from .types.campaign_keyword_match_type import CampaignKeywordMatchTypeEnum -from .types.campaign_primary_status import CampaignPrimaryStatusEnum -from .types.campaign_primary_status_reason import ( - CampaignPrimaryStatusReasonEnum, -) -from .types.campaign_serving_status import CampaignServingStatusEnum -from .types.campaign_shared_set_status import CampaignSharedSetStatusEnum -from .types.campaign_status import CampaignStatusEnum -from .types.chain_relationship_type import ChainRelationshipTypeEnum -from .types.change_client_type import ChangeClientTypeEnum -from .types.change_event_resource_type import ChangeEventResourceTypeEnum -from .types.change_status_operation import ChangeStatusOperationEnum -from .types.change_status_resource_type import ChangeStatusResourceTypeEnum -from .types.click_type import ClickTypeEnum -from .types.combined_audience_status import CombinedAudienceStatusEnum -from .types.consent_status import ConsentStatusEnum -from .types.content_label_type import ContentLabelTypeEnum -from .types.conversion_action_category import ConversionActionCategoryEnum -from .types.conversion_action_counting_type import ( - ConversionActionCountingTypeEnum, -) -from .types.conversion_action_status import ConversionActionStatusEnum -from .types.conversion_action_type import ConversionActionTypeEnum -from .types.conversion_adjustment_type import ConversionAdjustmentTypeEnum -from .types.conversion_attribution_event_type import ( - ConversionAttributionEventTypeEnum, -) -from .types.conversion_custom_variable_status import ( - ConversionCustomVariableStatusEnum, -) -from .types.conversion_customer_type import ConversionCustomerTypeEnum -from .types.conversion_environment_enum import ConversionEnvironmentEnum -from .types.conversion_lag_bucket import ConversionLagBucketEnum -from .types.conversion_or_adjustment_lag_bucket import ( - ConversionOrAdjustmentLagBucketEnum, -) -from .types.conversion_origin import ConversionOriginEnum -from .types.conversion_tracking_status_enum import ConversionTrackingStatusEnum -from .types.conversion_value_rule_primary_dimension import ( - ConversionValueRulePrimaryDimensionEnum, -) -from .types.conversion_value_rule_set_status import ( - ConversionValueRuleSetStatusEnum, -) -from .types.conversion_value_rule_status import ConversionValueRuleStatusEnum -from .types.converting_user_prior_engagement_type_and_ltv_bucket import ( - ConvertingUserPriorEngagementTypeAndLtvBucketEnum, -) -from .types.criterion_category_channel_availability_mode import ( - CriterionCategoryChannelAvailabilityModeEnum, -) -from .types.criterion_category_locale_availability_mode import ( - CriterionCategoryLocaleAvailabilityModeEnum, -) -from .types.criterion_system_serving_status import ( - CriterionSystemServingStatusEnum, -) -from .types.criterion_type import CriterionTypeEnum -from .types.custom_audience_member_type import CustomAudienceMemberTypeEnum -from .types.custom_audience_status import CustomAudienceStatusEnum -from .types.custom_audience_type import CustomAudienceTypeEnum -from .types.custom_conversion_goal_status import CustomConversionGoalStatusEnum -from .types.custom_interest_member_type import CustomInterestMemberTypeEnum -from .types.custom_interest_status import CustomInterestStatusEnum -from .types.custom_interest_type import CustomInterestTypeEnum -from .types.customer_acquisition_optimization_mode import ( - CustomerAcquisitionOptimizationModeEnum, -) -from .types.customer_match_upload_key_type import CustomerMatchUploadKeyTypeEnum -from .types.customer_pay_per_conversion_eligibility_failure_reason import ( - CustomerPayPerConversionEligibilityFailureReasonEnum, -) -from .types.customer_status import CustomerStatusEnum -from .types.customizer_attribute_status import CustomizerAttributeStatusEnum -from .types.customizer_attribute_type import CustomizerAttributeTypeEnum -from .types.customizer_value_status import CustomizerValueStatusEnum -from .types.data_driven_model_status import DataDrivenModelStatusEnum -from .types.data_link_status import DataLinkStatusEnum -from .types.data_link_type import DataLinkTypeEnum -from .types.day_of_week import DayOfWeekEnum -from .types.demand_gen_channel_config import DemandGenChannelConfigEnum -from .types.demand_gen_channel_strategy import DemandGenChannelStrategyEnum -from .types.device import DeviceEnum -from .types.display_ad_format_setting import DisplayAdFormatSettingEnum -from .types.display_upload_product_type import DisplayUploadProductTypeEnum -from .types.distance_bucket import DistanceBucketEnum -from .types.eu_political_advertising_status import ( - EuPoliticalAdvertisingStatusEnum, -) -from .types.experiment_metric import ExperimentMetricEnum -from .types.experiment_metric_direction import ExperimentMetricDirectionEnum -from .types.experiment_status import ExperimentStatusEnum -from .types.experiment_type import ExperimentTypeEnum -from .types.external_conversion_source import ExternalConversionSourceEnum -from .types.fixed_cpm_goal import FixedCpmGoalEnum -from .types.fixed_cpm_target_frequency_time_unit import ( - FixedCpmTargetFrequencyTimeUnitEnum, -) -from .types.frequency_cap_event_type import FrequencyCapEventTypeEnum -from .types.frequency_cap_level import FrequencyCapLevelEnum -from .types.frequency_cap_time_unit import FrequencyCapTimeUnitEnum -from .types.gender_type import GenderTypeEnum -from .types.geo_target_constant_status import GeoTargetConstantStatusEnum -from .types.geo_targeting_type import GeoTargetingTypeEnum -from .types.goal_config_level import GoalConfigLevelEnum -from .types.google_ads_field_category import GoogleAdsFieldCategoryEnum -from .types.google_ads_field_data_type import GoogleAdsFieldDataTypeEnum -from .types.google_voice_call_status import GoogleVoiceCallStatusEnum -from .types.hotel_asset_suggestion_status import HotelAssetSuggestionStatusEnum -from .types.hotel_date_selection_type import HotelDateSelectionTypeEnum -from .types.hotel_price_bucket import HotelPriceBucketEnum -from .types.hotel_rate_type import HotelRateTypeEnum -from .types.hotel_reconciliation_status import HotelReconciliationStatusEnum -from .types.identity_verification_program import IdentityVerificationProgramEnum -from .types.identity_verification_program_status import ( - IdentityVerificationProgramStatusEnum, -) -from .types.income_range_type import IncomeRangeTypeEnum -from .types.insights_knowledge_graph_entity_capabilities import ( - InsightsKnowledgeGraphEntityCapabilitiesEnum, -) -from .types.insights_trend import InsightsTrendEnum -from .types.interaction_event_type import InteractionEventTypeEnum -from .types.interaction_type import InteractionTypeEnum -from .types.invoice_type import InvoiceTypeEnum -from .types.keyword_match_type import KeywordMatchTypeEnum -from .types.keyword_plan_aggregate_metric_type import ( - KeywordPlanAggregateMetricTypeEnum, -) -from .types.keyword_plan_competition_level import ( - KeywordPlanCompetitionLevelEnum, -) -from .types.keyword_plan_concept_group_type import ( - KeywordPlanConceptGroupTypeEnum, -) -from .types.keyword_plan_forecast_interval import ( - KeywordPlanForecastIntervalEnum, -) -from .types.keyword_plan_keyword_annotation import ( - KeywordPlanKeywordAnnotationEnum, -) -from .types.keyword_plan_network import KeywordPlanNetworkEnum -from .types.label_status import LabelStatusEnum -from .types.lead_form_call_to_action_type import LeadFormCallToActionTypeEnum -from .types.lead_form_desired_intent import LeadFormDesiredIntentEnum -from .types.lead_form_field_user_input_type import ( - LeadFormFieldUserInputTypeEnum, -) -from .types.lead_form_post_submit_call_to_action_type import ( - LeadFormPostSubmitCallToActionTypeEnum, -) -from .types.legacy_app_install_ad_app_store import ( - LegacyAppInstallAdAppStoreEnum, -) -from .types.linked_account_type import LinkedAccountTypeEnum -from .types.linked_product_type import LinkedProductTypeEnum -from .types.listing_group_filter_custom_attribute_index import ( - ListingGroupFilterCustomAttributeIndexEnum, -) -from .types.listing_group_filter_listing_source import ( - ListingGroupFilterListingSourceEnum, -) -from .types.listing_group_filter_product_category_level import ( - ListingGroupFilterProductCategoryLevelEnum, -) -from .types.listing_group_filter_product_channel import ( - ListingGroupFilterProductChannelEnum, -) -from .types.listing_group_filter_product_condition import ( - ListingGroupFilterProductConditionEnum, -) -from .types.listing_group_filter_product_type_level import ( - ListingGroupFilterProductTypeLevelEnum, -) -from .types.listing_group_filter_type_enum import ListingGroupFilterTypeEnum -from .types.listing_group_type import ListingGroupTypeEnum -from .types.listing_type import ListingTypeEnum -from .types.local_services_business_registration_check_rejection_reason import ( - LocalServicesBusinessRegistrationCheckRejectionReasonEnum, -) -from .types.local_services_business_registration_type import ( - LocalServicesBusinessRegistrationTypeEnum, -) -from .types.local_services_conversation_type import ( - LocalServicesLeadConversationTypeEnum, -) -from .types.local_services_employee_status import ( - LocalServicesEmployeeStatusEnum, -) -from .types.local_services_employee_type import LocalServicesEmployeeTypeEnum -from .types.local_services_insurance_rejection_reason import ( - LocalServicesInsuranceRejectionReasonEnum, -) -from .types.local_services_lead_credit_issuance_decision import ( - LocalServicesLeadCreditIssuanceDecisionEnum, -) -from .types.local_services_lead_credit_state import LocalServicesCreditStateEnum -from .types.local_services_lead_status import LocalServicesLeadStatusEnum -from .types.local_services_lead_survey_answer import ( - LocalServicesLeadSurveyAnswerEnum, -) -from .types.local_services_lead_survey_dissatisfied_reason import ( - LocalServicesLeadSurveyDissatisfiedReasonEnum, -) -from .types.local_services_lead_survey_satisfied_reason import ( - LocalServicesLeadSurveySatisfiedReasonEnum, -) -from .types.local_services_lead_type import LocalServicesLeadTypeEnum -from .types.local_services_license_rejection_reason import ( - LocalServicesLicenseRejectionReasonEnum, -) -from .types.local_services_participant_type import ( - LocalServicesParticipantTypeEnum, -) -from .types.local_services_verification_artifact_status import ( - LocalServicesVerificationArtifactStatusEnum, -) -from .types.local_services_verification_artifact_type import ( - LocalServicesVerificationArtifactTypeEnum, -) -from .types.local_services_verification_status import ( - LocalServicesVerificationStatusEnum, -) -from .types.location_group_radius_units import LocationGroupRadiusUnitsEnum -from .types.location_ownership_type import LocationOwnershipTypeEnum -from .types.location_source_type import LocationSourceTypeEnum -from .types.location_string_filter_type import LocationStringFilterTypeEnum -from .types.lookalike_expansion_level import LookalikeExpansionLevelEnum -from .types.manager_link_status import ManagerLinkStatusEnum -from .types.media_type import MediaTypeEnum -from .types.mime_type import MimeTypeEnum -from .types.minute_of_hour import MinuteOfHourEnum -from .types.mobile_app_vendor import MobileAppVendorEnum -from .types.mobile_device_type import MobileDeviceTypeEnum -from .types.month_of_year import MonthOfYearEnum -from .types.negative_geo_target_type import NegativeGeoTargetTypeEnum -from .types.offline_conversion_diagnostic_status_enum import ( - OfflineConversionDiagnosticStatusEnum, -) -from .types.offline_event_upload_client_enum import OfflineEventUploadClientEnum -from .types.offline_user_data_job_failure_reason import ( - OfflineUserDataJobFailureReasonEnum, -) -from .types.offline_user_data_job_match_rate_range import ( - OfflineUserDataJobMatchRateRangeEnum, -) -from .types.offline_user_data_job_status import OfflineUserDataJobStatusEnum -from .types.offline_user_data_job_type import OfflineUserDataJobTypeEnum -from .types.operating_system_version_operator_type import ( - OperatingSystemVersionOperatorTypeEnum, -) -from .types.optimization_goal_type import OptimizationGoalTypeEnum -from .types.parental_status_type import ParentalStatusTypeEnum -from .types.payment_mode import PaymentModeEnum -from .types.performance_max_upgrade_status import ( - PerformanceMaxUpgradeStatusEnum, -) -from .types.placement_type import PlacementTypeEnum -from .types.policy_approval_status import PolicyApprovalStatusEnum -from .types.policy_review_status import PolicyReviewStatusEnum -from .types.policy_topic_entry_type import PolicyTopicEntryTypeEnum -from .types.policy_topic_evidence_destination_mismatch_url_type import ( - PolicyTopicEvidenceDestinationMismatchUrlTypeEnum, -) -from .types.policy_topic_evidence_destination_not_working_device import ( - PolicyTopicEvidenceDestinationNotWorkingDeviceEnum, -) -from .types.policy_topic_evidence_destination_not_working_dns_error_type import ( - PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum, -) -from .types.positive_geo_target_type import PositiveGeoTargetTypeEnum -from .types.price_extension_price_qualifier import ( - PriceExtensionPriceQualifierEnum, -) -from .types.price_extension_price_unit import PriceExtensionPriceUnitEnum -from .types.price_extension_type import PriceExtensionTypeEnum -from .types.product_availability import ProductAvailabilityEnum -from .types.product_category_level import ProductCategoryLevelEnum -from .types.product_category_state import ProductCategoryStateEnum -from .types.product_channel import ProductChannelEnum -from .types.product_channel_exclusivity import ProductChannelExclusivityEnum -from .types.product_condition import ProductConditionEnum -from .types.product_custom_attribute_index import ( - ProductCustomAttributeIndexEnum, -) -from .types.product_issue_severity import ProductIssueSeverityEnum -from .types.product_link_invitation_status import ( - ProductLinkInvitationStatusEnum, -) -from .types.product_status import ProductStatusEnum -from .types.product_type_level import ProductTypeLevelEnum -from .types.promotion_extension_discount_modifier import ( - PromotionExtensionDiscountModifierEnum, -) -from .types.promotion_extension_occasion import PromotionExtensionOccasionEnum -from .types.proximity_radius_units import ProximityRadiusUnitsEnum -from .types.quality_score_bucket import QualityScoreBucketEnum -from .types.reach_plan_age_range import ReachPlanAgeRangeEnum -from .types.reach_plan_conversion_rate_model import ( - ReachPlanConversionRateModelEnum, -) -from .types.reach_plan_network import ReachPlanNetworkEnum -from .types.reach_plan_surface import ReachPlanSurfaceEnum -from .types.recommendation_subscription_status import ( - RecommendationSubscriptionStatusEnum, -) -from .types.recommendation_type import RecommendationTypeEnum -from .types.resource_change_operation import ResourceChangeOperationEnum -from .types.resource_limit_type import ResourceLimitTypeEnum -from .types.response_content_type import ResponseContentTypeEnum -from .types.search_engine_results_page_type import ( - SearchEngineResultsPageTypeEnum, -) -from .types.search_term_match_type import SearchTermMatchTypeEnum -from .types.search_term_targeting_status import SearchTermTargetingStatusEnum -from .types.seasonality_event_scope import SeasonalityEventScopeEnum -from .types.seasonality_event_status import SeasonalityEventStatusEnum -from .types.served_asset_field_type import ServedAssetFieldTypeEnum -from .types.shared_set_status import SharedSetStatusEnum -from .types.shared_set_type import SharedSetTypeEnum -from .types.shopping_add_products_to_campaign_recommendation_enum import ( - ShoppingAddProductsToCampaignRecommendationEnum, -) -from .types.simulation_modification_method import ( - SimulationModificationMethodEnum, -) -from .types.simulation_type import SimulationTypeEnum -from .types.sk_ad_network_ad_event_type import SkAdNetworkAdEventTypeEnum -from .types.sk_ad_network_attribution_credit import ( - SkAdNetworkAttributionCreditEnum, -) -from .types.sk_ad_network_coarse_conversion_value import ( - SkAdNetworkCoarseConversionValueEnum, -) -from .types.sk_ad_network_source_type import SkAdNetworkSourceTypeEnum -from .types.sk_ad_network_user_type import SkAdNetworkUserTypeEnum -from .types.slot import SlotEnum -from .types.smart_campaign_not_eligible_reason import ( - SmartCampaignNotEligibleReasonEnum, -) -from .types.smart_campaign_status import SmartCampaignStatusEnum -from .types.spending_limit_type import SpendingLimitTypeEnum -from .types.summary_row_setting import SummaryRowSettingEnum -from .types.system_managed_entity_source import SystemManagedResourceSourceEnum -from .types.target_cpa_opt_in_recommendation_goal import ( - TargetCpaOptInRecommendationGoalEnum, -) -from .types.target_frequency_time_unit import TargetFrequencyTimeUnitEnum -from .types.target_impression_share_location import ( - TargetImpressionShareLocationEnum, -) -from .types.targeting_dimension import TargetingDimensionEnum -from .types.time_type import TimeTypeEnum -from .types.tracking_code_page_format import TrackingCodePageFormatEnum -from .types.tracking_code_type import TrackingCodeTypeEnum -from .types.user_identifier_source import UserIdentifierSourceEnum -from .types.user_interest_taxonomy_type import UserInterestTaxonomyTypeEnum -from .types.user_list_access_status import UserListAccessStatusEnum -from .types.user_list_closing_reason import UserListClosingReasonEnum -from .types.user_list_crm_data_source_type import UserListCrmDataSourceTypeEnum -from .types.user_list_customer_type_category import ( - UserListCustomerTypeCategoryEnum, -) -from .types.user_list_date_rule_item_operator import ( - UserListDateRuleItemOperatorEnum, -) -from .types.user_list_flexible_rule_operator import ( - UserListFlexibleRuleOperatorEnum, -) -from .types.user_list_logical_rule_operator import ( - UserListLogicalRuleOperatorEnum, -) -from .types.user_list_membership_status import UserListMembershipStatusEnum -from .types.user_list_number_rule_item_operator import ( - UserListNumberRuleItemOperatorEnum, -) -from .types.user_list_prepopulation_status import ( - UserListPrepopulationStatusEnum, -) -from .types.user_list_rule_type import UserListRuleTypeEnum -from .types.user_list_size_range import UserListSizeRangeEnum -from .types.user_list_string_rule_item_operator import ( - UserListStringRuleItemOperatorEnum, -) -from .types.user_list_type import UserListTypeEnum -from .types.value_rule_device_type import ValueRuleDeviceTypeEnum -from .types.value_rule_geo_location_match_type import ( - ValueRuleGeoLocationMatchTypeEnum, -) -from .types.value_rule_operation import ValueRuleOperationEnum -from .types.value_rule_set_attachment_type import ValueRuleSetAttachmentTypeEnum -from .types.value_rule_set_dimension import ValueRuleSetDimensionEnum -from .types.vanity_pharma_display_url_mode import VanityPharmaDisplayUrlModeEnum -from .types.vanity_pharma_text import VanityPharmaTextEnum -from .types.video_thumbnail import VideoThumbnailEnum -from .types.webpage_condition_operand import WebpageConditionOperandEnum -from .types.webpage_condition_operator import WebpageConditionOperatorEnum - -__all__ = ( - "AccessInvitationStatusEnum", - "AccessReasonEnum", - "AccessRoleEnum", - "AccountBudgetProposalStatusEnum", - "AccountBudgetProposalTypeEnum", - "AccountBudgetStatusEnum", - "AccountLinkStatusEnum", - "AdDestinationTypeEnum", - "AdFormatTypeEnum", - "AdGroupAdPrimaryStatusEnum", - "AdGroupAdPrimaryStatusReasonEnum", - "AdGroupAdRotationModeEnum", - "AdGroupAdStatusEnum", - "AdGroupCriterionApprovalStatusEnum", - "AdGroupCriterionPrimaryStatusEnum", - "AdGroupCriterionPrimaryStatusReasonEnum", - "AdGroupCriterionStatusEnum", - "AdGroupPrimaryStatusEnum", - "AdGroupPrimaryStatusReasonEnum", - "AdGroupStatusEnum", - "AdGroupTypeEnum", - "AdNetworkTypeEnum", - "AdServingOptimizationStatusEnum", - "AdStrengthActionItemTypeEnum", - "AdStrengthEnum", - "AdTypeEnum", - "AdvertisingChannelSubTypeEnum", - "AdvertisingChannelTypeEnum", - "AgeRangeTypeEnum", - "AndroidPrivacyInteractionTypeEnum", - "AndroidPrivacyNetworkTypeEnum", - "AppBiddingGoalEnum", - "AppCampaignAppStoreEnum", - "AppCampaignBiddingStrategyGoalTypeEnum", - "AppPaymentModelTypeEnum", - "AppUrlOperatingSystemTypeEnum", - "AssetAutomationStatusEnum", - "AssetAutomationTypeEnum", - "AssetCoverageVideoAspectRatioRequirementEnum", - "AssetFieldTypeEnum", - "AssetGroupPrimaryStatusEnum", - "AssetGroupPrimaryStatusReasonEnum", - "AssetGroupSignalApprovalStatusEnum", - "AssetGroupStatusEnum", - "AssetLinkPrimaryStatusEnum", - "AssetLinkPrimaryStatusReasonEnum", - "AssetLinkStatusEnum", - "AssetOfflineEvaluationErrorReasonsEnum", - "AssetPerformanceLabelEnum", - "AssetSetAssetStatusEnum", - "AssetSetLinkStatusEnum", - "AssetSetStatusEnum", - "AssetSetTypeEnum", - "AssetSourceEnum", - "AssetTypeEnum", - "AsyncActionStatusEnum", - "AttributionModelEnum", - "AudienceInsightsDimensionEnum", - "AudienceInsightsMarketingObjectiveEnum", - "AudienceScopeEnum", - "AudienceStatusEnum", - "BatchJobStatusEnum", - "BidModifierSourceEnum", - "BiddingSourceEnum", - "BiddingStrategyStatusEnum", - "BiddingStrategySystemStatusEnum", - "BiddingStrategyTypeEnum", - "BillingSetupStatusEnum", - "BrandRequestRejectionReasonEnum", - "BrandSafetySuitabilityEnum", - "BrandStateEnum", - "BudgetCampaignAssociationStatusEnum", - "BudgetDeliveryMethodEnum", - "BudgetPeriodEnum", - "BudgetStatusEnum", - "BudgetTypeEnum", - "BusinessMessageCallToActionTypeEnum", - "BusinessMessageProviderEnum", - "CallConversionReportingStateEnum", - "CallToActionTypeEnum", - "CallTrackingDisplayLocationEnum", - "CallTypeEnum", - "CampaignCriterionStatusEnum", - "CampaignDraftStatusEnum", - "CampaignExperimentTypeEnum", - "CampaignGroupStatusEnum", - "CampaignKeywordMatchTypeEnum", - "CampaignPrimaryStatusEnum", - "CampaignPrimaryStatusReasonEnum", - "CampaignServingStatusEnum", - "CampaignSharedSetStatusEnum", - "CampaignStatusEnum", - "ChainRelationshipTypeEnum", - "ChangeClientTypeEnum", - "ChangeEventResourceTypeEnum", - "ChangeStatusOperationEnum", - "ChangeStatusResourceTypeEnum", - "ClickTypeEnum", - "CombinedAudienceStatusEnum", - "ConsentStatusEnum", - "ContentLabelTypeEnum", - "ConversionActionCategoryEnum", - "ConversionActionCountingTypeEnum", - "ConversionActionStatusEnum", - "ConversionActionTypeEnum", - "ConversionAdjustmentTypeEnum", - "ConversionAttributionEventTypeEnum", - "ConversionCustomVariableStatusEnum", - "ConversionCustomerTypeEnum", - "ConversionEnvironmentEnum", - "ConversionLagBucketEnum", - "ConversionOrAdjustmentLagBucketEnum", - "ConversionOriginEnum", - "ConversionTrackingStatusEnum", - "ConversionValueRulePrimaryDimensionEnum", - "ConversionValueRuleSetStatusEnum", - "ConversionValueRuleStatusEnum", - "ConvertingUserPriorEngagementTypeAndLtvBucketEnum", - "CriterionCategoryChannelAvailabilityModeEnum", - "CriterionCategoryLocaleAvailabilityModeEnum", - "CriterionSystemServingStatusEnum", - "CriterionTypeEnum", - "CustomAudienceMemberTypeEnum", - "CustomAudienceStatusEnum", - "CustomAudienceTypeEnum", - "CustomConversionGoalStatusEnum", - "CustomInterestMemberTypeEnum", - "CustomInterestStatusEnum", - "CustomInterestTypeEnum", - "CustomerAcquisitionOptimizationModeEnum", - "CustomerMatchUploadKeyTypeEnum", - "CustomerPayPerConversionEligibilityFailureReasonEnum", - "CustomerStatusEnum", - "CustomizerAttributeStatusEnum", - "CustomizerAttributeTypeEnum", - "CustomizerValueStatusEnum", - "DataDrivenModelStatusEnum", - "DataLinkStatusEnum", - "DataLinkTypeEnum", - "DayOfWeekEnum", - "DemandGenChannelConfigEnum", - "DemandGenChannelStrategyEnum", - "DeviceEnum", - "DisplayAdFormatSettingEnum", - "DisplayUploadProductTypeEnum", - "DistanceBucketEnum", - "EuPoliticalAdvertisingStatusEnum", - "ExperimentMetricDirectionEnum", - "ExperimentMetricEnum", - "ExperimentStatusEnum", - "ExperimentTypeEnum", - "ExternalConversionSourceEnum", - "FixedCpmGoalEnum", - "FixedCpmTargetFrequencyTimeUnitEnum", - "FrequencyCapEventTypeEnum", - "FrequencyCapLevelEnum", - "FrequencyCapTimeUnitEnum", - "GenderTypeEnum", - "GeoTargetConstantStatusEnum", - "GeoTargetingTypeEnum", - "GoalConfigLevelEnum", - "GoogleAdsFieldCategoryEnum", - "GoogleAdsFieldDataTypeEnum", - "GoogleVoiceCallStatusEnum", - "HotelAssetSuggestionStatusEnum", - "HotelDateSelectionTypeEnum", - "HotelPriceBucketEnum", - "HotelRateTypeEnum", - "HotelReconciliationStatusEnum", - "IdentityVerificationProgramEnum", - "IdentityVerificationProgramStatusEnum", - "IncomeRangeTypeEnum", - "InsightsKnowledgeGraphEntityCapabilitiesEnum", - "InsightsTrendEnum", - "InteractionEventTypeEnum", - "InteractionTypeEnum", - "InvoiceTypeEnum", - "KeywordMatchTypeEnum", - "KeywordPlanAggregateMetricTypeEnum", - "KeywordPlanCompetitionLevelEnum", - "KeywordPlanConceptGroupTypeEnum", - "KeywordPlanForecastIntervalEnum", - "KeywordPlanKeywordAnnotationEnum", - "KeywordPlanNetworkEnum", - "LabelStatusEnum", - "LeadFormCallToActionTypeEnum", - "LeadFormDesiredIntentEnum", - "LeadFormFieldUserInputTypeEnum", - "LeadFormPostSubmitCallToActionTypeEnum", - "LegacyAppInstallAdAppStoreEnum", - "LinkedAccountTypeEnum", - "LinkedProductTypeEnum", - "ListingGroupFilterCustomAttributeIndexEnum", - "ListingGroupFilterListingSourceEnum", - "ListingGroupFilterProductCategoryLevelEnum", - "ListingGroupFilterProductChannelEnum", - "ListingGroupFilterProductConditionEnum", - "ListingGroupFilterProductTypeLevelEnum", - "ListingGroupFilterTypeEnum", - "ListingGroupTypeEnum", - "ListingTypeEnum", - "LocalServicesBusinessRegistrationCheckRejectionReasonEnum", - "LocalServicesBusinessRegistrationTypeEnum", - "LocalServicesCreditStateEnum", - "LocalServicesEmployeeStatusEnum", - "LocalServicesEmployeeTypeEnum", - "LocalServicesInsuranceRejectionReasonEnum", - "LocalServicesLeadConversationTypeEnum", - "LocalServicesLeadCreditIssuanceDecisionEnum", - "LocalServicesLeadStatusEnum", - "LocalServicesLeadSurveyAnswerEnum", - "LocalServicesLeadSurveyDissatisfiedReasonEnum", - "LocalServicesLeadSurveySatisfiedReasonEnum", - "LocalServicesLeadTypeEnum", - "LocalServicesLicenseRejectionReasonEnum", - "LocalServicesParticipantTypeEnum", - "LocalServicesVerificationArtifactStatusEnum", - "LocalServicesVerificationArtifactTypeEnum", - "LocalServicesVerificationStatusEnum", - "LocationGroupRadiusUnitsEnum", - "LocationOwnershipTypeEnum", - "LocationSourceTypeEnum", - "LocationStringFilterTypeEnum", - "LookalikeExpansionLevelEnum", - "ManagerLinkStatusEnum", - "MediaTypeEnum", - "MimeTypeEnum", - "MinuteOfHourEnum", - "MobileAppVendorEnum", - "MobileDeviceTypeEnum", - "MonthOfYearEnum", - "NegativeGeoTargetTypeEnum", - "OfflineConversionDiagnosticStatusEnum", - "OfflineEventUploadClientEnum", - "OfflineUserDataJobFailureReasonEnum", - "OfflineUserDataJobMatchRateRangeEnum", - "OfflineUserDataJobStatusEnum", - "OfflineUserDataJobTypeEnum", - "OperatingSystemVersionOperatorTypeEnum", - "OptimizationGoalTypeEnum", - "ParentalStatusTypeEnum", - "PaymentModeEnum", - "PerformanceMaxUpgradeStatusEnum", - "PlacementTypeEnum", - "PolicyApprovalStatusEnum", - "PolicyReviewStatusEnum", - "PolicyTopicEntryTypeEnum", - "PolicyTopicEvidenceDestinationMismatchUrlTypeEnum", - "PolicyTopicEvidenceDestinationNotWorkingDeviceEnum", - "PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum", - "PositiveGeoTargetTypeEnum", - "PriceExtensionPriceQualifierEnum", - "PriceExtensionPriceUnitEnum", - "PriceExtensionTypeEnum", - "ProductAvailabilityEnum", - "ProductCategoryLevelEnum", - "ProductCategoryStateEnum", - "ProductChannelEnum", - "ProductChannelExclusivityEnum", - "ProductConditionEnum", - "ProductCustomAttributeIndexEnum", - "ProductIssueSeverityEnum", - "ProductLinkInvitationStatusEnum", - "ProductStatusEnum", - "ProductTypeLevelEnum", - "PromotionExtensionDiscountModifierEnum", - "PromotionExtensionOccasionEnum", - "ProximityRadiusUnitsEnum", - "QualityScoreBucketEnum", - "ReachPlanAgeRangeEnum", - "ReachPlanConversionRateModelEnum", - "ReachPlanNetworkEnum", - "ReachPlanSurfaceEnum", - "RecommendationSubscriptionStatusEnum", - "RecommendationTypeEnum", - "ResourceChangeOperationEnum", - "ResourceLimitTypeEnum", - "ResponseContentTypeEnum", - "SearchEngineResultsPageTypeEnum", - "SearchTermMatchTypeEnum", - "SearchTermTargetingStatusEnum", - "SeasonalityEventScopeEnum", - "SeasonalityEventStatusEnum", - "ServedAssetFieldTypeEnum", - "SharedSetStatusEnum", - "SharedSetTypeEnum", - "ShoppingAddProductsToCampaignRecommendationEnum", - "SimulationModificationMethodEnum", - "SimulationTypeEnum", - "SkAdNetworkAdEventTypeEnum", - "SkAdNetworkAttributionCreditEnum", - "SkAdNetworkCoarseConversionValueEnum", - "SkAdNetworkSourceTypeEnum", - "SkAdNetworkUserTypeEnum", - "SlotEnum", - "SmartCampaignNotEligibleReasonEnum", - "SmartCampaignStatusEnum", - "SpendingLimitTypeEnum", - "SummaryRowSettingEnum", - "SystemManagedResourceSourceEnum", - "TargetCpaOptInRecommendationGoalEnum", - "TargetFrequencyTimeUnitEnum", - "TargetImpressionShareLocationEnum", - "TargetingDimensionEnum", - "TimeTypeEnum", - "TrackingCodePageFormatEnum", - "TrackingCodeTypeEnum", - "UserIdentifierSourceEnum", - "UserInterestTaxonomyTypeEnum", - "UserListAccessStatusEnum", - "UserListClosingReasonEnum", - "UserListCrmDataSourceTypeEnum", - "UserListCustomerTypeCategoryEnum", - "UserListDateRuleItemOperatorEnum", - "UserListFlexibleRuleOperatorEnum", - "UserListLogicalRuleOperatorEnum", - "UserListMembershipStatusEnum", - "UserListNumberRuleItemOperatorEnum", - "UserListPrepopulationStatusEnum", - "UserListRuleTypeEnum", - "UserListSizeRangeEnum", - "UserListStringRuleItemOperatorEnum", - "UserListTypeEnum", - "ValueRuleDeviceTypeEnum", - "ValueRuleGeoLocationMatchTypeEnum", - "ValueRuleOperationEnum", - "ValueRuleSetAttachmentTypeEnum", - "ValueRuleSetDimensionEnum", - "VanityPharmaDisplayUrlModeEnum", - "VanityPharmaTextEnum", - "VideoThumbnailEnum", - "WebpageConditionOperandEnum", - "WebpageConditionOperatorEnum", -) diff --git a/google/ads/googleads/v19/enums/types/__init__.py b/google/ads/googleads/v19/enums/types/__init__.py deleted file mode 100644 index 67e2edbc0..000000000 --- a/google/ads/googleads/v19/enums/types/__init__.py +++ /dev/null @@ -1,1350 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .access_invitation_status import ( - AccessInvitationStatusEnum, -) -from .access_reason import ( - AccessReasonEnum, -) -from .access_role import ( - AccessRoleEnum, -) -from .account_budget_proposal_status import ( - AccountBudgetProposalStatusEnum, -) -from .account_budget_proposal_type import ( - AccountBudgetProposalTypeEnum, -) -from .account_budget_status import ( - AccountBudgetStatusEnum, -) -from .account_link_status import ( - AccountLinkStatusEnum, -) -from .ad_destination_type import ( - AdDestinationTypeEnum, -) -from .ad_format_type import ( - AdFormatTypeEnum, -) -from .ad_group_ad_primary_status import ( - AdGroupAdPrimaryStatusEnum, -) -from .ad_group_ad_primary_status_reason import ( - AdGroupAdPrimaryStatusReasonEnum, -) -from .ad_group_ad_rotation_mode import ( - AdGroupAdRotationModeEnum, -) -from .ad_group_ad_status import ( - AdGroupAdStatusEnum, -) -from .ad_group_criterion_approval_status import ( - AdGroupCriterionApprovalStatusEnum, -) -from .ad_group_criterion_primary_status import ( - AdGroupCriterionPrimaryStatusEnum, -) -from .ad_group_criterion_primary_status_reason import ( - AdGroupCriterionPrimaryStatusReasonEnum, -) -from .ad_group_criterion_status import ( - AdGroupCriterionStatusEnum, -) -from .ad_group_primary_status import ( - AdGroupPrimaryStatusEnum, -) -from .ad_group_primary_status_reason import ( - AdGroupPrimaryStatusReasonEnum, -) -from .ad_group_status import ( - AdGroupStatusEnum, -) -from .ad_group_type import ( - AdGroupTypeEnum, -) -from .ad_network_type import ( - AdNetworkTypeEnum, -) -from .ad_serving_optimization_status import ( - AdServingOptimizationStatusEnum, -) -from .ad_strength import ( - AdStrengthEnum, -) -from .ad_strength_action_item_type import ( - AdStrengthActionItemTypeEnum, -) -from .ad_type import ( - AdTypeEnum, -) -from .advertising_channel_sub_type import ( - AdvertisingChannelSubTypeEnum, -) -from .advertising_channel_type import ( - AdvertisingChannelTypeEnum, -) -from .age_range_type import ( - AgeRangeTypeEnum, -) -from .android_privacy_interaction_type import ( - AndroidPrivacyInteractionTypeEnum, -) -from .android_privacy_network_type import ( - AndroidPrivacyNetworkTypeEnum, -) -from .app_bidding_goal import ( - AppBiddingGoalEnum, -) -from .app_campaign_app_store import ( - AppCampaignAppStoreEnum, -) -from .app_campaign_bidding_strategy_goal_type import ( - AppCampaignBiddingStrategyGoalTypeEnum, -) -from .app_payment_model_type import ( - AppPaymentModelTypeEnum, -) -from .app_url_operating_system_type import ( - AppUrlOperatingSystemTypeEnum, -) -from .asset_automation_status import ( - AssetAutomationStatusEnum, -) -from .asset_automation_type import ( - AssetAutomationTypeEnum, -) -from .asset_coverage_video_aspect_ratio_requirement import ( - AssetCoverageVideoAspectRatioRequirementEnum, -) -from .asset_field_type import ( - AssetFieldTypeEnum, -) -from .asset_group_primary_status import ( - AssetGroupPrimaryStatusEnum, -) -from .asset_group_primary_status_reason import ( - AssetGroupPrimaryStatusReasonEnum, -) -from .asset_group_signal_approval_status import ( - AssetGroupSignalApprovalStatusEnum, -) -from .asset_group_status import ( - AssetGroupStatusEnum, -) -from .asset_link_primary_status import ( - AssetLinkPrimaryStatusEnum, -) -from .asset_link_primary_status_reason import ( - AssetLinkPrimaryStatusReasonEnum, -) -from .asset_link_status import ( - AssetLinkStatusEnum, -) -from .asset_offline_evaluation_error_reasons import ( - AssetOfflineEvaluationErrorReasonsEnum, -) -from .asset_performance_label import ( - AssetPerformanceLabelEnum, -) -from .asset_set_asset_status import ( - AssetSetAssetStatusEnum, -) -from .asset_set_link_status import ( - AssetSetLinkStatusEnum, -) -from .asset_set_status import ( - AssetSetStatusEnum, -) -from .asset_set_type import ( - AssetSetTypeEnum, -) -from .asset_source import ( - AssetSourceEnum, -) -from .asset_type import ( - AssetTypeEnum, -) -from .async_action_status import ( - AsyncActionStatusEnum, -) -from .attribution_model import ( - AttributionModelEnum, -) -from .audience_insights_dimension import ( - AudienceInsightsDimensionEnum, -) -from .audience_insights_marketing_objective import ( - AudienceInsightsMarketingObjectiveEnum, -) -from .audience_scope import ( - AudienceScopeEnum, -) -from .audience_status import ( - AudienceStatusEnum, -) -from .batch_job_status import ( - BatchJobStatusEnum, -) -from .bid_modifier_source import ( - BidModifierSourceEnum, -) -from .bidding_source import ( - BiddingSourceEnum, -) -from .bidding_strategy_status import ( - BiddingStrategyStatusEnum, -) -from .bidding_strategy_system_status import ( - BiddingStrategySystemStatusEnum, -) -from .bidding_strategy_type import ( - BiddingStrategyTypeEnum, -) -from .billing_setup_status import ( - BillingSetupStatusEnum, -) -from .brand_request_rejection_reason import ( - BrandRequestRejectionReasonEnum, -) -from .brand_safety_suitability import ( - BrandSafetySuitabilityEnum, -) -from .brand_state import ( - BrandStateEnum, -) -from .budget_campaign_association_status import ( - BudgetCampaignAssociationStatusEnum, -) -from .budget_delivery_method import ( - BudgetDeliveryMethodEnum, -) -from .budget_period import ( - BudgetPeriodEnum, -) -from .budget_status import ( - BudgetStatusEnum, -) -from .budget_type import ( - BudgetTypeEnum, -) -from .business_message_call_to_action_type import ( - BusinessMessageCallToActionTypeEnum, -) -from .business_message_provider import ( - BusinessMessageProviderEnum, -) -from .call_conversion_reporting_state import ( - CallConversionReportingStateEnum, -) -from .call_to_action_type import ( - CallToActionTypeEnum, -) -from .call_tracking_display_location import ( - CallTrackingDisplayLocationEnum, -) -from .call_type import ( - CallTypeEnum, -) -from .campaign_criterion_status import ( - CampaignCriterionStatusEnum, -) -from .campaign_draft_status import ( - CampaignDraftStatusEnum, -) -from .campaign_experiment_type import ( - CampaignExperimentTypeEnum, -) -from .campaign_group_status import ( - CampaignGroupStatusEnum, -) -from .campaign_keyword_match_type import ( - CampaignKeywordMatchTypeEnum, -) -from .campaign_primary_status import ( - CampaignPrimaryStatusEnum, -) -from .campaign_primary_status_reason import ( - CampaignPrimaryStatusReasonEnum, -) -from .campaign_serving_status import ( - CampaignServingStatusEnum, -) -from .campaign_shared_set_status import ( - CampaignSharedSetStatusEnum, -) -from .campaign_status import ( - CampaignStatusEnum, -) -from .chain_relationship_type import ( - ChainRelationshipTypeEnum, -) -from .change_client_type import ( - ChangeClientTypeEnum, -) -from .change_event_resource_type import ( - ChangeEventResourceTypeEnum, -) -from .change_status_operation import ( - ChangeStatusOperationEnum, -) -from .change_status_resource_type import ( - ChangeStatusResourceTypeEnum, -) -from .click_type import ( - ClickTypeEnum, -) -from .combined_audience_status import ( - CombinedAudienceStatusEnum, -) -from .consent_status import ( - ConsentStatusEnum, -) -from .content_label_type import ( - ContentLabelTypeEnum, -) -from .conversion_action_category import ( - ConversionActionCategoryEnum, -) -from .conversion_action_counting_type import ( - ConversionActionCountingTypeEnum, -) -from .conversion_action_status import ( - ConversionActionStatusEnum, -) -from .conversion_action_type import ( - ConversionActionTypeEnum, -) -from .conversion_adjustment_type import ( - ConversionAdjustmentTypeEnum, -) -from .conversion_attribution_event_type import ( - ConversionAttributionEventTypeEnum, -) -from .conversion_custom_variable_status import ( - ConversionCustomVariableStatusEnum, -) -from .conversion_customer_type import ( - ConversionCustomerTypeEnum, -) -from .conversion_environment_enum import ( - ConversionEnvironmentEnum, -) -from .conversion_lag_bucket import ( - ConversionLagBucketEnum, -) -from .conversion_or_adjustment_lag_bucket import ( - ConversionOrAdjustmentLagBucketEnum, -) -from .conversion_origin import ( - ConversionOriginEnum, -) -from .conversion_tracking_status_enum import ( - ConversionTrackingStatusEnum, -) -from .conversion_value_rule_primary_dimension import ( - ConversionValueRulePrimaryDimensionEnum, -) -from .conversion_value_rule_set_status import ( - ConversionValueRuleSetStatusEnum, -) -from .conversion_value_rule_status import ( - ConversionValueRuleStatusEnum, -) -from .converting_user_prior_engagement_type_and_ltv_bucket import ( - ConvertingUserPriorEngagementTypeAndLtvBucketEnum, -) -from .criterion_category_channel_availability_mode import ( - CriterionCategoryChannelAvailabilityModeEnum, -) -from .criterion_category_locale_availability_mode import ( - CriterionCategoryLocaleAvailabilityModeEnum, -) -from .criterion_system_serving_status import ( - CriterionSystemServingStatusEnum, -) -from .criterion_type import ( - CriterionTypeEnum, -) -from .custom_audience_member_type import ( - CustomAudienceMemberTypeEnum, -) -from .custom_audience_status import ( - CustomAudienceStatusEnum, -) -from .custom_audience_type import ( - CustomAudienceTypeEnum, -) -from .custom_conversion_goal_status import ( - CustomConversionGoalStatusEnum, -) -from .custom_interest_member_type import ( - CustomInterestMemberTypeEnum, -) -from .custom_interest_status import ( - CustomInterestStatusEnum, -) -from .custom_interest_type import ( - CustomInterestTypeEnum, -) -from .customer_acquisition_optimization_mode import ( - CustomerAcquisitionOptimizationModeEnum, -) -from .customer_match_upload_key_type import ( - CustomerMatchUploadKeyTypeEnum, -) -from .customer_pay_per_conversion_eligibility_failure_reason import ( - CustomerPayPerConversionEligibilityFailureReasonEnum, -) -from .customer_status import ( - CustomerStatusEnum, -) -from .customizer_attribute_status import ( - CustomizerAttributeStatusEnum, -) -from .customizer_attribute_type import ( - CustomizerAttributeTypeEnum, -) -from .customizer_value_status import ( - CustomizerValueStatusEnum, -) -from .data_driven_model_status import ( - DataDrivenModelStatusEnum, -) -from .data_link_status import ( - DataLinkStatusEnum, -) -from .data_link_type import ( - DataLinkTypeEnum, -) -from .day_of_week import ( - DayOfWeekEnum, -) -from .demand_gen_channel_config import ( - DemandGenChannelConfigEnum, -) -from .demand_gen_channel_strategy import ( - DemandGenChannelStrategyEnum, -) -from .device import ( - DeviceEnum, -) -from .display_ad_format_setting import ( - DisplayAdFormatSettingEnum, -) -from .display_upload_product_type import ( - DisplayUploadProductTypeEnum, -) -from .distance_bucket import ( - DistanceBucketEnum, -) -from .eu_political_advertising_status import ( - EuPoliticalAdvertisingStatusEnum, -) -from .experiment_metric import ( - ExperimentMetricEnum, -) -from .experiment_metric_direction import ( - ExperimentMetricDirectionEnum, -) -from .experiment_status import ( - ExperimentStatusEnum, -) -from .experiment_type import ( - ExperimentTypeEnum, -) -from .external_conversion_source import ( - ExternalConversionSourceEnum, -) -from .fixed_cpm_goal import ( - FixedCpmGoalEnum, -) -from .fixed_cpm_target_frequency_time_unit import ( - FixedCpmTargetFrequencyTimeUnitEnum, -) -from .frequency_cap_event_type import ( - FrequencyCapEventTypeEnum, -) -from .frequency_cap_level import ( - FrequencyCapLevelEnum, -) -from .frequency_cap_time_unit import ( - FrequencyCapTimeUnitEnum, -) -from .gender_type import ( - GenderTypeEnum, -) -from .geo_target_constant_status import ( - GeoTargetConstantStatusEnum, -) -from .geo_targeting_type import ( - GeoTargetingTypeEnum, -) -from .goal_config_level import ( - GoalConfigLevelEnum, -) -from .google_ads_field_category import ( - GoogleAdsFieldCategoryEnum, -) -from .google_ads_field_data_type import ( - GoogleAdsFieldDataTypeEnum, -) -from .google_voice_call_status import ( - GoogleVoiceCallStatusEnum, -) -from .hotel_asset_suggestion_status import ( - HotelAssetSuggestionStatusEnum, -) -from .hotel_date_selection_type import ( - HotelDateSelectionTypeEnum, -) -from .hotel_price_bucket import ( - HotelPriceBucketEnum, -) -from .hotel_rate_type import ( - HotelRateTypeEnum, -) -from .hotel_reconciliation_status import ( - HotelReconciliationStatusEnum, -) -from .identity_verification_program import ( - IdentityVerificationProgramEnum, -) -from .identity_verification_program_status import ( - IdentityVerificationProgramStatusEnum, -) -from .income_range_type import ( - IncomeRangeTypeEnum, -) -from .insights_knowledge_graph_entity_capabilities import ( - InsightsKnowledgeGraphEntityCapabilitiesEnum, -) -from .insights_trend import ( - InsightsTrendEnum, -) -from .interaction_event_type import ( - InteractionEventTypeEnum, -) -from .interaction_type import ( - InteractionTypeEnum, -) -from .invoice_type import ( - InvoiceTypeEnum, -) -from .keyword_match_type import ( - KeywordMatchTypeEnum, -) -from .keyword_plan_aggregate_metric_type import ( - KeywordPlanAggregateMetricTypeEnum, -) -from .keyword_plan_competition_level import ( - KeywordPlanCompetitionLevelEnum, -) -from .keyword_plan_concept_group_type import ( - KeywordPlanConceptGroupTypeEnum, -) -from .keyword_plan_forecast_interval import ( - KeywordPlanForecastIntervalEnum, -) -from .keyword_plan_keyword_annotation import ( - KeywordPlanKeywordAnnotationEnum, -) -from .keyword_plan_network import ( - KeywordPlanNetworkEnum, -) -from .label_status import ( - LabelStatusEnum, -) -from .lead_form_call_to_action_type import ( - LeadFormCallToActionTypeEnum, -) -from .lead_form_desired_intent import ( - LeadFormDesiredIntentEnum, -) -from .lead_form_field_user_input_type import ( - LeadFormFieldUserInputTypeEnum, -) -from .lead_form_post_submit_call_to_action_type import ( - LeadFormPostSubmitCallToActionTypeEnum, -) -from .legacy_app_install_ad_app_store import ( - LegacyAppInstallAdAppStoreEnum, -) -from .linked_account_type import ( - LinkedAccountTypeEnum, -) -from .linked_product_type import ( - LinkedProductTypeEnum, -) -from .listing_group_filter_custom_attribute_index import ( - ListingGroupFilterCustomAttributeIndexEnum, -) -from .listing_group_filter_listing_source import ( - ListingGroupFilterListingSourceEnum, -) -from .listing_group_filter_product_category_level import ( - ListingGroupFilterProductCategoryLevelEnum, -) -from .listing_group_filter_product_channel import ( - ListingGroupFilterProductChannelEnum, -) -from .listing_group_filter_product_condition import ( - ListingGroupFilterProductConditionEnum, -) -from .listing_group_filter_product_type_level import ( - ListingGroupFilterProductTypeLevelEnum, -) -from .listing_group_filter_type_enum import ( - ListingGroupFilterTypeEnum, -) -from .listing_group_type import ( - ListingGroupTypeEnum, -) -from .listing_type import ( - ListingTypeEnum, -) -from .local_services_business_registration_check_rejection_reason import ( - LocalServicesBusinessRegistrationCheckRejectionReasonEnum, -) -from .local_services_business_registration_type import ( - LocalServicesBusinessRegistrationTypeEnum, -) -from .local_services_conversation_type import ( - LocalServicesLeadConversationTypeEnum, -) -from .local_services_employee_status import ( - LocalServicesEmployeeStatusEnum, -) -from .local_services_employee_type import ( - LocalServicesEmployeeTypeEnum, -) -from .local_services_insurance_rejection_reason import ( - LocalServicesInsuranceRejectionReasonEnum, -) -from .local_services_lead_credit_issuance_decision import ( - LocalServicesLeadCreditIssuanceDecisionEnum, -) -from .local_services_lead_credit_state import ( - LocalServicesCreditStateEnum, -) -from .local_services_lead_status import ( - LocalServicesLeadStatusEnum, -) -from .local_services_lead_survey_answer import ( - LocalServicesLeadSurveyAnswerEnum, -) -from .local_services_lead_survey_dissatisfied_reason import ( - LocalServicesLeadSurveyDissatisfiedReasonEnum, -) -from .local_services_lead_survey_satisfied_reason import ( - LocalServicesLeadSurveySatisfiedReasonEnum, -) -from .local_services_lead_type import ( - LocalServicesLeadTypeEnum, -) -from .local_services_license_rejection_reason import ( - LocalServicesLicenseRejectionReasonEnum, -) -from .local_services_participant_type import ( - LocalServicesParticipantTypeEnum, -) -from .local_services_verification_artifact_status import ( - LocalServicesVerificationArtifactStatusEnum, -) -from .local_services_verification_artifact_type import ( - LocalServicesVerificationArtifactTypeEnum, -) -from .local_services_verification_status import ( - LocalServicesVerificationStatusEnum, -) -from .location_group_radius_units import ( - LocationGroupRadiusUnitsEnum, -) -from .location_ownership_type import ( - LocationOwnershipTypeEnum, -) -from .location_source_type import ( - LocationSourceTypeEnum, -) -from .location_string_filter_type import ( - LocationStringFilterTypeEnum, -) -from .lookalike_expansion_level import ( - LookalikeExpansionLevelEnum, -) -from .manager_link_status import ( - ManagerLinkStatusEnum, -) -from .media_type import ( - MediaTypeEnum, -) -from .mime_type import ( - MimeTypeEnum, -) -from .minute_of_hour import ( - MinuteOfHourEnum, -) -from .mobile_app_vendor import ( - MobileAppVendorEnum, -) -from .mobile_device_type import ( - MobileDeviceTypeEnum, -) -from .month_of_year import ( - MonthOfYearEnum, -) -from .negative_geo_target_type import ( - NegativeGeoTargetTypeEnum, -) -from .offline_conversion_diagnostic_status_enum import ( - OfflineConversionDiagnosticStatusEnum, -) -from .offline_event_upload_client_enum import ( - OfflineEventUploadClientEnum, -) -from .offline_user_data_job_failure_reason import ( - OfflineUserDataJobFailureReasonEnum, -) -from .offline_user_data_job_match_rate_range import ( - OfflineUserDataJobMatchRateRangeEnum, -) -from .offline_user_data_job_status import ( - OfflineUserDataJobStatusEnum, -) -from .offline_user_data_job_type import ( - OfflineUserDataJobTypeEnum, -) -from .operating_system_version_operator_type import ( - OperatingSystemVersionOperatorTypeEnum, -) -from .optimization_goal_type import ( - OptimizationGoalTypeEnum, -) -from .parental_status_type import ( - ParentalStatusTypeEnum, -) -from .payment_mode import ( - PaymentModeEnum, -) -from .performance_max_upgrade_status import ( - PerformanceMaxUpgradeStatusEnum, -) -from .placement_type import ( - PlacementTypeEnum, -) -from .policy_approval_status import ( - PolicyApprovalStatusEnum, -) -from .policy_review_status import ( - PolicyReviewStatusEnum, -) -from .policy_topic_entry_type import ( - PolicyTopicEntryTypeEnum, -) -from .policy_topic_evidence_destination_mismatch_url_type import ( - PolicyTopicEvidenceDestinationMismatchUrlTypeEnum, -) -from .policy_topic_evidence_destination_not_working_device import ( - PolicyTopicEvidenceDestinationNotWorkingDeviceEnum, -) -from .policy_topic_evidence_destination_not_working_dns_error_type import ( - PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum, -) -from .positive_geo_target_type import ( - PositiveGeoTargetTypeEnum, -) -from .price_extension_price_qualifier import ( - PriceExtensionPriceQualifierEnum, -) -from .price_extension_price_unit import ( - PriceExtensionPriceUnitEnum, -) -from .price_extension_type import ( - PriceExtensionTypeEnum, -) -from .product_availability import ( - ProductAvailabilityEnum, -) -from .product_category_level import ( - ProductCategoryLevelEnum, -) -from .product_category_state import ( - ProductCategoryStateEnum, -) -from .product_channel import ( - ProductChannelEnum, -) -from .product_channel_exclusivity import ( - ProductChannelExclusivityEnum, -) -from .product_condition import ( - ProductConditionEnum, -) -from .product_custom_attribute_index import ( - ProductCustomAttributeIndexEnum, -) -from .product_issue_severity import ( - ProductIssueSeverityEnum, -) -from .product_link_invitation_status import ( - ProductLinkInvitationStatusEnum, -) -from .product_status import ( - ProductStatusEnum, -) -from .product_type_level import ( - ProductTypeLevelEnum, -) -from .promotion_extension_discount_modifier import ( - PromotionExtensionDiscountModifierEnum, -) -from .promotion_extension_occasion import ( - PromotionExtensionOccasionEnum, -) -from .proximity_radius_units import ( - ProximityRadiusUnitsEnum, -) -from .quality_score_bucket import ( - QualityScoreBucketEnum, -) -from .reach_plan_age_range import ( - ReachPlanAgeRangeEnum, -) -from .reach_plan_conversion_rate_model import ( - ReachPlanConversionRateModelEnum, -) -from .reach_plan_network import ( - ReachPlanNetworkEnum, -) -from .reach_plan_surface import ( - ReachPlanSurfaceEnum, -) -from .recommendation_subscription_status import ( - RecommendationSubscriptionStatusEnum, -) -from .recommendation_type import ( - RecommendationTypeEnum, -) -from .resource_change_operation import ( - ResourceChangeOperationEnum, -) -from .resource_limit_type import ( - ResourceLimitTypeEnum, -) -from .response_content_type import ( - ResponseContentTypeEnum, -) -from .search_engine_results_page_type import ( - SearchEngineResultsPageTypeEnum, -) -from .search_term_match_type import ( - SearchTermMatchTypeEnum, -) -from .search_term_targeting_status import ( - SearchTermTargetingStatusEnum, -) -from .seasonality_event_scope import ( - SeasonalityEventScopeEnum, -) -from .seasonality_event_status import ( - SeasonalityEventStatusEnum, -) -from .served_asset_field_type import ( - ServedAssetFieldTypeEnum, -) -from .shared_set_status import ( - SharedSetStatusEnum, -) -from .shared_set_type import ( - SharedSetTypeEnum, -) -from .shopping_add_products_to_campaign_recommendation_enum import ( - ShoppingAddProductsToCampaignRecommendationEnum, -) -from .simulation_modification_method import ( - SimulationModificationMethodEnum, -) -from .simulation_type import ( - SimulationTypeEnum, -) -from .sk_ad_network_ad_event_type import ( - SkAdNetworkAdEventTypeEnum, -) -from .sk_ad_network_attribution_credit import ( - SkAdNetworkAttributionCreditEnum, -) -from .sk_ad_network_coarse_conversion_value import ( - SkAdNetworkCoarseConversionValueEnum, -) -from .sk_ad_network_source_type import ( - SkAdNetworkSourceTypeEnum, -) -from .sk_ad_network_user_type import ( - SkAdNetworkUserTypeEnum, -) -from .slot import ( - SlotEnum, -) -from .smart_campaign_not_eligible_reason import ( - SmartCampaignNotEligibleReasonEnum, -) -from .smart_campaign_status import ( - SmartCampaignStatusEnum, -) -from .spending_limit_type import ( - SpendingLimitTypeEnum, -) -from .summary_row_setting import ( - SummaryRowSettingEnum, -) -from .system_managed_entity_source import ( - SystemManagedResourceSourceEnum, -) -from .target_cpa_opt_in_recommendation_goal import ( - TargetCpaOptInRecommendationGoalEnum, -) -from .target_frequency_time_unit import ( - TargetFrequencyTimeUnitEnum, -) -from .target_impression_share_location import ( - TargetImpressionShareLocationEnum, -) -from .targeting_dimension import ( - TargetingDimensionEnum, -) -from .time_type import ( - TimeTypeEnum, -) -from .tracking_code_page_format import ( - TrackingCodePageFormatEnum, -) -from .tracking_code_type import ( - TrackingCodeTypeEnum, -) -from .user_identifier_source import ( - UserIdentifierSourceEnum, -) -from .user_interest_taxonomy_type import ( - UserInterestTaxonomyTypeEnum, -) -from .user_list_access_status import ( - UserListAccessStatusEnum, -) -from .user_list_closing_reason import ( - UserListClosingReasonEnum, -) -from .user_list_crm_data_source_type import ( - UserListCrmDataSourceTypeEnum, -) -from .user_list_customer_type_category import ( - UserListCustomerTypeCategoryEnum, -) -from .user_list_date_rule_item_operator import ( - UserListDateRuleItemOperatorEnum, -) -from .user_list_flexible_rule_operator import ( - UserListFlexibleRuleOperatorEnum, -) -from .user_list_logical_rule_operator import ( - UserListLogicalRuleOperatorEnum, -) -from .user_list_membership_status import ( - UserListMembershipStatusEnum, -) -from .user_list_number_rule_item_operator import ( - UserListNumberRuleItemOperatorEnum, -) -from .user_list_prepopulation_status import ( - UserListPrepopulationStatusEnum, -) -from .user_list_rule_type import ( - UserListRuleTypeEnum, -) -from .user_list_size_range import ( - UserListSizeRangeEnum, -) -from .user_list_string_rule_item_operator import ( - UserListStringRuleItemOperatorEnum, -) -from .user_list_type import ( - UserListTypeEnum, -) -from .value_rule_device_type import ( - ValueRuleDeviceTypeEnum, -) -from .value_rule_geo_location_match_type import ( - ValueRuleGeoLocationMatchTypeEnum, -) -from .value_rule_operation import ( - ValueRuleOperationEnum, -) -from .value_rule_set_attachment_type import ( - ValueRuleSetAttachmentTypeEnum, -) -from .value_rule_set_dimension import ( - ValueRuleSetDimensionEnum, -) -from .vanity_pharma_display_url_mode import ( - VanityPharmaDisplayUrlModeEnum, -) -from .vanity_pharma_text import ( - VanityPharmaTextEnum, -) -from .video_thumbnail import ( - VideoThumbnailEnum, -) -from .webpage_condition_operand import ( - WebpageConditionOperandEnum, -) -from .webpage_condition_operator import ( - WebpageConditionOperatorEnum, -) - -__all__ = ( - "AccessInvitationStatusEnum", - "AccessReasonEnum", - "AccessRoleEnum", - "AccountBudgetProposalStatusEnum", - "AccountBudgetProposalTypeEnum", - "AccountBudgetStatusEnum", - "AccountLinkStatusEnum", - "AdDestinationTypeEnum", - "AdFormatTypeEnum", - "AdGroupAdPrimaryStatusEnum", - "AdGroupAdPrimaryStatusReasonEnum", - "AdGroupAdRotationModeEnum", - "AdGroupAdStatusEnum", - "AdGroupCriterionApprovalStatusEnum", - "AdGroupCriterionPrimaryStatusEnum", - "AdGroupCriterionPrimaryStatusReasonEnum", - "AdGroupCriterionStatusEnum", - "AdGroupPrimaryStatusEnum", - "AdGroupPrimaryStatusReasonEnum", - "AdGroupStatusEnum", - "AdGroupTypeEnum", - "AdNetworkTypeEnum", - "AdServingOptimizationStatusEnum", - "AdStrengthEnum", - "AdStrengthActionItemTypeEnum", - "AdTypeEnum", - "AdvertisingChannelSubTypeEnum", - "AdvertisingChannelTypeEnum", - "AgeRangeTypeEnum", - "AndroidPrivacyInteractionTypeEnum", - "AndroidPrivacyNetworkTypeEnum", - "AppBiddingGoalEnum", - "AppCampaignAppStoreEnum", - "AppCampaignBiddingStrategyGoalTypeEnum", - "AppPaymentModelTypeEnum", - "AppUrlOperatingSystemTypeEnum", - "AssetAutomationStatusEnum", - "AssetAutomationTypeEnum", - "AssetCoverageVideoAspectRatioRequirementEnum", - "AssetFieldTypeEnum", - "AssetGroupPrimaryStatusEnum", - "AssetGroupPrimaryStatusReasonEnum", - "AssetGroupSignalApprovalStatusEnum", - "AssetGroupStatusEnum", - "AssetLinkPrimaryStatusEnum", - "AssetLinkPrimaryStatusReasonEnum", - "AssetLinkStatusEnum", - "AssetOfflineEvaluationErrorReasonsEnum", - "AssetPerformanceLabelEnum", - "AssetSetAssetStatusEnum", - "AssetSetLinkStatusEnum", - "AssetSetStatusEnum", - "AssetSetTypeEnum", - "AssetSourceEnum", - "AssetTypeEnum", - "AsyncActionStatusEnum", - "AttributionModelEnum", - "AudienceInsightsDimensionEnum", - "AudienceInsightsMarketingObjectiveEnum", - "AudienceScopeEnum", - "AudienceStatusEnum", - "BatchJobStatusEnum", - "BidModifierSourceEnum", - "BiddingSourceEnum", - "BiddingStrategyStatusEnum", - "BiddingStrategySystemStatusEnum", - "BiddingStrategyTypeEnum", - "BillingSetupStatusEnum", - "BrandRequestRejectionReasonEnum", - "BrandSafetySuitabilityEnum", - "BrandStateEnum", - "BudgetCampaignAssociationStatusEnum", - "BudgetDeliveryMethodEnum", - "BudgetPeriodEnum", - "BudgetStatusEnum", - "BudgetTypeEnum", - "BusinessMessageCallToActionTypeEnum", - "BusinessMessageProviderEnum", - "CallConversionReportingStateEnum", - "CallToActionTypeEnum", - "CallTrackingDisplayLocationEnum", - "CallTypeEnum", - "CampaignCriterionStatusEnum", - "CampaignDraftStatusEnum", - "CampaignExperimentTypeEnum", - "CampaignGroupStatusEnum", - "CampaignKeywordMatchTypeEnum", - "CampaignPrimaryStatusEnum", - "CampaignPrimaryStatusReasonEnum", - "CampaignServingStatusEnum", - "CampaignSharedSetStatusEnum", - "CampaignStatusEnum", - "ChainRelationshipTypeEnum", - "ChangeClientTypeEnum", - "ChangeEventResourceTypeEnum", - "ChangeStatusOperationEnum", - "ChangeStatusResourceTypeEnum", - "ClickTypeEnum", - "CombinedAudienceStatusEnum", - "ConsentStatusEnum", - "ContentLabelTypeEnum", - "ConversionActionCategoryEnum", - "ConversionActionCountingTypeEnum", - "ConversionActionStatusEnum", - "ConversionActionTypeEnum", - "ConversionAdjustmentTypeEnum", - "ConversionAttributionEventTypeEnum", - "ConversionCustomVariableStatusEnum", - "ConversionCustomerTypeEnum", - "ConversionEnvironmentEnum", - "ConversionLagBucketEnum", - "ConversionOrAdjustmentLagBucketEnum", - "ConversionOriginEnum", - "ConversionTrackingStatusEnum", - "ConversionValueRulePrimaryDimensionEnum", - "ConversionValueRuleSetStatusEnum", - "ConversionValueRuleStatusEnum", - "ConvertingUserPriorEngagementTypeAndLtvBucketEnum", - "CriterionCategoryChannelAvailabilityModeEnum", - "CriterionCategoryLocaleAvailabilityModeEnum", - "CriterionSystemServingStatusEnum", - "CriterionTypeEnum", - "CustomAudienceMemberTypeEnum", - "CustomAudienceStatusEnum", - "CustomAudienceTypeEnum", - "CustomConversionGoalStatusEnum", - "CustomInterestMemberTypeEnum", - "CustomInterestStatusEnum", - "CustomInterestTypeEnum", - "CustomerAcquisitionOptimizationModeEnum", - "CustomerMatchUploadKeyTypeEnum", - "CustomerPayPerConversionEligibilityFailureReasonEnum", - "CustomerStatusEnum", - "CustomizerAttributeStatusEnum", - "CustomizerAttributeTypeEnum", - "CustomizerValueStatusEnum", - "DataDrivenModelStatusEnum", - "DataLinkStatusEnum", - "DataLinkTypeEnum", - "DayOfWeekEnum", - "DemandGenChannelConfigEnum", - "DemandGenChannelStrategyEnum", - "DeviceEnum", - "DisplayAdFormatSettingEnum", - "DisplayUploadProductTypeEnum", - "DistanceBucketEnum", - "EuPoliticalAdvertisingStatusEnum", - "ExperimentMetricEnum", - "ExperimentMetricDirectionEnum", - "ExperimentStatusEnum", - "ExperimentTypeEnum", - "ExternalConversionSourceEnum", - "FixedCpmGoalEnum", - "FixedCpmTargetFrequencyTimeUnitEnum", - "FrequencyCapEventTypeEnum", - "FrequencyCapLevelEnum", - "FrequencyCapTimeUnitEnum", - "GenderTypeEnum", - "GeoTargetConstantStatusEnum", - "GeoTargetingTypeEnum", - "GoalConfigLevelEnum", - "GoogleAdsFieldCategoryEnum", - "GoogleAdsFieldDataTypeEnum", - "GoogleVoiceCallStatusEnum", - "HotelAssetSuggestionStatusEnum", - "HotelDateSelectionTypeEnum", - "HotelPriceBucketEnum", - "HotelRateTypeEnum", - "HotelReconciliationStatusEnum", - "IdentityVerificationProgramEnum", - "IdentityVerificationProgramStatusEnum", - "IncomeRangeTypeEnum", - "InsightsKnowledgeGraphEntityCapabilitiesEnum", - "InsightsTrendEnum", - "InteractionEventTypeEnum", - "InteractionTypeEnum", - "InvoiceTypeEnum", - "KeywordMatchTypeEnum", - "KeywordPlanAggregateMetricTypeEnum", - "KeywordPlanCompetitionLevelEnum", - "KeywordPlanConceptGroupTypeEnum", - "KeywordPlanForecastIntervalEnum", - "KeywordPlanKeywordAnnotationEnum", - "KeywordPlanNetworkEnum", - "LabelStatusEnum", - "LeadFormCallToActionTypeEnum", - "LeadFormDesiredIntentEnum", - "LeadFormFieldUserInputTypeEnum", - "LeadFormPostSubmitCallToActionTypeEnum", - "LegacyAppInstallAdAppStoreEnum", - "LinkedAccountTypeEnum", - "LinkedProductTypeEnum", - "ListingGroupFilterCustomAttributeIndexEnum", - "ListingGroupFilterListingSourceEnum", - "ListingGroupFilterProductCategoryLevelEnum", - "ListingGroupFilterProductChannelEnum", - "ListingGroupFilterProductConditionEnum", - "ListingGroupFilterProductTypeLevelEnum", - "ListingGroupFilterTypeEnum", - "ListingGroupTypeEnum", - "ListingTypeEnum", - "LocalServicesBusinessRegistrationCheckRejectionReasonEnum", - "LocalServicesBusinessRegistrationTypeEnum", - "LocalServicesLeadConversationTypeEnum", - "LocalServicesEmployeeStatusEnum", - "LocalServicesEmployeeTypeEnum", - "LocalServicesInsuranceRejectionReasonEnum", - "LocalServicesLeadCreditIssuanceDecisionEnum", - "LocalServicesCreditStateEnum", - "LocalServicesLeadStatusEnum", - "LocalServicesLeadSurveyAnswerEnum", - "LocalServicesLeadSurveyDissatisfiedReasonEnum", - "LocalServicesLeadSurveySatisfiedReasonEnum", - "LocalServicesLeadTypeEnum", - "LocalServicesLicenseRejectionReasonEnum", - "LocalServicesParticipantTypeEnum", - "LocalServicesVerificationArtifactStatusEnum", - "LocalServicesVerificationArtifactTypeEnum", - "LocalServicesVerificationStatusEnum", - "LocationGroupRadiusUnitsEnum", - "LocationOwnershipTypeEnum", - "LocationSourceTypeEnum", - "LocationStringFilterTypeEnum", - "LookalikeExpansionLevelEnum", - "ManagerLinkStatusEnum", - "MediaTypeEnum", - "MimeTypeEnum", - "MinuteOfHourEnum", - "MobileAppVendorEnum", - "MobileDeviceTypeEnum", - "MonthOfYearEnum", - "NegativeGeoTargetTypeEnum", - "OfflineConversionDiagnosticStatusEnum", - "OfflineEventUploadClientEnum", - "OfflineUserDataJobFailureReasonEnum", - "OfflineUserDataJobMatchRateRangeEnum", - "OfflineUserDataJobStatusEnum", - "OfflineUserDataJobTypeEnum", - "OperatingSystemVersionOperatorTypeEnum", - "OptimizationGoalTypeEnum", - "ParentalStatusTypeEnum", - "PaymentModeEnum", - "PerformanceMaxUpgradeStatusEnum", - "PlacementTypeEnum", - "PolicyApprovalStatusEnum", - "PolicyReviewStatusEnum", - "PolicyTopicEntryTypeEnum", - "PolicyTopicEvidenceDestinationMismatchUrlTypeEnum", - "PolicyTopicEvidenceDestinationNotWorkingDeviceEnum", - "PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum", - "PositiveGeoTargetTypeEnum", - "PriceExtensionPriceQualifierEnum", - "PriceExtensionPriceUnitEnum", - "PriceExtensionTypeEnum", - "ProductAvailabilityEnum", - "ProductCategoryLevelEnum", - "ProductCategoryStateEnum", - "ProductChannelEnum", - "ProductChannelExclusivityEnum", - "ProductConditionEnum", - "ProductCustomAttributeIndexEnum", - "ProductIssueSeverityEnum", - "ProductLinkInvitationStatusEnum", - "ProductStatusEnum", - "ProductTypeLevelEnum", - "PromotionExtensionDiscountModifierEnum", - "PromotionExtensionOccasionEnum", - "ProximityRadiusUnitsEnum", - "QualityScoreBucketEnum", - "ReachPlanAgeRangeEnum", - "ReachPlanConversionRateModelEnum", - "ReachPlanNetworkEnum", - "ReachPlanSurfaceEnum", - "RecommendationSubscriptionStatusEnum", - "RecommendationTypeEnum", - "ResourceChangeOperationEnum", - "ResourceLimitTypeEnum", - "ResponseContentTypeEnum", - "SearchEngineResultsPageTypeEnum", - "SearchTermMatchTypeEnum", - "SearchTermTargetingStatusEnum", - "SeasonalityEventScopeEnum", - "SeasonalityEventStatusEnum", - "ServedAssetFieldTypeEnum", - "SharedSetStatusEnum", - "SharedSetTypeEnum", - "ShoppingAddProductsToCampaignRecommendationEnum", - "SimulationModificationMethodEnum", - "SimulationTypeEnum", - "SkAdNetworkAdEventTypeEnum", - "SkAdNetworkAttributionCreditEnum", - "SkAdNetworkCoarseConversionValueEnum", - "SkAdNetworkSourceTypeEnum", - "SkAdNetworkUserTypeEnum", - "SlotEnum", - "SmartCampaignNotEligibleReasonEnum", - "SmartCampaignStatusEnum", - "SpendingLimitTypeEnum", - "SummaryRowSettingEnum", - "SystemManagedResourceSourceEnum", - "TargetCpaOptInRecommendationGoalEnum", - "TargetFrequencyTimeUnitEnum", - "TargetImpressionShareLocationEnum", - "TargetingDimensionEnum", - "TimeTypeEnum", - "TrackingCodePageFormatEnum", - "TrackingCodeTypeEnum", - "UserIdentifierSourceEnum", - "UserInterestTaxonomyTypeEnum", - "UserListAccessStatusEnum", - "UserListClosingReasonEnum", - "UserListCrmDataSourceTypeEnum", - "UserListCustomerTypeCategoryEnum", - "UserListDateRuleItemOperatorEnum", - "UserListFlexibleRuleOperatorEnum", - "UserListLogicalRuleOperatorEnum", - "UserListMembershipStatusEnum", - "UserListNumberRuleItemOperatorEnum", - "UserListPrepopulationStatusEnum", - "UserListRuleTypeEnum", - "UserListSizeRangeEnum", - "UserListStringRuleItemOperatorEnum", - "UserListTypeEnum", - "ValueRuleDeviceTypeEnum", - "ValueRuleGeoLocationMatchTypeEnum", - "ValueRuleOperationEnum", - "ValueRuleSetAttachmentTypeEnum", - "ValueRuleSetDimensionEnum", - "VanityPharmaDisplayUrlModeEnum", - "VanityPharmaTextEnum", - "VideoThumbnailEnum", - "WebpageConditionOperandEnum", - "WebpageConditionOperatorEnum", -) diff --git a/google/ads/googleads/v19/enums/types/ad_format_type.py b/google/ads/googleads/v19/enums/types/ad_format_type.py deleted file mode 100644 index b13590c84..000000000 --- a/google/ads/googleads/v19/enums/types/ad_format_type.py +++ /dev/null @@ -1,102 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - - -import proto # type: ignore - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", - manifest={ - "AdFormatTypeEnum", - }, -) - - -class AdFormatTypeEnum(proto.Message): - r"""Container for enumeration of Google Ads format types.""" - - class AdFormatType(proto.Enum): - r"""Enumerates Google Ads format types. - - Note that this segmentation is available only for Video and - Demand Gen campaigns. For assets, only video assets are - supported. - - Values: - UNSPECIFIED (0): - No value has been specified. - UNKNOWN (1): - Used for return value only. Represents value - unknown in this version. - OTHER (2): - Value assigned to formats (such as - experimental formats) which don't support format - segmentation in Video and Demand Gen campaigns. - - Note that these formats may change categories in - the future, for example if an experimental - format is exposed or a new format is added. We - strongly recommend to not rely on this field for - long term decisions. - UNSEGMENTED (3): - Value assigned for Video TrueView for Action - campaigns statistics. - Note that statistics with this value may change - categories in the future, for example if format - segmentation support is added for new campaign - types. We strongly recommend to not rely on this - field for long term decisions. - INSTREAM_SKIPPABLE (4): - Skippable in-stream ads. - INSTREAM_NON_SKIPPABLE (5): - Non-skippable in-stream ads. - INFEED (6): - In-feed YouTube or image ads served on feed - surfaces (e.g. Discover Feed, YouTube Home, - etc.). - BUMPER (7): - Short (<7 secs) in-stream non-skippable - YouTube ads. - OUTSTREAM (8): - Outstream ads. - MASTHEAD (9): - Masthead ads. - AUDIO (10): - Audio ads. - SHORTS (11): - Vertical full-screen video or image ads - served on YouTube Shorts or BrandConnect ads - served as organic YouTube Shorts. - """ - - UNSPECIFIED = 0 - UNKNOWN = 1 - OTHER = 2 - UNSEGMENTED = 3 - INSTREAM_SKIPPABLE = 4 - INSTREAM_NON_SKIPPABLE = 5 - INFEED = 6 - BUMPER = 7 - OUTSTREAM = 8 - MASTHEAD = 9 - AUDIO = 10 - SHORTS = 11 - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/ad_network_type.py b/google/ads/googleads/v19/enums/types/ad_network_type.py deleted file mode 100644 index 070b38487..000000000 --- a/google/ads/googleads/v19/enums/types/ad_network_type.py +++ /dev/null @@ -1,71 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - - -import proto # type: ignore - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", - manifest={ - "AdNetworkTypeEnum", - }, -) - - -class AdNetworkTypeEnum(proto.Message): - r"""Container for enumeration of Google Ads network types.""" - - class AdNetworkType(proto.Enum): - r"""Enumerates Google Ads network types. - - Values: - UNSPECIFIED (0): - Not specified. - UNKNOWN (1): - The value is unknown in this version. - SEARCH (2): - Google search. - SEARCH_PARTNERS (3): - Search partners. - CONTENT (4): - Display Network. - MIXED (7): - Cross-network. - YOUTUBE (8): - YouTube - GOOGLE_TV (9): - Google TV - GOOGLE_OWNED_CHANNELS (10): - Google Owned Channels such as Discover feed, - Gmail, YouTube. This network is only used by - Demand Gen campaigns. - """ - - UNSPECIFIED = 0 - UNKNOWN = 1 - SEARCH = 2 - SEARCH_PARTNERS = 3 - CONTENT = 4 - MIXED = 7 - YOUTUBE = 8 - GOOGLE_TV = 9 - GOOGLE_OWNED_CHANNELS = 10 - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/asset_automation_type.py b/google/ads/googleads/v19/enums/types/asset_automation_type.py deleted file mode 100644 index 689e1a383..000000000 --- a/google/ads/googleads/v19/enums/types/asset_automation_type.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - - -import proto # type: ignore - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", - manifest={ - "AssetAutomationTypeEnum", - }, -) - - -class AssetAutomationTypeEnum(proto.Message): - r"""Container for enum describing the type of asset automation.""" - - class AssetAutomationType(proto.Enum): - r"""The type of asset automation. - - Values: - UNSPECIFIED (0): - Not specified. - UNKNOWN (1): - Used as a return value only. Represents value - unknown in this version. - TEXT_ASSET_AUTOMATION (2): - Text asset automation includes headlines and - descriptions. By default, advertisers are - opted-in for Performance Max and opted-out for - Search. - GENERATE_VERTICAL_YOUTUBE_VIDEOS (3): - Converts horizontal video assets to vertical - orientation using content-aware technology. By - default, advertisers are opted in for - DemandGenVideoResponsiveAd. - GENERATE_SHORTER_YOUTUBE_VIDEOS (4): - Shortens video assets to better capture user - attention using content-aware technology. By - default, advertisers are opted in for - DemandGenVideoResponsiveAd. - GENERATE_LANDING_PAGE_PREVIEW (5): - Generates a preview of the landing page shown - in the engagement panel. - By using this feature, you confirm that you own - all legal rights to the images on the landing - page used by this account (or you have - permission to share the images with Google). You - hereby instruct Google to publish these images - on your behalf for advertising or other - commercial purposes. - GENERATE_ENHANCED_YOUTUBE_VIDEOS (6): - Generates video enhancements (vertical and - shorter videos) for PMax campaigns. Opted in by - default. - """ - - UNSPECIFIED = 0 - UNKNOWN = 1 - TEXT_ASSET_AUTOMATION = 2 - GENERATE_VERTICAL_YOUTUBE_VIDEOS = 3 - GENERATE_SHORTER_YOUTUBE_VIDEOS = 4 - GENERATE_LANDING_PAGE_PREVIEW = 5 - GENERATE_ENHANCED_YOUTUBE_VIDEOS = 6 - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/__init__.py b/google/ads/googleads/v19/errors/__init__.py deleted file mode 100644 index 9fb044b8b..000000000 --- a/google/ads/googleads/v19/errors/__init__.py +++ /dev/null @@ -1,395 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.ads.googleads.v19 import gapic_version as package_version - -__version__ = package_version.__version__ - - -from .types.access_invitation_error import AccessInvitationErrorEnum -from .types.account_budget_proposal_error import AccountBudgetProposalErrorEnum -from .types.account_link_error import AccountLinkErrorEnum -from .types.ad_customizer_error import AdCustomizerErrorEnum -from .types.ad_error import AdErrorEnum -from .types.ad_group_ad_error import AdGroupAdErrorEnum -from .types.ad_group_bid_modifier_error import AdGroupBidModifierErrorEnum -from .types.ad_group_criterion_customizer_error import ( - AdGroupCriterionCustomizerErrorEnum, -) -from .types.ad_group_criterion_error import AdGroupCriterionErrorEnum -from .types.ad_group_customizer_error import AdGroupCustomizerErrorEnum -from .types.ad_group_error import AdGroupErrorEnum -from .types.ad_group_feed_error import AdGroupFeedErrorEnum -from .types.ad_parameter_error import AdParameterErrorEnum -from .types.ad_sharing_error import AdSharingErrorEnum -from .types.adx_error import AdxErrorEnum -from .types.asset_error import AssetErrorEnum -from .types.asset_group_asset_error import AssetGroupAssetErrorEnum -from .types.asset_group_error import AssetGroupErrorEnum -from .types.asset_group_listing_group_filter_error import ( - AssetGroupListingGroupFilterErrorEnum, -) -from .types.asset_group_signal_error import AssetGroupSignalErrorEnum -from .types.asset_link_error import AssetLinkErrorEnum -from .types.asset_set_asset_error import AssetSetAssetErrorEnum -from .types.asset_set_error import AssetSetErrorEnum -from .types.asset_set_link_error import AssetSetLinkErrorEnum -from .types.audience_error import AudienceErrorEnum -from .types.audience_insights_error import AudienceInsightsErrorEnum -from .types.authentication_error import AuthenticationErrorEnum -from .types.authorization_error import AuthorizationErrorEnum -from .types.automatically_created_asset_removal_error import ( - AutomaticallyCreatedAssetRemovalErrorEnum, -) -from .types.batch_job_error import BatchJobErrorEnum -from .types.bidding_error import BiddingErrorEnum -from .types.bidding_strategy_error import BiddingStrategyErrorEnum -from .types.billing_setup_error import BillingSetupErrorEnum -from .types.brand_guidelines_migration_error import ( - BrandGuidelinesMigrationErrorEnum, -) -from .types.campaign_budget_error import CampaignBudgetErrorEnum -from .types.campaign_conversion_goal_error import ( - CampaignConversionGoalErrorEnum, -) -from .types.campaign_criterion_error import CampaignCriterionErrorEnum -from .types.campaign_customizer_error import CampaignCustomizerErrorEnum -from .types.campaign_draft_error import CampaignDraftErrorEnum -from .types.campaign_error import CampaignErrorEnum -from .types.campaign_experiment_error import CampaignExperimentErrorEnum -from .types.campaign_feed_error import CampaignFeedErrorEnum -from .types.campaign_lifecycle_goal_error import CampaignLifecycleGoalErrorEnum -from .types.campaign_shared_set_error import CampaignSharedSetErrorEnum -from .types.change_event_error import ChangeEventErrorEnum -from .types.change_status_error import ChangeStatusErrorEnum -from .types.collection_size_error import CollectionSizeErrorEnum -from .types.context_error import ContextErrorEnum -from .types.conversion_action_error import ConversionActionErrorEnum -from .types.conversion_adjustment_upload_error import ( - ConversionAdjustmentUploadErrorEnum, -) -from .types.conversion_custom_variable_error import ( - ConversionCustomVariableErrorEnum, -) -from .types.conversion_goal_campaign_config_error import ( - ConversionGoalCampaignConfigErrorEnum, -) -from .types.conversion_upload_error import ConversionUploadErrorEnum -from .types.conversion_value_rule_error import ConversionValueRuleErrorEnum -from .types.conversion_value_rule_set_error import ( - ConversionValueRuleSetErrorEnum, -) -from .types.country_code_error import CountryCodeErrorEnum -from .types.criterion_error import CriterionErrorEnum -from .types.currency_code_error import CurrencyCodeErrorEnum -from .types.currency_error import CurrencyErrorEnum -from .types.custom_audience_error import CustomAudienceErrorEnum -from .types.custom_conversion_goal_error import CustomConversionGoalErrorEnum -from .types.custom_interest_error import CustomInterestErrorEnum -from .types.customer_client_link_error import CustomerClientLinkErrorEnum -from .types.customer_customizer_error import CustomerCustomizerErrorEnum -from .types.customer_error import CustomerErrorEnum -from .types.customer_feed_error import CustomerFeedErrorEnum -from .types.customer_lifecycle_goal_error import CustomerLifecycleGoalErrorEnum -from .types.customer_manager_link_error import CustomerManagerLinkErrorEnum -from .types.customer_sk_ad_network_conversion_value_schema_error import ( - CustomerSkAdNetworkConversionValueSchemaErrorEnum, -) -from .types.customer_user_access_error import CustomerUserAccessErrorEnum -from .types.customizer_attribute_error import CustomizerAttributeErrorEnum -from .types.data_link_error import DataLinkErrorEnum -from .types.database_error import DatabaseErrorEnum -from .types.date_error import DateErrorEnum -from .types.date_range_error import DateRangeErrorEnum -from .types.distinct_error import DistinctErrorEnum -from .types.enum_error import EnumErrorEnum -from .types.errors import ErrorCode -from .types.errors import ErrorDetails -from .types.errors import ErrorLocation -from .types.errors import GoogleAdsError -from .types.errors import GoogleAdsFailure -from .types.errors import PolicyFindingDetails -from .types.errors import PolicyViolationDetails -from .types.errors import QuotaErrorDetails -from .types.errors import ResourceCountDetails -from .types.experiment_arm_error import ExperimentArmErrorEnum -from .types.experiment_error import ExperimentErrorEnum -from .types.extension_feed_item_error import ExtensionFeedItemErrorEnum -from .types.extension_setting_error import ExtensionSettingErrorEnum -from .types.feed_attribute_reference_error import ( - FeedAttributeReferenceErrorEnum, -) -from .types.feed_error import FeedErrorEnum -from .types.feed_item_error import FeedItemErrorEnum -from .types.feed_item_set_error import FeedItemSetErrorEnum -from .types.feed_item_set_link_error import FeedItemSetLinkErrorEnum -from .types.feed_item_target_error import FeedItemTargetErrorEnum -from .types.feed_item_validation_error import FeedItemValidationErrorEnum -from .types.feed_mapping_error import FeedMappingErrorEnum -from .types.field_error import FieldErrorEnum -from .types.field_mask_error import FieldMaskErrorEnum -from .types.function_error import FunctionErrorEnum -from .types.function_parsing_error import FunctionParsingErrorEnum -from .types.geo_target_constant_suggestion_error import ( - GeoTargetConstantSuggestionErrorEnum, -) -from .types.header_error import HeaderErrorEnum -from .types.id_error import IdErrorEnum -from .types.identity_verification_error import IdentityVerificationErrorEnum -from .types.image_error import ImageErrorEnum -from .types.internal_error import InternalErrorEnum -from .types.invoice_error import InvoiceErrorEnum -from .types.keyword_plan_ad_group_error import KeywordPlanAdGroupErrorEnum -from .types.keyword_plan_ad_group_keyword_error import ( - KeywordPlanAdGroupKeywordErrorEnum, -) -from .types.keyword_plan_campaign_error import KeywordPlanCampaignErrorEnum -from .types.keyword_plan_campaign_keyword_error import ( - KeywordPlanCampaignKeywordErrorEnum, -) -from .types.keyword_plan_error import KeywordPlanErrorEnum -from .types.keyword_plan_idea_error import KeywordPlanIdeaErrorEnum -from .types.label_error import LabelErrorEnum -from .types.language_code_error import LanguageCodeErrorEnum -from .types.list_operation_error import ListOperationErrorEnum -from .types.manager_link_error import ManagerLinkErrorEnum -from .types.media_bundle_error import MediaBundleErrorEnum -from .types.media_file_error import MediaFileErrorEnum -from .types.media_upload_error import MediaUploadErrorEnum -from .types.merchant_center_error import MerchantCenterErrorEnum -from .types.multiplier_error import MultiplierErrorEnum -from .types.mutate_error import MutateErrorEnum -from .types.new_resource_creation_error import NewResourceCreationErrorEnum -from .types.not_allowlisted_error import NotAllowlistedErrorEnum -from .types.not_empty_error import NotEmptyErrorEnum -from .types.null_error import NullErrorEnum -from .types.offline_user_data_job_error import OfflineUserDataJobErrorEnum -from .types.operation_access_denied_error import OperationAccessDeniedErrorEnum -from .types.operator_error import OperatorErrorEnum -from .types.partial_failure_error import PartialFailureErrorEnum -from .types.payments_account_error import PaymentsAccountErrorEnum -from .types.policy_finding_error import PolicyFindingErrorEnum -from .types.policy_validation_parameter_error import ( - PolicyValidationParameterErrorEnum, -) -from .types.policy_violation_error import PolicyViolationErrorEnum -from .types.product_link_error import ProductLinkErrorEnum -from .types.product_link_invitation_error import ProductLinkInvitationErrorEnum -from .types.query_error import QueryErrorEnum -from .types.quota_error import QuotaErrorEnum -from .types.range_error import RangeErrorEnum -from .types.reach_plan_error import ReachPlanErrorEnum -from .types.recommendation_error import RecommendationErrorEnum -from .types.recommendation_subscription_error import ( - RecommendationSubscriptionErrorEnum, -) -from .types.region_code_error import RegionCodeErrorEnum -from .types.request_error import RequestErrorEnum -from .types.resource_access_denied_error import ResourceAccessDeniedErrorEnum -from .types.resource_count_limit_exceeded_error import ( - ResourceCountLimitExceededErrorEnum, -) -from .types.search_term_insight_error import SearchTermInsightErrorEnum -from .types.setting_error import SettingErrorEnum -from .types.shareable_preview_error import ShareablePreviewErrorEnum -from .types.shared_criterion_error import SharedCriterionErrorEnum -from .types.shared_set_error import SharedSetErrorEnum -from .types.shopping_product_error import ShoppingProductErrorEnum -from .types.size_limit_error import SizeLimitErrorEnum -from .types.smart_campaign_error import SmartCampaignErrorEnum -from .types.string_format_error import StringFormatErrorEnum -from .types.string_length_error import StringLengthErrorEnum -from .types.third_party_app_analytics_link_error import ( - ThirdPartyAppAnalyticsLinkErrorEnum, -) -from .types.time_zone_error import TimeZoneErrorEnum -from .types.url_field_error import UrlFieldErrorEnum -from .types.user_data_error import UserDataErrorEnum -from .types.user_list_customer_type_error import UserListCustomerTypeErrorEnum -from .types.user_list_error import UserListErrorEnum -from .types.video_campaign_error import VideoCampaignErrorEnum -from .types.youtube_video_registration_error import ( - YoutubeVideoRegistrationErrorEnum, -) - -__all__ = ( - "AccessInvitationErrorEnum", - "AccountBudgetProposalErrorEnum", - "AccountLinkErrorEnum", - "AdCustomizerErrorEnum", - "AdErrorEnum", - "AdGroupAdErrorEnum", - "AdGroupBidModifierErrorEnum", - "AdGroupCriterionCustomizerErrorEnum", - "AdGroupCriterionErrorEnum", - "AdGroupCustomizerErrorEnum", - "AdGroupErrorEnum", - "AdGroupFeedErrorEnum", - "AdParameterErrorEnum", - "AdSharingErrorEnum", - "AdxErrorEnum", - "AssetErrorEnum", - "AssetGroupAssetErrorEnum", - "AssetGroupErrorEnum", - "AssetGroupListingGroupFilterErrorEnum", - "AssetGroupSignalErrorEnum", - "AssetLinkErrorEnum", - "AssetSetAssetErrorEnum", - "AssetSetErrorEnum", - "AssetSetLinkErrorEnum", - "AudienceErrorEnum", - "AudienceInsightsErrorEnum", - "AuthenticationErrorEnum", - "AuthorizationErrorEnum", - "AutomaticallyCreatedAssetRemovalErrorEnum", - "BatchJobErrorEnum", - "BiddingErrorEnum", - "BiddingStrategyErrorEnum", - "BillingSetupErrorEnum", - "BrandGuidelinesMigrationErrorEnum", - "CampaignBudgetErrorEnum", - "CampaignConversionGoalErrorEnum", - "CampaignCriterionErrorEnum", - "CampaignCustomizerErrorEnum", - "CampaignDraftErrorEnum", - "CampaignErrorEnum", - "CampaignExperimentErrorEnum", - "CampaignFeedErrorEnum", - "CampaignLifecycleGoalErrorEnum", - "CampaignSharedSetErrorEnum", - "ChangeEventErrorEnum", - "ChangeStatusErrorEnum", - "CollectionSizeErrorEnum", - "ContextErrorEnum", - "ConversionActionErrorEnum", - "ConversionAdjustmentUploadErrorEnum", - "ConversionCustomVariableErrorEnum", - "ConversionGoalCampaignConfigErrorEnum", - "ConversionUploadErrorEnum", - "ConversionValueRuleErrorEnum", - "ConversionValueRuleSetErrorEnum", - "CountryCodeErrorEnum", - "CriterionErrorEnum", - "CurrencyCodeErrorEnum", - "CurrencyErrorEnum", - "CustomAudienceErrorEnum", - "CustomConversionGoalErrorEnum", - "CustomInterestErrorEnum", - "CustomerClientLinkErrorEnum", - "CustomerCustomizerErrorEnum", - "CustomerErrorEnum", - "CustomerFeedErrorEnum", - "CustomerLifecycleGoalErrorEnum", - "CustomerManagerLinkErrorEnum", - "CustomerSkAdNetworkConversionValueSchemaErrorEnum", - "CustomerUserAccessErrorEnum", - "CustomizerAttributeErrorEnum", - "DataLinkErrorEnum", - "DatabaseErrorEnum", - "DateErrorEnum", - "DateRangeErrorEnum", - "DistinctErrorEnum", - "EnumErrorEnum", - "ErrorCode", - "ErrorDetails", - "ErrorLocation", - "ExperimentArmErrorEnum", - "ExperimentErrorEnum", - "ExtensionFeedItemErrorEnum", - "ExtensionSettingErrorEnum", - "FeedAttributeReferenceErrorEnum", - "FeedErrorEnum", - "FeedItemErrorEnum", - "FeedItemSetErrorEnum", - "FeedItemSetLinkErrorEnum", - "FeedItemTargetErrorEnum", - "FeedItemValidationErrorEnum", - "FeedMappingErrorEnum", - "FieldErrorEnum", - "FieldMaskErrorEnum", - "FunctionErrorEnum", - "FunctionParsingErrorEnum", - "GeoTargetConstantSuggestionErrorEnum", - "GoogleAdsError", - "GoogleAdsFailure", - "HeaderErrorEnum", - "IdErrorEnum", - "IdentityVerificationErrorEnum", - "ImageErrorEnum", - "InternalErrorEnum", - "InvoiceErrorEnum", - "KeywordPlanAdGroupErrorEnum", - "KeywordPlanAdGroupKeywordErrorEnum", - "KeywordPlanCampaignErrorEnum", - "KeywordPlanCampaignKeywordErrorEnum", - "KeywordPlanErrorEnum", - "KeywordPlanIdeaErrorEnum", - "LabelErrorEnum", - "LanguageCodeErrorEnum", - "ListOperationErrorEnum", - "ManagerLinkErrorEnum", - "MediaBundleErrorEnum", - "MediaFileErrorEnum", - "MediaUploadErrorEnum", - "MerchantCenterErrorEnum", - "MultiplierErrorEnum", - "MutateErrorEnum", - "NewResourceCreationErrorEnum", - "NotAllowlistedErrorEnum", - "NotEmptyErrorEnum", - "NullErrorEnum", - "OfflineUserDataJobErrorEnum", - "OperationAccessDeniedErrorEnum", - "OperatorErrorEnum", - "PartialFailureErrorEnum", - "PaymentsAccountErrorEnum", - "PolicyFindingDetails", - "PolicyFindingErrorEnum", - "PolicyValidationParameterErrorEnum", - "PolicyViolationDetails", - "PolicyViolationErrorEnum", - "ProductLinkErrorEnum", - "ProductLinkInvitationErrorEnum", - "QueryErrorEnum", - "QuotaErrorDetails", - "QuotaErrorEnum", - "RangeErrorEnum", - "ReachPlanErrorEnum", - "RecommendationErrorEnum", - "RecommendationSubscriptionErrorEnum", - "RegionCodeErrorEnum", - "RequestErrorEnum", - "ResourceAccessDeniedErrorEnum", - "ResourceCountDetails", - "ResourceCountLimitExceededErrorEnum", - "SearchTermInsightErrorEnum", - "SettingErrorEnum", - "ShareablePreviewErrorEnum", - "SharedCriterionErrorEnum", - "SharedSetErrorEnum", - "ShoppingProductErrorEnum", - "SizeLimitErrorEnum", - "SmartCampaignErrorEnum", - "StringFormatErrorEnum", - "StringLengthErrorEnum", - "ThirdPartyAppAnalyticsLinkErrorEnum", - "TimeZoneErrorEnum", - "UrlFieldErrorEnum", - "UserDataErrorEnum", - "UserListCustomerTypeErrorEnum", - "UserListErrorEnum", - "VideoCampaignErrorEnum", - "YoutubeVideoRegistrationErrorEnum", -) diff --git a/google/ads/googleads/v19/errors/types/__init__.py b/google/ads/googleads/v19/errors/types/__init__.py deleted file mode 100644 index 12e2131d3..000000000 --- a/google/ads/googleads/v19/errors/types/__init__.py +++ /dev/null @@ -1,670 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .access_invitation_error import ( - AccessInvitationErrorEnum, -) -from .account_budget_proposal_error import ( - AccountBudgetProposalErrorEnum, -) -from .account_link_error import ( - AccountLinkErrorEnum, -) -from .ad_customizer_error import ( - AdCustomizerErrorEnum, -) -from .ad_error import ( - AdErrorEnum, -) -from .ad_group_ad_error import ( - AdGroupAdErrorEnum, -) -from .ad_group_bid_modifier_error import ( - AdGroupBidModifierErrorEnum, -) -from .ad_group_criterion_customizer_error import ( - AdGroupCriterionCustomizerErrorEnum, -) -from .ad_group_criterion_error import ( - AdGroupCriterionErrorEnum, -) -from .ad_group_customizer_error import ( - AdGroupCustomizerErrorEnum, -) -from .ad_group_error import ( - AdGroupErrorEnum, -) -from .ad_group_feed_error import ( - AdGroupFeedErrorEnum, -) -from .ad_parameter_error import ( - AdParameterErrorEnum, -) -from .ad_sharing_error import ( - AdSharingErrorEnum, -) -from .adx_error import ( - AdxErrorEnum, -) -from .asset_error import ( - AssetErrorEnum, -) -from .asset_group_asset_error import ( - AssetGroupAssetErrorEnum, -) -from .asset_group_error import ( - AssetGroupErrorEnum, -) -from .asset_group_listing_group_filter_error import ( - AssetGroupListingGroupFilterErrorEnum, -) -from .asset_group_signal_error import ( - AssetGroupSignalErrorEnum, -) -from .asset_link_error import ( - AssetLinkErrorEnum, -) -from .asset_set_asset_error import ( - AssetSetAssetErrorEnum, -) -from .asset_set_error import ( - AssetSetErrorEnum, -) -from .asset_set_link_error import ( - AssetSetLinkErrorEnum, -) -from .audience_error import ( - AudienceErrorEnum, -) -from .audience_insights_error import ( - AudienceInsightsErrorEnum, -) -from .authentication_error import ( - AuthenticationErrorEnum, -) -from .authorization_error import ( - AuthorizationErrorEnum, -) -from .automatically_created_asset_removal_error import ( - AutomaticallyCreatedAssetRemovalErrorEnum, -) -from .batch_job_error import ( - BatchJobErrorEnum, -) -from .bidding_error import ( - BiddingErrorEnum, -) -from .bidding_strategy_error import ( - BiddingStrategyErrorEnum, -) -from .billing_setup_error import ( - BillingSetupErrorEnum, -) -from .brand_guidelines_migration_error import ( - BrandGuidelinesMigrationErrorEnum, -) -from .campaign_budget_error import ( - CampaignBudgetErrorEnum, -) -from .campaign_conversion_goal_error import ( - CampaignConversionGoalErrorEnum, -) -from .campaign_criterion_error import ( - CampaignCriterionErrorEnum, -) -from .campaign_customizer_error import ( - CampaignCustomizerErrorEnum, -) -from .campaign_draft_error import ( - CampaignDraftErrorEnum, -) -from .campaign_error import ( - CampaignErrorEnum, -) -from .campaign_experiment_error import ( - CampaignExperimentErrorEnum, -) -from .campaign_feed_error import ( - CampaignFeedErrorEnum, -) -from .campaign_lifecycle_goal_error import ( - CampaignLifecycleGoalErrorEnum, -) -from .campaign_shared_set_error import ( - CampaignSharedSetErrorEnum, -) -from .change_event_error import ( - ChangeEventErrorEnum, -) -from .change_status_error import ( - ChangeStatusErrorEnum, -) -from .collection_size_error import ( - CollectionSizeErrorEnum, -) -from .context_error import ( - ContextErrorEnum, -) -from .conversion_action_error import ( - ConversionActionErrorEnum, -) -from .conversion_adjustment_upload_error import ( - ConversionAdjustmentUploadErrorEnum, -) -from .conversion_custom_variable_error import ( - ConversionCustomVariableErrorEnum, -) -from .conversion_goal_campaign_config_error import ( - ConversionGoalCampaignConfigErrorEnum, -) -from .conversion_upload_error import ( - ConversionUploadErrorEnum, -) -from .conversion_value_rule_error import ( - ConversionValueRuleErrorEnum, -) -from .conversion_value_rule_set_error import ( - ConversionValueRuleSetErrorEnum, -) -from .country_code_error import ( - CountryCodeErrorEnum, -) -from .criterion_error import ( - CriterionErrorEnum, -) -from .currency_code_error import ( - CurrencyCodeErrorEnum, -) -from .currency_error import ( - CurrencyErrorEnum, -) -from .custom_audience_error import ( - CustomAudienceErrorEnum, -) -from .custom_conversion_goal_error import ( - CustomConversionGoalErrorEnum, -) -from .custom_interest_error import ( - CustomInterestErrorEnum, -) -from .customer_client_link_error import ( - CustomerClientLinkErrorEnum, -) -from .customer_customizer_error import ( - CustomerCustomizerErrorEnum, -) -from .customer_error import ( - CustomerErrorEnum, -) -from .customer_feed_error import ( - CustomerFeedErrorEnum, -) -from .customer_lifecycle_goal_error import ( - CustomerLifecycleGoalErrorEnum, -) -from .customer_manager_link_error import ( - CustomerManagerLinkErrorEnum, -) -from .customer_sk_ad_network_conversion_value_schema_error import ( - CustomerSkAdNetworkConversionValueSchemaErrorEnum, -) -from .customer_user_access_error import ( - CustomerUserAccessErrorEnum, -) -from .customizer_attribute_error import ( - CustomizerAttributeErrorEnum, -) -from .data_link_error import ( - DataLinkErrorEnum, -) -from .database_error import ( - DatabaseErrorEnum, -) -from .date_error import ( - DateErrorEnum, -) -from .date_range_error import ( - DateRangeErrorEnum, -) -from .distinct_error import ( - DistinctErrorEnum, -) -from .enum_error import ( - EnumErrorEnum, -) -from .errors import ( - ErrorCode, - ErrorDetails, - ErrorLocation, - GoogleAdsError, - GoogleAdsFailure, - PolicyFindingDetails, - PolicyViolationDetails, - QuotaErrorDetails, - ResourceCountDetails, -) -from .experiment_arm_error import ( - ExperimentArmErrorEnum, -) -from .experiment_error import ( - ExperimentErrorEnum, -) -from .extension_feed_item_error import ( - ExtensionFeedItemErrorEnum, -) -from .extension_setting_error import ( - ExtensionSettingErrorEnum, -) -from .feed_attribute_reference_error import ( - FeedAttributeReferenceErrorEnum, -) -from .feed_error import ( - FeedErrorEnum, -) -from .feed_item_error import ( - FeedItemErrorEnum, -) -from .feed_item_set_error import ( - FeedItemSetErrorEnum, -) -from .feed_item_set_link_error import ( - FeedItemSetLinkErrorEnum, -) -from .feed_item_target_error import ( - FeedItemTargetErrorEnum, -) -from .feed_item_validation_error import ( - FeedItemValidationErrorEnum, -) -from .feed_mapping_error import ( - FeedMappingErrorEnum, -) -from .field_error import ( - FieldErrorEnum, -) -from .field_mask_error import ( - FieldMaskErrorEnum, -) -from .function_error import ( - FunctionErrorEnum, -) -from .function_parsing_error import ( - FunctionParsingErrorEnum, -) -from .geo_target_constant_suggestion_error import ( - GeoTargetConstantSuggestionErrorEnum, -) -from .header_error import ( - HeaderErrorEnum, -) -from .id_error import ( - IdErrorEnum, -) -from .identity_verification_error import ( - IdentityVerificationErrorEnum, -) -from .image_error import ( - ImageErrorEnum, -) -from .internal_error import ( - InternalErrorEnum, -) -from .invoice_error import ( - InvoiceErrorEnum, -) -from .keyword_plan_ad_group_error import ( - KeywordPlanAdGroupErrorEnum, -) -from .keyword_plan_ad_group_keyword_error import ( - KeywordPlanAdGroupKeywordErrorEnum, -) -from .keyword_plan_campaign_error import ( - KeywordPlanCampaignErrorEnum, -) -from .keyword_plan_campaign_keyword_error import ( - KeywordPlanCampaignKeywordErrorEnum, -) -from .keyword_plan_error import ( - KeywordPlanErrorEnum, -) -from .keyword_plan_idea_error import ( - KeywordPlanIdeaErrorEnum, -) -from .label_error import ( - LabelErrorEnum, -) -from .language_code_error import ( - LanguageCodeErrorEnum, -) -from .list_operation_error import ( - ListOperationErrorEnum, -) -from .manager_link_error import ( - ManagerLinkErrorEnum, -) -from .media_bundle_error import ( - MediaBundleErrorEnum, -) -from .media_file_error import ( - MediaFileErrorEnum, -) -from .media_upload_error import ( - MediaUploadErrorEnum, -) -from .merchant_center_error import ( - MerchantCenterErrorEnum, -) -from .multiplier_error import ( - MultiplierErrorEnum, -) -from .mutate_error import ( - MutateErrorEnum, -) -from .new_resource_creation_error import ( - NewResourceCreationErrorEnum, -) -from .not_allowlisted_error import ( - NotAllowlistedErrorEnum, -) -from .not_empty_error import ( - NotEmptyErrorEnum, -) -from .null_error import ( - NullErrorEnum, -) -from .offline_user_data_job_error import ( - OfflineUserDataJobErrorEnum, -) -from .operation_access_denied_error import ( - OperationAccessDeniedErrorEnum, -) -from .operator_error import ( - OperatorErrorEnum, -) -from .partial_failure_error import ( - PartialFailureErrorEnum, -) -from .payments_account_error import ( - PaymentsAccountErrorEnum, -) -from .policy_finding_error import ( - PolicyFindingErrorEnum, -) -from .policy_validation_parameter_error import ( - PolicyValidationParameterErrorEnum, -) -from .policy_violation_error import ( - PolicyViolationErrorEnum, -) -from .product_link_error import ( - ProductLinkErrorEnum, -) -from .product_link_invitation_error import ( - ProductLinkInvitationErrorEnum, -) -from .query_error import ( - QueryErrorEnum, -) -from .quota_error import ( - QuotaErrorEnum, -) -from .range_error import ( - RangeErrorEnum, -) -from .reach_plan_error import ( - ReachPlanErrorEnum, -) -from .recommendation_error import ( - RecommendationErrorEnum, -) -from .recommendation_subscription_error import ( - RecommendationSubscriptionErrorEnum, -) -from .region_code_error import ( - RegionCodeErrorEnum, -) -from .request_error import ( - RequestErrorEnum, -) -from .resource_access_denied_error import ( - ResourceAccessDeniedErrorEnum, -) -from .resource_count_limit_exceeded_error import ( - ResourceCountLimitExceededErrorEnum, -) -from .search_term_insight_error import ( - SearchTermInsightErrorEnum, -) -from .setting_error import ( - SettingErrorEnum, -) -from .shareable_preview_error import ( - ShareablePreviewErrorEnum, -) -from .shared_criterion_error import ( - SharedCriterionErrorEnum, -) -from .shared_set_error import ( - SharedSetErrorEnum, -) -from .shopping_product_error import ( - ShoppingProductErrorEnum, -) -from .size_limit_error import ( - SizeLimitErrorEnum, -) -from .smart_campaign_error import ( - SmartCampaignErrorEnum, -) -from .string_format_error import ( - StringFormatErrorEnum, -) -from .string_length_error import ( - StringLengthErrorEnum, -) -from .third_party_app_analytics_link_error import ( - ThirdPartyAppAnalyticsLinkErrorEnum, -) -from .time_zone_error import ( - TimeZoneErrorEnum, -) -from .url_field_error import ( - UrlFieldErrorEnum, -) -from .user_data_error import ( - UserDataErrorEnum, -) -from .user_list_customer_type_error import ( - UserListCustomerTypeErrorEnum, -) -from .user_list_error import ( - UserListErrorEnum, -) -from .video_campaign_error import ( - VideoCampaignErrorEnum, -) -from .youtube_video_registration_error import ( - YoutubeVideoRegistrationErrorEnum, -) - -__all__ = ( - "AccessInvitationErrorEnum", - "AccountBudgetProposalErrorEnum", - "AccountLinkErrorEnum", - "AdCustomizerErrorEnum", - "AdErrorEnum", - "AdGroupAdErrorEnum", - "AdGroupBidModifierErrorEnum", - "AdGroupCriterionCustomizerErrorEnum", - "AdGroupCriterionErrorEnum", - "AdGroupCustomizerErrorEnum", - "AdGroupErrorEnum", - "AdGroupFeedErrorEnum", - "AdParameterErrorEnum", - "AdSharingErrorEnum", - "AdxErrorEnum", - "AssetErrorEnum", - "AssetGroupAssetErrorEnum", - "AssetGroupErrorEnum", - "AssetGroupListingGroupFilterErrorEnum", - "AssetGroupSignalErrorEnum", - "AssetLinkErrorEnum", - "AssetSetAssetErrorEnum", - "AssetSetErrorEnum", - "AssetSetLinkErrorEnum", - "AudienceErrorEnum", - "AudienceInsightsErrorEnum", - "AuthenticationErrorEnum", - "AuthorizationErrorEnum", - "AutomaticallyCreatedAssetRemovalErrorEnum", - "BatchJobErrorEnum", - "BiddingErrorEnum", - "BiddingStrategyErrorEnum", - "BillingSetupErrorEnum", - "BrandGuidelinesMigrationErrorEnum", - "CampaignBudgetErrorEnum", - "CampaignConversionGoalErrorEnum", - "CampaignCriterionErrorEnum", - "CampaignCustomizerErrorEnum", - "CampaignDraftErrorEnum", - "CampaignErrorEnum", - "CampaignExperimentErrorEnum", - "CampaignFeedErrorEnum", - "CampaignLifecycleGoalErrorEnum", - "CampaignSharedSetErrorEnum", - "ChangeEventErrorEnum", - "ChangeStatusErrorEnum", - "CollectionSizeErrorEnum", - "ContextErrorEnum", - "ConversionActionErrorEnum", - "ConversionAdjustmentUploadErrorEnum", - "ConversionCustomVariableErrorEnum", - "ConversionGoalCampaignConfigErrorEnum", - "ConversionUploadErrorEnum", - "ConversionValueRuleErrorEnum", - "ConversionValueRuleSetErrorEnum", - "CountryCodeErrorEnum", - "CriterionErrorEnum", - "CurrencyCodeErrorEnum", - "CurrencyErrorEnum", - "CustomAudienceErrorEnum", - "CustomConversionGoalErrorEnum", - "CustomInterestErrorEnum", - "CustomerClientLinkErrorEnum", - "CustomerCustomizerErrorEnum", - "CustomerErrorEnum", - "CustomerFeedErrorEnum", - "CustomerLifecycleGoalErrorEnum", - "CustomerManagerLinkErrorEnum", - "CustomerSkAdNetworkConversionValueSchemaErrorEnum", - "CustomerUserAccessErrorEnum", - "CustomizerAttributeErrorEnum", - "DataLinkErrorEnum", - "DatabaseErrorEnum", - "DateErrorEnum", - "DateRangeErrorEnum", - "DistinctErrorEnum", - "EnumErrorEnum", - "ErrorCode", - "ErrorDetails", - "ErrorLocation", - "GoogleAdsError", - "GoogleAdsFailure", - "PolicyFindingDetails", - "PolicyViolationDetails", - "QuotaErrorDetails", - "ResourceCountDetails", - "ExperimentArmErrorEnum", - "ExperimentErrorEnum", - "ExtensionFeedItemErrorEnum", - "ExtensionSettingErrorEnum", - "FeedAttributeReferenceErrorEnum", - "FeedErrorEnum", - "FeedItemErrorEnum", - "FeedItemSetErrorEnum", - "FeedItemSetLinkErrorEnum", - "FeedItemTargetErrorEnum", - "FeedItemValidationErrorEnum", - "FeedMappingErrorEnum", - "FieldErrorEnum", - "FieldMaskErrorEnum", - "FunctionErrorEnum", - "FunctionParsingErrorEnum", - "GeoTargetConstantSuggestionErrorEnum", - "HeaderErrorEnum", - "IdErrorEnum", - "IdentityVerificationErrorEnum", - "ImageErrorEnum", - "InternalErrorEnum", - "InvoiceErrorEnum", - "KeywordPlanAdGroupErrorEnum", - "KeywordPlanAdGroupKeywordErrorEnum", - "KeywordPlanCampaignErrorEnum", - "KeywordPlanCampaignKeywordErrorEnum", - "KeywordPlanErrorEnum", - "KeywordPlanIdeaErrorEnum", - "LabelErrorEnum", - "LanguageCodeErrorEnum", - "ListOperationErrorEnum", - "ManagerLinkErrorEnum", - "MediaBundleErrorEnum", - "MediaFileErrorEnum", - "MediaUploadErrorEnum", - "MerchantCenterErrorEnum", - "MultiplierErrorEnum", - "MutateErrorEnum", - "NewResourceCreationErrorEnum", - "NotAllowlistedErrorEnum", - "NotEmptyErrorEnum", - "NullErrorEnum", - "OfflineUserDataJobErrorEnum", - "OperationAccessDeniedErrorEnum", - "OperatorErrorEnum", - "PartialFailureErrorEnum", - "PaymentsAccountErrorEnum", - "PolicyFindingErrorEnum", - "PolicyValidationParameterErrorEnum", - "PolicyViolationErrorEnum", - "ProductLinkErrorEnum", - "ProductLinkInvitationErrorEnum", - "QueryErrorEnum", - "QuotaErrorEnum", - "RangeErrorEnum", - "ReachPlanErrorEnum", - "RecommendationErrorEnum", - "RecommendationSubscriptionErrorEnum", - "RegionCodeErrorEnum", - "RequestErrorEnum", - "ResourceAccessDeniedErrorEnum", - "ResourceCountLimitExceededErrorEnum", - "SearchTermInsightErrorEnum", - "SettingErrorEnum", - "ShareablePreviewErrorEnum", - "SharedCriterionErrorEnum", - "SharedSetErrorEnum", - "ShoppingProductErrorEnum", - "SizeLimitErrorEnum", - "SmartCampaignErrorEnum", - "StringFormatErrorEnum", - "StringLengthErrorEnum", - "ThirdPartyAppAnalyticsLinkErrorEnum", - "TimeZoneErrorEnum", - "UrlFieldErrorEnum", - "UserDataErrorEnum", - "UserListCustomerTypeErrorEnum", - "UserListErrorEnum", - "VideoCampaignErrorEnum", - "YoutubeVideoRegistrationErrorEnum", -) diff --git a/google/ads/googleads/v19/errors/types/ad_group_error.py b/google/ads/googleads/v19/errors/types/ad_group_error.py deleted file mode 100644 index cb2bfb3c0..000000000 --- a/google/ads/googleads/v19/errors/types/ad_group_error.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - - -import proto # type: ignore - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", - manifest={ - "AdGroupErrorEnum", - }, -) - - -class AdGroupErrorEnum(proto.Message): - r"""Container for enum describing possible ad group errors.""" - - class AdGroupError(proto.Enum): - r"""Enum describing possible ad group errors. - - Values: - UNSPECIFIED (0): - Enum unspecified. - UNKNOWN (1): - The received error code is not known in this - version. - DUPLICATE_ADGROUP_NAME (2): - AdGroup with the same name already exists for - the campaign. - INVALID_ADGROUP_NAME (3): - AdGroup name is not valid. - ADVERTISER_NOT_ON_CONTENT_NETWORK (5): - Advertiser is not allowed to target sites or - set site bids that are not on the Google Search - Network. - BID_TOO_BIG (6): - Bid amount is too big. - BID_TYPE_AND_BIDDING_STRATEGY_MISMATCH (7): - AdGroup bid does not match the campaign's - bidding strategy. - MISSING_ADGROUP_NAME (8): - AdGroup name is required for Add. - ADGROUP_LABEL_DOES_NOT_EXIST (9): - No link found between the ad group and the - label. - ADGROUP_LABEL_ALREADY_EXISTS (10): - The label has already been attached to the ad - group. - INVALID_CONTENT_BID_CRITERION_TYPE_GROUP (11): - The CriterionTypeGroup is not supported for - the content bid dimension. - AD_GROUP_TYPE_NOT_VALID_FOR_ADVERTISING_CHANNEL_TYPE (12): - The ad group type is not compatible with the - campaign channel type. - ADGROUP_TYPE_NOT_SUPPORTED_FOR_CAMPAIGN_SALES_COUNTRY (13): - The ad group type is not supported in the - country of sale of the campaign. - CANNOT_ADD_ADGROUP_OF_TYPE_DSA_TO_CAMPAIGN_WITHOUT_DSA_SETTING (14): - Ad groups of AdGroupType.SEARCH_DYNAMIC_ADS can only be - added to campaigns that have DynamicSearchAdsSetting - attached. - PROMOTED_HOTEL_AD_GROUPS_NOT_AVAILABLE_FOR_CUSTOMER (15): - Promoted hotels ad groups are only available - to customers on the allow-list. - INVALID_EXCLUDED_PARENT_ASSET_FIELD_TYPE (16): - The field type cannot be excluded because an - active ad group-asset link of this type exists. - INVALID_EXCLUDED_PARENT_ASSET_SET_TYPE (17): - The asset set type is invalid for setting the - excluded_parent_asset_set_types field. - CANNOT_ADD_AD_GROUP_FOR_CAMPAIGN_TYPE (18): - Cannot add ad groups for the campaign type. - INVALID_STATUS (19): - Invalid status for the ad group. - """ - - UNSPECIFIED = 0 - UNKNOWN = 1 - DUPLICATE_ADGROUP_NAME = 2 - INVALID_ADGROUP_NAME = 3 - ADVERTISER_NOT_ON_CONTENT_NETWORK = 5 - BID_TOO_BIG = 6 - BID_TYPE_AND_BIDDING_STRATEGY_MISMATCH = 7 - MISSING_ADGROUP_NAME = 8 - ADGROUP_LABEL_DOES_NOT_EXIST = 9 - ADGROUP_LABEL_ALREADY_EXISTS = 10 - INVALID_CONTENT_BID_CRITERION_TYPE_GROUP = 11 - AD_GROUP_TYPE_NOT_VALID_FOR_ADVERTISING_CHANNEL_TYPE = 12 - ADGROUP_TYPE_NOT_SUPPORTED_FOR_CAMPAIGN_SALES_COUNTRY = 13 - CANNOT_ADD_ADGROUP_OF_TYPE_DSA_TO_CAMPAIGN_WITHOUT_DSA_SETTING = 14 - PROMOTED_HOTEL_AD_GROUPS_NOT_AVAILABLE_FOR_CUSTOMER = 15 - INVALID_EXCLUDED_PARENT_ASSET_FIELD_TYPE = 16 - INVALID_EXCLUDED_PARENT_ASSET_SET_TYPE = 17 - CANNOT_ADD_AD_GROUP_FOR_CAMPAIGN_TYPE = 18 - INVALID_STATUS = 19 - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/quota_error.py b/google/ads/googleads/v19/errors/types/quota_error.py deleted file mode 100644 index ffe54e3c0..000000000 --- a/google/ads/googleads/v19/errors/types/quota_error.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - - -import proto # type: ignore - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", - manifest={ - "QuotaErrorEnum", - }, -) - - -class QuotaErrorEnum(proto.Message): - r"""Container for enum describing possible quota errors.""" - - class QuotaError(proto.Enum): - r"""Enum describing possible quota errors. - - Values: - UNSPECIFIED (0): - Enum unspecified. - UNKNOWN (1): - The received error code is not known in this - version. - RESOURCE_EXHAUSTED (2): - Too many requests. - ACCESS_PROHIBITED (3): - Access is prohibited. - RESOURCE_TEMPORARILY_EXHAUSTED (4): - Too many requests in a short amount of time. - EXCESSIVE_SHORT_TERM_QUERY_RESOURCE_CONSUMPTION (5): - Too many expensive requests from query - pattern over a short amount of time. - EXCESSIVE_LONG_TERM_QUERY_RESOURCE_CONSUMPTION (6): - Too many expensive requests from query - pattern over an extended duration of time. - """ - - UNSPECIFIED = 0 - UNKNOWN = 1 - RESOURCE_EXHAUSTED = 2 - ACCESS_PROHIBITED = 3 - RESOURCE_TEMPORARILY_EXHAUSTED = 4 - EXCESSIVE_SHORT_TERM_QUERY_RESOURCE_CONSUMPTION = 5 - EXCESSIVE_LONG_TERM_QUERY_RESOURCE_CONSUMPTION = 6 - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/__init__.py b/google/ads/googleads/v19/resources/__init__.py deleted file mode 100644 index bceea9ac1..000000000 --- a/google/ads/googleads/v19/resources/__init__.py +++ /dev/null @@ -1,525 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.ads.googleads.v19 import gapic_version as package_version - -__version__ = package_version.__version__ - - -from .types.accessible_bidding_strategy import AccessibleBiddingStrategy -from .types.account_budget import AccountBudget -from .types.account_budget_proposal import AccountBudgetProposal -from .types.account_link import AccountLink -from .types.account_link import ThirdPartyAppAnalyticsLinkIdentifier -from .types.ad import Ad -from .types.ad_group import AdGroup -from .types.ad_group_ad import AdGroupAd -from .types.ad_group_ad import AdGroupAdAssetAutomationSetting -from .types.ad_group_ad import AdGroupAdPolicySummary -from .types.ad_group_ad_asset_combination_view import ( - AdGroupAdAssetCombinationView, -) -from .types.ad_group_ad_asset_view import AdGroupAdAssetPolicySummary -from .types.ad_group_ad_asset_view import AdGroupAdAssetView -from .types.ad_group_ad_label import AdGroupAdLabel -from .types.ad_group_asset import AdGroupAsset -from .types.ad_group_asset_set import AdGroupAssetSet -from .types.ad_group_audience_view import AdGroupAudienceView -from .types.ad_group_bid_modifier import AdGroupBidModifier -from .types.ad_group_criterion import AdGroupCriterion -from .types.ad_group_criterion_customizer import AdGroupCriterionCustomizer -from .types.ad_group_criterion_label import AdGroupCriterionLabel -from .types.ad_group_criterion_simulation import AdGroupCriterionSimulation -from .types.ad_group_customizer import AdGroupCustomizer -from .types.ad_group_label import AdGroupLabel -from .types.ad_group_simulation import AdGroupSimulation -from .types.ad_parameter import AdParameter -from .types.ad_schedule_view import AdScheduleView -from .types.age_range_view import AgeRangeView -from .types.android_privacy_shared_key_google_ad_group import ( - AndroidPrivacySharedKeyGoogleAdGroup, -) -from .types.android_privacy_shared_key_google_campaign import ( - AndroidPrivacySharedKeyGoogleCampaign, -) -from .types.android_privacy_shared_key_google_network_type import ( - AndroidPrivacySharedKeyGoogleNetworkType, -) -from .types.asset import Asset -from .types.asset import AssetFieldTypePolicySummary -from .types.asset import AssetPolicySummary -from .types.asset_field_type_view import AssetFieldTypeView -from .types.asset_group import AdStrengthActionItem -from .types.asset_group import AssetCoverage -from .types.asset_group import AssetGroup -from .types.asset_group_asset import AssetGroupAsset -from .types.asset_group_listing_group_filter import AssetGroupListingGroupFilter -from .types.asset_group_listing_group_filter import ListingGroupFilterDimension -from .types.asset_group_listing_group_filter import ( - ListingGroupFilterDimensionPath, -) -from .types.asset_group_product_group_view import AssetGroupProductGroupView -from .types.asset_group_signal import AssetGroupSignal -from .types.asset_group_top_combination_view import ( - AssetGroupAssetCombinationData, -) -from .types.asset_group_top_combination_view import AssetGroupTopCombinationView -from .types.asset_set import AssetSet -from .types.asset_set_asset import AssetSetAsset -from .types.asset_set_type_view import AssetSetTypeView -from .types.audience import Audience -from .types.batch_job import BatchJob -from .types.bidding_data_exclusion import BiddingDataExclusion -from .types.bidding_seasonality_adjustment import BiddingSeasonalityAdjustment -from .types.bidding_strategy import BiddingStrategy -from .types.bidding_strategy_simulation import BiddingStrategySimulation -from .types.billing_setup import BillingSetup -from .types.call_view import CallView -from .types.campaign import Campaign -from .types.campaign_aggregate_asset_view import CampaignAggregateAssetView -from .types.campaign_asset import CampaignAsset -from .types.campaign_asset_set import CampaignAssetSet -from .types.campaign_audience_view import CampaignAudienceView -from .types.campaign_bid_modifier import CampaignBidModifier -from .types.campaign_budget import CampaignBudget -from .types.campaign_conversion_goal import CampaignConversionGoal -from .types.campaign_criterion import CampaignCriterion -from .types.campaign_customizer import CampaignCustomizer -from .types.campaign_draft import CampaignDraft -from .types.campaign_group import CampaignGroup -from .types.campaign_label import CampaignLabel -from .types.campaign_lifecycle_goal import CampaignLifecycleGoal -from .types.campaign_lifecycle_goal import CustomerAcquisitionGoalSettings -from .types.campaign_search_term_insight import CampaignSearchTermInsight -from .types.campaign_shared_set import CampaignSharedSet -from .types.campaign_simulation import CampaignSimulation -from .types.carrier_constant import CarrierConstant -from .types.change_event import ChangeEvent -from .types.change_status import ChangeStatus -from .types.channel_aggregate_asset_view import ChannelAggregateAssetView -from .types.click_view import ClickView -from .types.combined_audience import CombinedAudience -from .types.content_criterion_view import ContentCriterionView -from .types.conversion_action import ConversionAction -from .types.conversion_custom_variable import ConversionCustomVariable -from .types.conversion_goal_campaign_config import ConversionGoalCampaignConfig -from .types.conversion_value_rule import ConversionValueRule -from .types.conversion_value_rule_set import ConversionValueRuleSet -from .types.currency_constant import CurrencyConstant -from .types.custom_audience import CustomAudience -from .types.custom_audience import CustomAudienceMember -from .types.custom_conversion_goal import CustomConversionGoal -from .types.custom_interest import CustomInterest -from .types.custom_interest import CustomInterestMember -from .types.customer import CallReportingSetting -from .types.customer import ConversionTrackingSetting -from .types.customer import Customer -from .types.customer import CustomerAgreementSetting -from .types.customer import GranularInsuranceStatus -from .types.customer import GranularLicenseStatus -from .types.customer import LocalServicesSettings -from .types.customer import RemarketingSetting -from .types.customer_asset import CustomerAsset -from .types.customer_asset_set import CustomerAssetSet -from .types.customer_client import CustomerClient -from .types.customer_client_link import CustomerClientLink -from .types.customer_conversion_goal import CustomerConversionGoal -from .types.customer_customizer import CustomerCustomizer -from .types.customer_label import CustomerLabel -from .types.customer_lifecycle_goal import CustomerLifecycleGoal -from .types.customer_manager_link import CustomerManagerLink -from .types.customer_negative_criterion import CustomerNegativeCriterion -from .types.customer_search_term_insight import CustomerSearchTermInsight -from .types.customer_sk_ad_network_conversion_value_schema import ( - CustomerSkAdNetworkConversionValueSchema, -) -from .types.customer_user_access import CustomerUserAccess -from .types.customer_user_access_invitation import CustomerUserAccessInvitation -from .types.customizer_attribute import CustomizerAttribute -from .types.data_link import DataLink -from .types.data_link import YoutubeVideoIdentifier -from .types.detail_placement_view import DetailPlacementView -from .types.detailed_demographic import DetailedDemographic -from .types.display_keyword_view import DisplayKeywordView -from .types.distance_view import DistanceView -from .types.domain_category import DomainCategory -from .types.dynamic_search_ads_search_term_view import ( - DynamicSearchAdsSearchTermView, -) -from .types.expanded_landing_page_view import ExpandedLandingPageView -from .types.experiment import Experiment -from .types.experiment_arm import ExperimentArm -from .types.gender_view import GenderView -from .types.geo_target_constant import GeoTargetConstant -from .types.geographic_view import GeographicView -from .types.google_ads_field import GoogleAdsField -from .types.group_placement_view import GroupPlacementView -from .types.hotel_group_view import HotelGroupView -from .types.hotel_performance_view import HotelPerformanceView -from .types.hotel_reconciliation import HotelReconciliation -from .types.income_range_view import IncomeRangeView -from .types.invoice import Invoice -from .types.keyword_plan import KeywordPlan -from .types.keyword_plan import KeywordPlanForecastPeriod -from .types.keyword_plan_ad_group import KeywordPlanAdGroup -from .types.keyword_plan_ad_group_keyword import KeywordPlanAdGroupKeyword -from .types.keyword_plan_campaign import KeywordPlanCampaign -from .types.keyword_plan_campaign import KeywordPlanGeoTarget -from .types.keyword_plan_campaign_keyword import KeywordPlanCampaignKeyword -from .types.keyword_theme_constant import KeywordThemeConstant -from .types.keyword_view import KeywordView -from .types.label import Label -from .types.landing_page_view import LandingPageView -from .types.language_constant import LanguageConstant -from .types.lead_form_submission_data import CustomLeadFormSubmissionField -from .types.lead_form_submission_data import LeadFormSubmissionData -from .types.lead_form_submission_data import LeadFormSubmissionField -from .types.life_event import LifeEvent -from .types.local_services_employee import Fellowship -from .types.local_services_employee import LocalServicesEmployee -from .types.local_services_employee import Residency -from .types.local_services_employee import UniversityDegree -from .types.local_services_lead import ContactDetails -from .types.local_services_lead import CreditDetails -from .types.local_services_lead import LocalServicesLead -from .types.local_services_lead import Note -from .types.local_services_lead_conversation import ( - LocalServicesLeadConversation, -) -from .types.local_services_lead_conversation import MessageDetails -from .types.local_services_lead_conversation import PhoneCallDetails -from .types.local_services_verification_artifact import ( - BackgroundCheckVerificationArtifact, -) -from .types.local_services_verification_artifact import ( - BusinessRegistrationCheckVerificationArtifact, -) -from .types.local_services_verification_artifact import ( - BusinessRegistrationDocument, -) -from .types.local_services_verification_artifact import ( - BusinessRegistrationNumber, -) -from .types.local_services_verification_artifact import ( - InsuranceVerificationArtifact, -) -from .types.local_services_verification_artifact import ( - LicenseVerificationArtifact, -) -from .types.local_services_verification_artifact import ( - LocalServicesVerificationArtifact, -) -from .types.location_view import LocationView -from .types.managed_placement_view import ManagedPlacementView -from .types.media_file import MediaAudio -from .types.media_file import MediaBundle -from .types.media_file import MediaFile -from .types.media_file import MediaImage -from .types.media_file import MediaVideo -from .types.mobile_app_category_constant import MobileAppCategoryConstant -from .types.mobile_device_constant import MobileDeviceConstant -from .types.offline_conversion_upload_client_summary import ( - OfflineConversionAlert, -) -from .types.offline_conversion_upload_client_summary import ( - OfflineConversionError, -) -from .types.offline_conversion_upload_client_summary import ( - OfflineConversionSummary, -) -from .types.offline_conversion_upload_client_summary import ( - OfflineConversionUploadClientSummary, -) -from .types.offline_conversion_upload_conversion_action_summary import ( - OfflineConversionUploadConversionActionSummary, -) -from .types.offline_user_data_job import OfflineUserDataJob -from .types.offline_user_data_job import OfflineUserDataJobMetadata -from .types.operating_system_version_constant import ( - OperatingSystemVersionConstant, -) -from .types.paid_organic_search_term_view import PaidOrganicSearchTermView -from .types.parental_status_view import ParentalStatusView -from .types.payments_account import PaymentsAccount -from .types.per_store_view import PerStoreView -from .types.performance_max_placement_view import PerformanceMaxPlacementView -from .types.product_category_constant import ProductCategoryConstant -from .types.product_group_view import ProductGroupView -from .types.product_link import AdvertisingPartnerIdentifier -from .types.product_link import DataPartnerIdentifier -from .types.product_link import GoogleAdsIdentifier -from .types.product_link import MerchantCenterIdentifier -from .types.product_link import ProductLink -from .types.product_link_invitation import ( - AdvertisingPartnerLinkInvitationIdentifier, -) -from .types.product_link_invitation import HotelCenterLinkInvitationIdentifier -from .types.product_link_invitation import ( - MerchantCenterLinkInvitationIdentifier, -) -from .types.product_link_invitation import ProductLinkInvitation -from .types.qualifying_question import QualifyingQuestion -from .types.recommendation import Recommendation -from .types.recommendation_subscription import RecommendationSubscription -from .types.remarketing_action import RemarketingAction -from .types.search_term_view import SearchTermView -from .types.shared_criterion import SharedCriterion -from .types.shared_set import SharedSet -from .types.shopping_performance_view import ShoppingPerformanceView -from .types.shopping_product import ShoppingProduct -from .types.smart_campaign_search_term_view import SmartCampaignSearchTermView -from .types.smart_campaign_setting import SmartCampaignSetting -from .types.third_party_app_analytics_link import ThirdPartyAppAnalyticsLink -from .types.topic_constant import TopicConstant -from .types.topic_view import TopicView -from .types.travel_activity_group_view import TravelActivityGroupView -from .types.travel_activity_performance_view import ( - TravelActivityPerformanceView, -) -from .types.user_interest import UserInterest -from .types.user_list import UserList -from .types.user_list_customer_type import UserListCustomerType -from .types.user_location_view import UserLocationView -from .types.video import Video -from .types.webpage_view import WebpageView - -__all__ = ( - "AccessibleBiddingStrategy", - "AccountBudget", - "AccountBudgetProposal", - "AccountLink", - "Ad", - "AdGroup", - "AdGroupAd", - "AdGroupAdAssetAutomationSetting", - "AdGroupAdAssetCombinationView", - "AdGroupAdAssetPolicySummary", - "AdGroupAdAssetView", - "AdGroupAdLabel", - "AdGroupAdPolicySummary", - "AdGroupAsset", - "AdGroupAssetSet", - "AdGroupAudienceView", - "AdGroupBidModifier", - "AdGroupCriterion", - "AdGroupCriterionCustomizer", - "AdGroupCriterionLabel", - "AdGroupCriterionSimulation", - "AdGroupCustomizer", - "AdGroupLabel", - "AdGroupSimulation", - "AdParameter", - "AdScheduleView", - "AdStrengthActionItem", - "AdvertisingPartnerIdentifier", - "AdvertisingPartnerLinkInvitationIdentifier", - "AgeRangeView", - "AndroidPrivacySharedKeyGoogleAdGroup", - "AndroidPrivacySharedKeyGoogleCampaign", - "AndroidPrivacySharedKeyGoogleNetworkType", - "Asset", - "AssetCoverage", - "AssetFieldTypePolicySummary", - "AssetFieldTypeView", - "AssetGroup", - "AssetGroupAsset", - "AssetGroupAssetCombinationData", - "AssetGroupListingGroupFilter", - "AssetGroupProductGroupView", - "AssetGroupSignal", - "AssetGroupTopCombinationView", - "AssetPolicySummary", - "AssetSet", - "AssetSetAsset", - "AssetSetTypeView", - "Audience", - "BackgroundCheckVerificationArtifact", - "BatchJob", - "BiddingDataExclusion", - "BiddingSeasonalityAdjustment", - "BiddingStrategy", - "BiddingStrategySimulation", - "BillingSetup", - "BusinessRegistrationCheckVerificationArtifact", - "BusinessRegistrationDocument", - "BusinessRegistrationNumber", - "CallReportingSetting", - "CallView", - "Campaign", - "CampaignAggregateAssetView", - "CampaignAsset", - "CampaignAssetSet", - "CampaignAudienceView", - "CampaignBidModifier", - "CampaignBudget", - "CampaignConversionGoal", - "CampaignCriterion", - "CampaignCustomizer", - "CampaignDraft", - "CampaignGroup", - "CampaignLabel", - "CampaignLifecycleGoal", - "CampaignSearchTermInsight", - "CampaignSharedSet", - "CampaignSimulation", - "CarrierConstant", - "ChangeEvent", - "ChangeStatus", - "ChannelAggregateAssetView", - "ClickView", - "CombinedAudience", - "ContactDetails", - "ContentCriterionView", - "ConversionAction", - "ConversionCustomVariable", - "ConversionGoalCampaignConfig", - "ConversionTrackingSetting", - "ConversionValueRule", - "ConversionValueRuleSet", - "CreditDetails", - "CurrencyConstant", - "CustomAudience", - "CustomAudienceMember", - "CustomConversionGoal", - "CustomInterest", - "CustomInterestMember", - "CustomLeadFormSubmissionField", - "Customer", - "CustomerAcquisitionGoalSettings", - "CustomerAgreementSetting", - "CustomerAsset", - "CustomerAssetSet", - "CustomerClient", - "CustomerClientLink", - "CustomerConversionGoal", - "CustomerCustomizer", - "CustomerLabel", - "CustomerLifecycleGoal", - "CustomerManagerLink", - "CustomerNegativeCriterion", - "CustomerSearchTermInsight", - "CustomerSkAdNetworkConversionValueSchema", - "CustomerUserAccess", - "CustomerUserAccessInvitation", - "CustomizerAttribute", - "DataLink", - "DataPartnerIdentifier", - "DetailPlacementView", - "DetailedDemographic", - "DisplayKeywordView", - "DistanceView", - "DomainCategory", - "DynamicSearchAdsSearchTermView", - "ExpandedLandingPageView", - "Experiment", - "ExperimentArm", - "Fellowship", - "GenderView", - "GeoTargetConstant", - "GeographicView", - "GoogleAdsField", - "GoogleAdsIdentifier", - "GranularInsuranceStatus", - "GranularLicenseStatus", - "GroupPlacementView", - "HotelCenterLinkInvitationIdentifier", - "HotelGroupView", - "HotelPerformanceView", - "HotelReconciliation", - "IncomeRangeView", - "InsuranceVerificationArtifact", - "Invoice", - "KeywordPlan", - "KeywordPlanAdGroup", - "KeywordPlanAdGroupKeyword", - "KeywordPlanCampaign", - "KeywordPlanCampaignKeyword", - "KeywordPlanForecastPeriod", - "KeywordPlanGeoTarget", - "KeywordThemeConstant", - "KeywordView", - "Label", - "LandingPageView", - "LanguageConstant", - "LeadFormSubmissionData", - "LeadFormSubmissionField", - "LicenseVerificationArtifact", - "LifeEvent", - "ListingGroupFilterDimension", - "ListingGroupFilterDimensionPath", - "LocalServicesEmployee", - "LocalServicesLead", - "LocalServicesLeadConversation", - "LocalServicesSettings", - "LocalServicesVerificationArtifact", - "LocationView", - "ManagedPlacementView", - "MediaAudio", - "MediaBundle", - "MediaFile", - "MediaImage", - "MediaVideo", - "MerchantCenterIdentifier", - "MerchantCenterLinkInvitationIdentifier", - "MessageDetails", - "MobileAppCategoryConstant", - "MobileDeviceConstant", - "Note", - "OfflineConversionAlert", - "OfflineConversionError", - "OfflineConversionSummary", - "OfflineConversionUploadClientSummary", - "OfflineConversionUploadConversionActionSummary", - "OfflineUserDataJob", - "OfflineUserDataJobMetadata", - "OperatingSystemVersionConstant", - "PaidOrganicSearchTermView", - "ParentalStatusView", - "PaymentsAccount", - "PerStoreView", - "PerformanceMaxPlacementView", - "PhoneCallDetails", - "ProductCategoryConstant", - "ProductGroupView", - "ProductLink", - "ProductLinkInvitation", - "QualifyingQuestion", - "Recommendation", - "RecommendationSubscription", - "RemarketingAction", - "RemarketingSetting", - "Residency", - "SearchTermView", - "SharedCriterion", - "SharedSet", - "ShoppingPerformanceView", - "ShoppingProduct", - "SmartCampaignSearchTermView", - "SmartCampaignSetting", - "ThirdPartyAppAnalyticsLink", - "ThirdPartyAppAnalyticsLinkIdentifier", - "TopicConstant", - "TopicView", - "TravelActivityGroupView", - "TravelActivityPerformanceView", - "UniversityDegree", - "UserInterest", - "UserList", - "UserListCustomerType", - "UserLocationView", - "Video", - "WebpageView", - "YoutubeVideoIdentifier", -) diff --git a/google/ads/googleads/v19/resources/types/__init__.py b/google/ads/googleads/v19/resources/types/__init__.py deleted file mode 100644 index 72e1f3f81..000000000 --- a/google/ads/googleads/v19/resources/types/__init__.py +++ /dev/null @@ -1,812 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .accessible_bidding_strategy import ( - AccessibleBiddingStrategy, -) -from .account_budget import ( - AccountBudget, -) -from .account_budget_proposal import ( - AccountBudgetProposal, -) -from .account_link import ( - AccountLink, - ThirdPartyAppAnalyticsLinkIdentifier, -) -from .ad import ( - Ad, -) -from .ad_group import ( - AdGroup, -) -from .ad_group_ad import ( - AdGroupAd, - AdGroupAdAssetAutomationSetting, - AdGroupAdPolicySummary, -) -from .ad_group_ad_asset_combination_view import ( - AdGroupAdAssetCombinationView, -) -from .ad_group_ad_asset_view import ( - AdGroupAdAssetPolicySummary, - AdGroupAdAssetView, -) -from .ad_group_ad_label import ( - AdGroupAdLabel, -) -from .ad_group_asset import ( - AdGroupAsset, -) -from .ad_group_asset_set import ( - AdGroupAssetSet, -) -from .ad_group_audience_view import ( - AdGroupAudienceView, -) -from .ad_group_bid_modifier import ( - AdGroupBidModifier, -) -from .ad_group_criterion import ( - AdGroupCriterion, -) -from .ad_group_criterion_customizer import ( - AdGroupCriterionCustomizer, -) -from .ad_group_criterion_label import ( - AdGroupCriterionLabel, -) -from .ad_group_criterion_simulation import ( - AdGroupCriterionSimulation, -) -from .ad_group_customizer import ( - AdGroupCustomizer, -) -from .ad_group_label import ( - AdGroupLabel, -) -from .ad_group_simulation import ( - AdGroupSimulation, -) -from .ad_parameter import ( - AdParameter, -) -from .ad_schedule_view import ( - AdScheduleView, -) -from .age_range_view import ( - AgeRangeView, -) -from .android_privacy_shared_key_google_ad_group import ( - AndroidPrivacySharedKeyGoogleAdGroup, -) -from .android_privacy_shared_key_google_campaign import ( - AndroidPrivacySharedKeyGoogleCampaign, -) -from .android_privacy_shared_key_google_network_type import ( - AndroidPrivacySharedKeyGoogleNetworkType, -) -from .asset import ( - Asset, - AssetFieldTypePolicySummary, - AssetPolicySummary, -) -from .asset_field_type_view import ( - AssetFieldTypeView, -) -from .asset_group import ( - AdStrengthActionItem, - AssetCoverage, - AssetGroup, -) -from .asset_group_asset import ( - AssetGroupAsset, -) -from .asset_group_listing_group_filter import ( - AssetGroupListingGroupFilter, - ListingGroupFilterDimension, - ListingGroupFilterDimensionPath, -) -from .asset_group_product_group_view import ( - AssetGroupProductGroupView, -) -from .asset_group_signal import ( - AssetGroupSignal, -) -from .asset_group_top_combination_view import ( - AssetGroupAssetCombinationData, - AssetGroupTopCombinationView, -) -from .asset_set import ( - AssetSet, -) -from .asset_set_asset import ( - AssetSetAsset, -) -from .asset_set_type_view import ( - AssetSetTypeView, -) -from .audience import ( - Audience, -) -from .batch_job import ( - BatchJob, -) -from .bidding_data_exclusion import ( - BiddingDataExclusion, -) -from .bidding_seasonality_adjustment import ( - BiddingSeasonalityAdjustment, -) -from .bidding_strategy import ( - BiddingStrategy, -) -from .bidding_strategy_simulation import ( - BiddingStrategySimulation, -) -from .billing_setup import ( - BillingSetup, -) -from .call_view import ( - CallView, -) -from .campaign import ( - Campaign, -) -from .campaign_aggregate_asset_view import ( - CampaignAggregateAssetView, -) -from .campaign_asset import ( - CampaignAsset, -) -from .campaign_asset_set import ( - CampaignAssetSet, -) -from .campaign_audience_view import ( - CampaignAudienceView, -) -from .campaign_bid_modifier import ( - CampaignBidModifier, -) -from .campaign_budget import ( - CampaignBudget, -) -from .campaign_conversion_goal import ( - CampaignConversionGoal, -) -from .campaign_criterion import ( - CampaignCriterion, -) -from .campaign_customizer import ( - CampaignCustomizer, -) -from .campaign_draft import ( - CampaignDraft, -) -from .campaign_group import ( - CampaignGroup, -) -from .campaign_label import ( - CampaignLabel, -) -from .campaign_lifecycle_goal import ( - CampaignLifecycleGoal, - CustomerAcquisitionGoalSettings, -) -from .campaign_search_term_insight import ( - CampaignSearchTermInsight, -) -from .campaign_shared_set import ( - CampaignSharedSet, -) -from .campaign_simulation import ( - CampaignSimulation, -) -from .carrier_constant import ( - CarrierConstant, -) -from .change_event import ( - ChangeEvent, -) -from .change_status import ( - ChangeStatus, -) -from .channel_aggregate_asset_view import ( - ChannelAggregateAssetView, -) -from .click_view import ( - ClickView, -) -from .combined_audience import ( - CombinedAudience, -) -from .content_criterion_view import ( - ContentCriterionView, -) -from .conversion_action import ( - ConversionAction, -) -from .conversion_custom_variable import ( - ConversionCustomVariable, -) -from .conversion_goal_campaign_config import ( - ConversionGoalCampaignConfig, -) -from .conversion_value_rule import ( - ConversionValueRule, -) -from .conversion_value_rule_set import ( - ConversionValueRuleSet, -) -from .currency_constant import ( - CurrencyConstant, -) -from .custom_audience import ( - CustomAudience, - CustomAudienceMember, -) -from .custom_conversion_goal import ( - CustomConversionGoal, -) -from .custom_interest import ( - CustomInterest, - CustomInterestMember, -) -from .customer import ( - CallReportingSetting, - ConversionTrackingSetting, - Customer, - CustomerAgreementSetting, - GranularInsuranceStatus, - GranularLicenseStatus, - LocalServicesSettings, - RemarketingSetting, -) -from .customer_asset import ( - CustomerAsset, -) -from .customer_asset_set import ( - CustomerAssetSet, -) -from .customer_client import ( - CustomerClient, -) -from .customer_client_link import ( - CustomerClientLink, -) -from .customer_conversion_goal import ( - CustomerConversionGoal, -) -from .customer_customizer import ( - CustomerCustomizer, -) -from .customer_label import ( - CustomerLabel, -) -from .customer_lifecycle_goal import ( - CustomerLifecycleGoal, -) -from .customer_manager_link import ( - CustomerManagerLink, -) -from .customer_negative_criterion import ( - CustomerNegativeCriterion, -) -from .customer_search_term_insight import ( - CustomerSearchTermInsight, -) -from .customer_sk_ad_network_conversion_value_schema import ( - CustomerSkAdNetworkConversionValueSchema, -) -from .customer_user_access import ( - CustomerUserAccess, -) -from .customer_user_access_invitation import ( - CustomerUserAccessInvitation, -) -from .customizer_attribute import ( - CustomizerAttribute, -) -from .data_link import ( - DataLink, - YoutubeVideoIdentifier, -) -from .detail_placement_view import ( - DetailPlacementView, -) -from .detailed_demographic import ( - DetailedDemographic, -) -from .display_keyword_view import ( - DisplayKeywordView, -) -from .distance_view import ( - DistanceView, -) -from .domain_category import ( - DomainCategory, -) -from .dynamic_search_ads_search_term_view import ( - DynamicSearchAdsSearchTermView, -) -from .expanded_landing_page_view import ( - ExpandedLandingPageView, -) -from .experiment import ( - Experiment, -) -from .experiment_arm import ( - ExperimentArm, -) -from .gender_view import ( - GenderView, -) -from .geo_target_constant import ( - GeoTargetConstant, -) -from .geographic_view import ( - GeographicView, -) -from .google_ads_field import ( - GoogleAdsField, -) -from .group_placement_view import ( - GroupPlacementView, -) -from .hotel_group_view import ( - HotelGroupView, -) -from .hotel_performance_view import ( - HotelPerformanceView, -) -from .hotel_reconciliation import ( - HotelReconciliation, -) -from .income_range_view import ( - IncomeRangeView, -) -from .invoice import ( - Invoice, -) -from .keyword_plan import ( - KeywordPlan, - KeywordPlanForecastPeriod, -) -from .keyword_plan_ad_group import ( - KeywordPlanAdGroup, -) -from .keyword_plan_ad_group_keyword import ( - KeywordPlanAdGroupKeyword, -) -from .keyword_plan_campaign import ( - KeywordPlanCampaign, - KeywordPlanGeoTarget, -) -from .keyword_plan_campaign_keyword import ( - KeywordPlanCampaignKeyword, -) -from .keyword_theme_constant import ( - KeywordThemeConstant, -) -from .keyword_view import ( - KeywordView, -) -from .label import ( - Label, -) -from .landing_page_view import ( - LandingPageView, -) -from .language_constant import ( - LanguageConstant, -) -from .lead_form_submission_data import ( - CustomLeadFormSubmissionField, - LeadFormSubmissionData, - LeadFormSubmissionField, -) -from .life_event import ( - LifeEvent, -) -from .local_services_employee import ( - Fellowship, - LocalServicesEmployee, - Residency, - UniversityDegree, -) -from .local_services_lead import ( - ContactDetails, - CreditDetails, - LocalServicesLead, - Note, -) -from .local_services_lead_conversation import ( - LocalServicesLeadConversation, - MessageDetails, - PhoneCallDetails, -) -from .local_services_verification_artifact import ( - BackgroundCheckVerificationArtifact, - BusinessRegistrationCheckVerificationArtifact, - BusinessRegistrationDocument, - BusinessRegistrationNumber, - InsuranceVerificationArtifact, - LicenseVerificationArtifact, - LocalServicesVerificationArtifact, -) -from .location_view import ( - LocationView, -) -from .managed_placement_view import ( - ManagedPlacementView, -) -from .media_file import ( - MediaAudio, - MediaBundle, - MediaFile, - MediaImage, - MediaVideo, -) -from .mobile_app_category_constant import ( - MobileAppCategoryConstant, -) -from .mobile_device_constant import ( - MobileDeviceConstant, -) -from .offline_conversion_upload_client_summary import ( - OfflineConversionAlert, - OfflineConversionError, - OfflineConversionSummary, - OfflineConversionUploadClientSummary, -) -from .offline_conversion_upload_conversion_action_summary import ( - OfflineConversionUploadConversionActionSummary, -) -from .offline_user_data_job import ( - OfflineUserDataJob, - OfflineUserDataJobMetadata, -) -from .operating_system_version_constant import ( - OperatingSystemVersionConstant, -) -from .paid_organic_search_term_view import ( - PaidOrganicSearchTermView, -) -from .parental_status_view import ( - ParentalStatusView, -) -from .payments_account import ( - PaymentsAccount, -) -from .per_store_view import ( - PerStoreView, -) -from .performance_max_placement_view import ( - PerformanceMaxPlacementView, -) -from .product_category_constant import ( - ProductCategoryConstant, -) -from .product_group_view import ( - ProductGroupView, -) -from .product_link import ( - AdvertisingPartnerIdentifier, - DataPartnerIdentifier, - GoogleAdsIdentifier, - MerchantCenterIdentifier, - ProductLink, -) -from .product_link_invitation import ( - AdvertisingPartnerLinkInvitationIdentifier, - HotelCenterLinkInvitationIdentifier, - MerchantCenterLinkInvitationIdentifier, - ProductLinkInvitation, -) -from .qualifying_question import ( - QualifyingQuestion, -) -from .recommendation import ( - Recommendation, -) -from .recommendation_subscription import ( - RecommendationSubscription, -) -from .remarketing_action import ( - RemarketingAction, -) -from .search_term_view import ( - SearchTermView, -) -from .shared_criterion import ( - SharedCriterion, -) -from .shared_set import ( - SharedSet, -) -from .shopping_performance_view import ( - ShoppingPerformanceView, -) -from .shopping_product import ( - ShoppingProduct, -) -from .smart_campaign_search_term_view import ( - SmartCampaignSearchTermView, -) -from .smart_campaign_setting import ( - SmartCampaignSetting, -) -from .third_party_app_analytics_link import ( - ThirdPartyAppAnalyticsLink, -) -from .topic_constant import ( - TopicConstant, -) -from .topic_view import ( - TopicView, -) -from .travel_activity_group_view import ( - TravelActivityGroupView, -) -from .travel_activity_performance_view import ( - TravelActivityPerformanceView, -) -from .user_interest import ( - UserInterest, -) -from .user_list import ( - UserList, -) -from .user_list_customer_type import ( - UserListCustomerType, -) -from .user_location_view import ( - UserLocationView, -) -from .video import ( - Video, -) -from .webpage_view import ( - WebpageView, -) - -__all__ = ( - "AccessibleBiddingStrategy", - "AccountBudget", - "AccountBudgetProposal", - "AccountLink", - "ThirdPartyAppAnalyticsLinkIdentifier", - "Ad", - "AdGroup", - "AdGroupAd", - "AdGroupAdAssetAutomationSetting", - "AdGroupAdPolicySummary", - "AdGroupAdAssetCombinationView", - "AdGroupAdAssetPolicySummary", - "AdGroupAdAssetView", - "AdGroupAdLabel", - "AdGroupAsset", - "AdGroupAssetSet", - "AdGroupAudienceView", - "AdGroupBidModifier", - "AdGroupCriterion", - "AdGroupCriterionCustomizer", - "AdGroupCriterionLabel", - "AdGroupCriterionSimulation", - "AdGroupCustomizer", - "AdGroupLabel", - "AdGroupSimulation", - "AdParameter", - "AdScheduleView", - "AgeRangeView", - "AndroidPrivacySharedKeyGoogleAdGroup", - "AndroidPrivacySharedKeyGoogleCampaign", - "AndroidPrivacySharedKeyGoogleNetworkType", - "Asset", - "AssetFieldTypePolicySummary", - "AssetPolicySummary", - "AssetFieldTypeView", - "AdStrengthActionItem", - "AssetCoverage", - "AssetGroup", - "AssetGroupAsset", - "AssetGroupListingGroupFilter", - "ListingGroupFilterDimension", - "ListingGroupFilterDimensionPath", - "AssetGroupProductGroupView", - "AssetGroupSignal", - "AssetGroupAssetCombinationData", - "AssetGroupTopCombinationView", - "AssetSet", - "AssetSetAsset", - "AssetSetTypeView", - "Audience", - "BatchJob", - "BiddingDataExclusion", - "BiddingSeasonalityAdjustment", - "BiddingStrategy", - "BiddingStrategySimulation", - "BillingSetup", - "CallView", - "Campaign", - "CampaignAggregateAssetView", - "CampaignAsset", - "CampaignAssetSet", - "CampaignAudienceView", - "CampaignBidModifier", - "CampaignBudget", - "CampaignConversionGoal", - "CampaignCriterion", - "CampaignCustomizer", - "CampaignDraft", - "CampaignGroup", - "CampaignLabel", - "CampaignLifecycleGoal", - "CustomerAcquisitionGoalSettings", - "CampaignSearchTermInsight", - "CampaignSharedSet", - "CampaignSimulation", - "CarrierConstant", - "ChangeEvent", - "ChangeStatus", - "ChannelAggregateAssetView", - "ClickView", - "CombinedAudience", - "ContentCriterionView", - "ConversionAction", - "ConversionCustomVariable", - "ConversionGoalCampaignConfig", - "ConversionValueRule", - "ConversionValueRuleSet", - "CurrencyConstant", - "CustomAudience", - "CustomAudienceMember", - "CustomConversionGoal", - "CustomInterest", - "CustomInterestMember", - "CallReportingSetting", - "ConversionTrackingSetting", - "Customer", - "CustomerAgreementSetting", - "GranularInsuranceStatus", - "GranularLicenseStatus", - "LocalServicesSettings", - "RemarketingSetting", - "CustomerAsset", - "CustomerAssetSet", - "CustomerClient", - "CustomerClientLink", - "CustomerConversionGoal", - "CustomerCustomizer", - "CustomerLabel", - "CustomerLifecycleGoal", - "CustomerManagerLink", - "CustomerNegativeCriterion", - "CustomerSearchTermInsight", - "CustomerSkAdNetworkConversionValueSchema", - "CustomerUserAccess", - "CustomerUserAccessInvitation", - "CustomizerAttribute", - "DataLink", - "YoutubeVideoIdentifier", - "DetailPlacementView", - "DetailedDemographic", - "DisplayKeywordView", - "DistanceView", - "DomainCategory", - "DynamicSearchAdsSearchTermView", - "ExpandedLandingPageView", - "Experiment", - "ExperimentArm", - "GenderView", - "GeoTargetConstant", - "GeographicView", - "GoogleAdsField", - "GroupPlacementView", - "HotelGroupView", - "HotelPerformanceView", - "HotelReconciliation", - "IncomeRangeView", - "Invoice", - "KeywordPlan", - "KeywordPlanForecastPeriod", - "KeywordPlanAdGroup", - "KeywordPlanAdGroupKeyword", - "KeywordPlanCampaign", - "KeywordPlanGeoTarget", - "KeywordPlanCampaignKeyword", - "KeywordThemeConstant", - "KeywordView", - "Label", - "LandingPageView", - "LanguageConstant", - "CustomLeadFormSubmissionField", - "LeadFormSubmissionData", - "LeadFormSubmissionField", - "LifeEvent", - "Fellowship", - "LocalServicesEmployee", - "Residency", - "UniversityDegree", - "ContactDetails", - "CreditDetails", - "LocalServicesLead", - "Note", - "LocalServicesLeadConversation", - "MessageDetails", - "PhoneCallDetails", - "BackgroundCheckVerificationArtifact", - "BusinessRegistrationCheckVerificationArtifact", - "BusinessRegistrationDocument", - "BusinessRegistrationNumber", - "InsuranceVerificationArtifact", - "LicenseVerificationArtifact", - "LocalServicesVerificationArtifact", - "LocationView", - "ManagedPlacementView", - "MediaAudio", - "MediaBundle", - "MediaFile", - "MediaImage", - "MediaVideo", - "MobileAppCategoryConstant", - "MobileDeviceConstant", - "OfflineConversionAlert", - "OfflineConversionError", - "OfflineConversionSummary", - "OfflineConversionUploadClientSummary", - "OfflineConversionUploadConversionActionSummary", - "OfflineUserDataJob", - "OfflineUserDataJobMetadata", - "OperatingSystemVersionConstant", - "PaidOrganicSearchTermView", - "ParentalStatusView", - "PaymentsAccount", - "PerStoreView", - "PerformanceMaxPlacementView", - "ProductCategoryConstant", - "ProductGroupView", - "AdvertisingPartnerIdentifier", - "DataPartnerIdentifier", - "GoogleAdsIdentifier", - "MerchantCenterIdentifier", - "ProductLink", - "AdvertisingPartnerLinkInvitationIdentifier", - "HotelCenterLinkInvitationIdentifier", - "MerchantCenterLinkInvitationIdentifier", - "ProductLinkInvitation", - "QualifyingQuestion", - "Recommendation", - "RecommendationSubscription", - "RemarketingAction", - "SearchTermView", - "SharedCriterion", - "SharedSet", - "ShoppingPerformanceView", - "ShoppingProduct", - "SmartCampaignSearchTermView", - "SmartCampaignSetting", - "ThirdPartyAppAnalyticsLink", - "TopicConstant", - "TopicView", - "TravelActivityGroupView", - "TravelActivityPerformanceView", - "UserInterest", - "UserList", - "UserListCustomerType", - "UserLocationView", - "Video", - "WebpageView", -) diff --git a/google/ads/googleads/v19/resources/types/ad_group.py b/google/ads/googleads/v19/resources/types/ad_group.py deleted file mode 100644 index 94eb78c2c..000000000 --- a/google/ads/googleads/v19/resources/types/ad_group.py +++ /dev/null @@ -1,570 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -from typing import MutableSequence - -import proto # type: ignore - -from google.ads.googleads.v19.common.types import custom_parameter -from google.ads.googleads.v19.common.types import ( - targeting_setting as gagc_targeting_setting, -) -from google.ads.googleads.v19.enums.types import ad_group_ad_rotation_mode -from google.ads.googleads.v19.enums.types import ad_group_primary_status -from google.ads.googleads.v19.enums.types import ad_group_primary_status_reason -from google.ads.googleads.v19.enums.types import ad_group_status -from google.ads.googleads.v19.enums.types import ad_group_type -from google.ads.googleads.v19.enums.types import asset_field_type -from google.ads.googleads.v19.enums.types import asset_set_type -from google.ads.googleads.v19.enums.types import bidding_source -from google.ads.googleads.v19.enums.types import demand_gen_channel_config -from google.ads.googleads.v19.enums.types import demand_gen_channel_strategy -from google.ads.googleads.v19.enums.types import targeting_dimension - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", - manifest={ - "AdGroup", - }, -) - - -class AdGroup(proto.Message): - r"""An ad group. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - resource_name (str): - Immutable. The resource name of the ad group. Ad group - resource names have the form: - - ``customers/{customer_id}/adGroups/{ad_group_id}`` - id (int): - Output only. The ID of the ad group. - - This field is a member of `oneof`_ ``_id``. - name (str): - The name of the ad group. - - This field is required and should not be empty - when creating new ad groups. - - It must contain fewer than 255 UTF-8 full-width - characters. - - It must not contain any null (code point 0x0), - NL line feed (code point 0xA) or carriage return - (code point 0xD) characters. - - This field is a member of `oneof`_ ``_name``. - status (google.ads.googleads.v19.enums.types.AdGroupStatusEnum.AdGroupStatus): - The status of the ad group. - type_ (google.ads.googleads.v19.enums.types.AdGroupTypeEnum.AdGroupType): - Immutable. The type of the ad group. - ad_rotation_mode (google.ads.googleads.v19.enums.types.AdGroupAdRotationModeEnum.AdGroupAdRotationMode): - The ad rotation mode of the ad group. - base_ad_group (str): - Output only. For draft or experiment ad - groups, this field is the resource name of the - base ad group from which this ad group was - created. If a draft or experiment ad group does - not have a base ad group, then this field is - null. - - For base ad groups, this field equals the ad - group resource name. - - This field is read-only. - - This field is a member of `oneof`_ ``_base_ad_group``. - tracking_url_template (str): - The URL template for constructing a tracking - URL. - - This field is a member of `oneof`_ ``_tracking_url_template``. - url_custom_parameters (MutableSequence[google.ads.googleads.v19.common.types.CustomParameter]): - The list of mappings used to substitute custom parameter - tags in a ``tracking_url_template``, ``final_urls``, or - ``mobile_final_urls``. - campaign (str): - Immutable. The campaign to which the ad group - belongs. - - This field is a member of `oneof`_ ``_campaign``. - cpc_bid_micros (int): - The maximum CPC (cost-per-click) bid. - - This field is a member of `oneof`_ ``_cpc_bid_micros``. - effective_cpc_bid_micros (int): - Output only. Value will be same as that of - the CPC (cost-per-click) bid value when the - bidding strategy is one of manual cpc, enhanced - cpc, page one promoted or target outrank share, - otherwise the value will be null. - - This field is a member of `oneof`_ ``_effective_cpc_bid_micros``. - cpm_bid_micros (int): - The maximum CPM (cost-per-thousand viewable - impressions) bid. - - This field is a member of `oneof`_ ``_cpm_bid_micros``. - target_cpa_micros (int): - The target CPA (cost-per-acquisition). If the ad group's - campaign bidding strategy is TargetCpa or - MaximizeConversions (with its target_cpa field set), then - this field overrides the target CPA specified in the - campaign's bidding strategy. Otherwise, this value is - ignored. - - This field is a member of `oneof`_ ``_target_cpa_micros``. - cpv_bid_micros (int): - The CPV (cost-per-view) bid. - - This field is a member of `oneof`_ ``_cpv_bid_micros``. - target_cpm_micros (int): - Average amount in micros that the advertiser - is willing to pay for every thousand times the - ad is shown. - - This field is a member of `oneof`_ ``_target_cpm_micros``. - target_roas (float): - The target ROAS (return-on-ad-spend) override. If the ad - group's campaign bidding strategy is TargetRoas or - MaximizeConversionValue (with its target_roas field set), - then this field overrides the target ROAS specified in the - campaign's bidding strategy. Otherwise, this value is - ignored. - - This field is a member of `oneof`_ ``_target_roas``. - percent_cpc_bid_micros (int): - The percent cpc bid amount, expressed as a fraction of the - advertised price for some good or service. The valid range - for the fraction is [0,1) and the value stored here is - 1,000,000 \* [fraction]. - - This field is a member of `oneof`_ ``_percent_cpc_bid_micros``. - fixed_cpm_micros (int): - The fixed amount in micros that the - advertiser pays for every thousand impressions - of the ad. - - This field is a member of `oneof`_ ``_fixed_cpm_micros``. - target_cpv_micros (int): - Average amount in micros that the advertiser - is willing to pay for every ad view. - - This field is a member of `oneof`_ ``_target_cpv_micros``. - optimized_targeting_enabled (bool): - True if optimized targeting is enabled. - Optimized Targeting is the replacement for - Audience Expansion. - exclude_demographic_expansion (bool): - When this value is true, demographics will be excluded from - the types of targeting which are expanded when - optimized_targeting_enabled is true. When - optimized_targeting_enabled is false, this field is ignored. - Default is false. - display_custom_bid_dimension (google.ads.googleads.v19.enums.types.TargetingDimensionEnum.TargetingDimension): - Allows advertisers to specify a targeting - dimension on which to place absolute bids. This - is only applicable for campaigns that target - only the display network and not search. - final_url_suffix (str): - URL template for appending params to Final - URL. - - This field is a member of `oneof`_ ``_final_url_suffix``. - targeting_setting (google.ads.googleads.v19.common.types.TargetingSetting): - Setting for targeting related features. - audience_setting (google.ads.googleads.v19.resources.types.AdGroup.AudienceSetting): - Immutable. Setting for audience related - features. - effective_target_cpa_micros (int): - Output only. The effective target CPA - (cost-per-acquisition). This field is read-only. - - This field is a member of `oneof`_ ``_effective_target_cpa_micros``. - effective_target_cpa_source (google.ads.googleads.v19.enums.types.BiddingSourceEnum.BiddingSource): - Output only. Source of the effective target - CPA. This field is read-only. - effective_target_roas (float): - Output only. The effective target ROAS - (return-on-ad-spend). This field is read-only. - - This field is a member of `oneof`_ ``_effective_target_roas``. - effective_target_roas_source (google.ads.googleads.v19.enums.types.BiddingSourceEnum.BiddingSource): - Output only. Source of the effective target - ROAS. This field is read-only. - labels (MutableSequence[str]): - Output only. The resource names of labels - attached to this ad group. - excluded_parent_asset_field_types (MutableSequence[google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType]): - The asset field types that should be excluded - from this ad group. Asset links with these field - types will not be inherited by this ad group - from the upper levels. - excluded_parent_asset_set_types (MutableSequence[google.ads.googleads.v19.enums.types.AssetSetTypeEnum.AssetSetType]): - The asset set types that should be excluded from this ad - group. Asset set links with these types will not be - inherited by this ad group from the upper levels. Location - group types (GMB_DYNAMIC_LOCATION_GROUP, - CHAIN_DYNAMIC_LOCATION_GROUP, and STATIC_LOCATION_GROUP) are - child types of LOCATION_SYNC. Therefore, if LOCATION_SYNC is - set for this field, all location group asset sets are not - allowed to be linked to this ad group, and all Location - Extension (LE) and Affiliate Location Extensions (ALE) will - not be served under this ad group. Only LOCATION_SYNC is - currently supported. - primary_status (google.ads.googleads.v19.enums.types.AdGroupPrimaryStatusEnum.AdGroupPrimaryStatus): - Output only. Provides aggregated view into - why an ad group is not serving or not serving - optimally. - primary_status_reasons (MutableSequence[google.ads.googleads.v19.enums.types.AdGroupPrimaryStatusReasonEnum.AdGroupPrimaryStatusReason]): - Output only. Provides reasons for why an ad - group is not serving or not serving optimally. - demand_gen_ad_group_settings (google.ads.googleads.v19.resources.types.AdGroup.DemandGenAdGroupSettings): - Settings for Demand Gen ad groups. - """ - - class AudienceSetting(proto.Message): - r"""Settings for the audience targeting. - - Attributes: - use_audience_grouped (bool): - Immutable. If true, this ad group uses an - Audience resource for audience targeting. If - false, this ad group may use audience segment - criteria instead. - """ - - use_audience_grouped: bool = proto.Field( - proto.BOOL, - number=1, - ) - - class DemandGenAdGroupSettings(proto.Message): - r"""Settings for Demand Gen ad groups. - - Attributes: - channel_controls (google.ads.googleads.v19.resources.types.AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls): - Channel controls for Demand Gen ad groups. - """ - - class DemandGenChannelControls(proto.Message): - r"""Channel controls for Demand Gen ad groups. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - channel_config (google.ads.googleads.v19.enums.types.DemandGenChannelConfigEnum.DemandGenChannelConfig): - Output only. Channel configuration reflecting - which field in the oneof is populated. - channel_strategy (google.ads.googleads.v19.enums.types.DemandGenChannelStrategyEnum.DemandGenChannelStrategy): - High level channel strategy. - - This field is a member of `oneof`_ ``channel_configuration``. - selected_channels (google.ads.googleads.v19.resources.types.AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls.DemandGenSelectedChannels): - Explicitly selected channels. This field - should be set with at least one true value when - present. - - This field is a member of `oneof`_ ``channel_configuration``. - """ - - class DemandGenSelectedChannels(proto.Message): - r"""Explicitly selected channels for channel controls in Demand - Gen ad groups. - - Attributes: - youtube_in_stream (bool): - Whether to enable ads on the YouTube - In-Stream channel. - youtube_in_feed (bool): - Whether to enable ads on the YouTube In-Feed - channel. - youtube_shorts (bool): - Whether to enable ads on the YouTube Shorts - channel. - discover (bool): - Whether to enable ads on the Discover - channel. - gmail (bool): - Whether to enable ads on the Gmail channel. - display (bool): - Whether to enable ads on the Display channel. - """ - - youtube_in_stream: bool = proto.Field( - proto.BOOL, - number=1, - ) - youtube_in_feed: bool = proto.Field( - proto.BOOL, - number=2, - ) - youtube_shorts: bool = proto.Field( - proto.BOOL, - number=3, - ) - discover: bool = proto.Field( - proto.BOOL, - number=4, - ) - gmail: bool = proto.Field( - proto.BOOL, - number=5, - ) - display: bool = proto.Field( - proto.BOOL, - number=6, - ) - - channel_config: ( - demand_gen_channel_config.DemandGenChannelConfigEnum.DemandGenChannelConfig - ) = proto.Field( - proto.ENUM, - number=1, - enum=demand_gen_channel_config.DemandGenChannelConfigEnum.DemandGenChannelConfig, - ) - channel_strategy: ( - demand_gen_channel_strategy.DemandGenChannelStrategyEnum.DemandGenChannelStrategy - ) = proto.Field( - proto.ENUM, - number=2, - oneof="channel_configuration", - enum=demand_gen_channel_strategy.DemandGenChannelStrategyEnum.DemandGenChannelStrategy, - ) - selected_channels: "AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls.DemandGenSelectedChannels" = proto.Field( - proto.MESSAGE, - number=3, - oneof="channel_configuration", - message="AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls.DemandGenSelectedChannels", - ) - - channel_controls: ( - "AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls" - ) = proto.Field( - proto.MESSAGE, - number=1, - message="AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls", - ) - - resource_name: str = proto.Field( - proto.STRING, - number=1, - ) - id: int = proto.Field( - proto.INT64, - number=34, - optional=True, - ) - name: str = proto.Field( - proto.STRING, - number=35, - optional=True, - ) - status: ad_group_status.AdGroupStatusEnum.AdGroupStatus = proto.Field( - proto.ENUM, - number=5, - enum=ad_group_status.AdGroupStatusEnum.AdGroupStatus, - ) - type_: ad_group_type.AdGroupTypeEnum.AdGroupType = proto.Field( - proto.ENUM, - number=12, - enum=ad_group_type.AdGroupTypeEnum.AdGroupType, - ) - ad_rotation_mode: ( - ad_group_ad_rotation_mode.AdGroupAdRotationModeEnum.AdGroupAdRotationMode - ) = proto.Field( - proto.ENUM, - number=22, - enum=ad_group_ad_rotation_mode.AdGroupAdRotationModeEnum.AdGroupAdRotationMode, - ) - base_ad_group: str = proto.Field( - proto.STRING, - number=36, - optional=True, - ) - tracking_url_template: str = proto.Field( - proto.STRING, - number=37, - optional=True, - ) - url_custom_parameters: MutableSequence[custom_parameter.CustomParameter] = ( - proto.RepeatedField( - proto.MESSAGE, - number=6, - message=custom_parameter.CustomParameter, - ) - ) - campaign: str = proto.Field( - proto.STRING, - number=38, - optional=True, - ) - cpc_bid_micros: int = proto.Field( - proto.INT64, - number=39, - optional=True, - ) - effective_cpc_bid_micros: int = proto.Field( - proto.INT64, - number=57, - optional=True, - ) - cpm_bid_micros: int = proto.Field( - proto.INT64, - number=40, - optional=True, - ) - target_cpa_micros: int = proto.Field( - proto.INT64, - number=41, - optional=True, - ) - cpv_bid_micros: int = proto.Field( - proto.INT64, - number=42, - optional=True, - ) - target_cpm_micros: int = proto.Field( - proto.INT64, - number=43, - optional=True, - ) - target_roas: float = proto.Field( - proto.DOUBLE, - number=44, - optional=True, - ) - percent_cpc_bid_micros: int = proto.Field( - proto.INT64, - number=45, - optional=True, - ) - fixed_cpm_micros: int = proto.Field( - proto.INT64, - number=64, - optional=True, - ) - target_cpv_micros: int = proto.Field( - proto.INT64, - number=65, - optional=True, - ) - optimized_targeting_enabled: bool = proto.Field( - proto.BOOL, - number=59, - ) - exclude_demographic_expansion: bool = proto.Field( - proto.BOOL, - number=67, - ) - display_custom_bid_dimension: ( - targeting_dimension.TargetingDimensionEnum.TargetingDimension - ) = proto.Field( - proto.ENUM, - number=23, - enum=targeting_dimension.TargetingDimensionEnum.TargetingDimension, - ) - final_url_suffix: str = proto.Field( - proto.STRING, - number=46, - optional=True, - ) - targeting_setting: gagc_targeting_setting.TargetingSetting = proto.Field( - proto.MESSAGE, - number=25, - message=gagc_targeting_setting.TargetingSetting, - ) - audience_setting: AudienceSetting = proto.Field( - proto.MESSAGE, - number=56, - message=AudienceSetting, - ) - effective_target_cpa_micros: int = proto.Field( - proto.INT64, - number=47, - optional=True, - ) - effective_target_cpa_source: ( - bidding_source.BiddingSourceEnum.BiddingSource - ) = proto.Field( - proto.ENUM, - number=29, - enum=bidding_source.BiddingSourceEnum.BiddingSource, - ) - effective_target_roas: float = proto.Field( - proto.DOUBLE, - number=48, - optional=True, - ) - effective_target_roas_source: ( - bidding_source.BiddingSourceEnum.BiddingSource - ) = proto.Field( - proto.ENUM, - number=32, - enum=bidding_source.BiddingSourceEnum.BiddingSource, - ) - labels: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=49, - ) - excluded_parent_asset_field_types: MutableSequence[ - asset_field_type.AssetFieldTypeEnum.AssetFieldType - ] = proto.RepeatedField( - proto.ENUM, - number=54, - enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, - ) - excluded_parent_asset_set_types: MutableSequence[ - asset_set_type.AssetSetTypeEnum.AssetSetType - ] = proto.RepeatedField( - proto.ENUM, - number=58, - enum=asset_set_type.AssetSetTypeEnum.AssetSetType, - ) - primary_status: ( - ad_group_primary_status.AdGroupPrimaryStatusEnum.AdGroupPrimaryStatus - ) = proto.Field( - proto.ENUM, - number=62, - enum=ad_group_primary_status.AdGroupPrimaryStatusEnum.AdGroupPrimaryStatus, - ) - primary_status_reasons: MutableSequence[ - ad_group_primary_status_reason.AdGroupPrimaryStatusReasonEnum.AdGroupPrimaryStatusReason - ] = proto.RepeatedField( - proto.ENUM, - number=63, - enum=ad_group_primary_status_reason.AdGroupPrimaryStatusReasonEnum.AdGroupPrimaryStatusReason, - ) - demand_gen_ad_group_settings: DemandGenAdGroupSettings = proto.Field( - proto.MESSAGE, - number=91, - message=DemandGenAdGroupSettings, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/campaign.py b/google/ads/googleads/v19/resources/types/campaign.py deleted file mode 100644 index 73a7754ea..000000000 --- a/google/ads/googleads/v19/resources/types/campaign.py +++ /dev/null @@ -1,1640 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -from typing import MutableSequence - -import proto # type: ignore - -from google.ads.googleads.v19.common.types import bidding -from google.ads.googleads.v19.common.types import custom_parameter -from google.ads.googleads.v19.common.types import frequency_cap -from google.ads.googleads.v19.common.types import ( - real_time_bidding_setting as gagc_real_time_bidding_setting, -) -from google.ads.googleads.v19.common.types import ( - targeting_setting as gagc_targeting_setting, -) -from google.ads.googleads.v19.enums.types import ( - ad_serving_optimization_status as gage_ad_serving_optimization_status, -) -from google.ads.googleads.v19.enums.types import ( - advertising_channel_sub_type as gage_advertising_channel_sub_type, -) -from google.ads.googleads.v19.enums.types import ( - advertising_channel_type as gage_advertising_channel_type, -) -from google.ads.googleads.v19.enums.types import app_campaign_app_store -from google.ads.googleads.v19.enums.types import ( - app_campaign_bidding_strategy_goal_type, -) -from google.ads.googleads.v19.enums.types import ( - asset_automation_status as gage_asset_automation_status, -) -from google.ads.googleads.v19.enums.types import ( - asset_automation_type as gage_asset_automation_type, -) -from google.ads.googleads.v19.enums.types import asset_field_type -from google.ads.googleads.v19.enums.types import asset_set_type -from google.ads.googleads.v19.enums.types import ( - bidding_strategy_system_status as gage_bidding_strategy_system_status, -) -from google.ads.googleads.v19.enums.types import ( - bidding_strategy_type as gage_bidding_strategy_type, -) -from google.ads.googleads.v19.enums.types import brand_safety_suitability -from google.ads.googleads.v19.enums.types import campaign_experiment_type -from google.ads.googleads.v19.enums.types import campaign_keyword_match_type -from google.ads.googleads.v19.enums.types import campaign_primary_status -from google.ads.googleads.v19.enums.types import campaign_primary_status_reason -from google.ads.googleads.v19.enums.types import campaign_serving_status -from google.ads.googleads.v19.enums.types import campaign_status -from google.ads.googleads.v19.enums.types import eu_political_advertising_status -from google.ads.googleads.v19.enums.types import ( - listing_type as gage_listing_type, -) -from google.ads.googleads.v19.enums.types import ( - location_source_type as gage_location_source_type, -) -from google.ads.googleads.v19.enums.types import ( - negative_geo_target_type as gage_negative_geo_target_type, -) -from google.ads.googleads.v19.enums.types import optimization_goal_type -from google.ads.googleads.v19.enums.types import ( - payment_mode as gage_payment_mode, -) -from google.ads.googleads.v19.enums.types import performance_max_upgrade_status -from google.ads.googleads.v19.enums.types import ( - positive_geo_target_type as gage_positive_geo_target_type, -) -from google.ads.googleads.v19.enums.types import ( - vanity_pharma_display_url_mode as gage_vanity_pharma_display_url_mode, -) -from google.ads.googleads.v19.enums.types import ( - vanity_pharma_text as gage_vanity_pharma_text, -) - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", - manifest={ - "Campaign", - }, -) - - -class Campaign(proto.Message): - r"""A campaign. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - resource_name (str): - Immutable. The resource name of the campaign. Campaign - resource names have the form: - - ``customers/{customer_id}/campaigns/{campaign_id}`` - id (int): - Output only. The ID of the campaign. - - This field is a member of `oneof`_ ``_id``. - name (str): - The name of the campaign. - - This field is required and should not be empty - when creating new campaigns. - - It must not contain any null (code point 0x0), - NL line feed (code point 0xA) or carriage return - (code point 0xD) characters. - - This field is a member of `oneof`_ ``_name``. - primary_status (google.ads.googleads.v19.enums.types.CampaignPrimaryStatusEnum.CampaignPrimaryStatus): - Output only. The primary status of the - campaign. - Provides insight into why a campaign is not - serving or not serving optimally. Modification - to the campaign and its related entities might - take a while to be reflected in this status. - primary_status_reasons (MutableSequence[google.ads.googleads.v19.enums.types.CampaignPrimaryStatusReasonEnum.CampaignPrimaryStatusReason]): - Output only. The primary status reasons of - the campaign. - Provides insight into why a campaign is not - serving or not serving optimally. These reasons - are aggregated to determine an overall - CampaignPrimaryStatus. - status (google.ads.googleads.v19.enums.types.CampaignStatusEnum.CampaignStatus): - The status of the campaign. - - When a new campaign is added, the status - defaults to ENABLED. - serving_status (google.ads.googleads.v19.enums.types.CampaignServingStatusEnum.CampaignServingStatus): - Output only. The ad serving status of the - campaign. - bidding_strategy_system_status (google.ads.googleads.v19.enums.types.BiddingStrategySystemStatusEnum.BiddingStrategySystemStatus): - Output only. The system status of the - campaign's bidding strategy. - ad_serving_optimization_status (google.ads.googleads.v19.enums.types.AdServingOptimizationStatusEnum.AdServingOptimizationStatus): - The ad serving optimization status of the - campaign. - advertising_channel_type (google.ads.googleads.v19.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): - Immutable. The primary serving target for ads within the - campaign. The targeting options can be refined in - ``network_settings``. - - This field is required and should not be empty when creating - new campaigns. - - Can be set only when creating campaigns. After the campaign - is created, the field can not be changed. - advertising_channel_sub_type (google.ads.googleads.v19.enums.types.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType): - Immutable. Optional refinement to - ``advertising_channel_type``. Must be a valid sub-type of - the parent channel type. - - Can be set only when creating campaigns. After campaign is - created, the field can not be changed. - tracking_url_template (str): - The URL template for constructing a tracking - URL. - - This field is a member of `oneof`_ ``_tracking_url_template``. - url_custom_parameters (MutableSequence[google.ads.googleads.v19.common.types.CustomParameter]): - The list of mappings used to substitute custom parameter - tags in a ``tracking_url_template``, ``final_urls``, or - ``mobile_final_urls``. - local_services_campaign_settings (google.ads.googleads.v19.resources.types.Campaign.LocalServicesCampaignSettings): - The Local Services Campaign related settings. - travel_campaign_settings (google.ads.googleads.v19.resources.types.Campaign.TravelCampaignSettings): - Settings for Travel campaign. - demand_gen_campaign_settings (google.ads.googleads.v19.resources.types.Campaign.DemandGenCampaignSettings): - Settings for Demand Gen campaign. - video_campaign_settings (google.ads.googleads.v19.resources.types.Campaign.VideoCampaignSettings): - Settings for Video campaign. - pmax_campaign_settings (google.ads.googleads.v19.resources.types.Campaign.PmaxCampaignSettings): - Settings for Performance Max campaign. - real_time_bidding_setting (google.ads.googleads.v19.common.types.RealTimeBiddingSetting): - Settings for Real-Time Bidding, a feature - only available for campaigns targeting the Ad - Exchange network. - network_settings (google.ads.googleads.v19.resources.types.Campaign.NetworkSettings): - The network settings for the campaign. - hotel_setting (google.ads.googleads.v19.resources.types.Campaign.HotelSettingInfo): - Immutable. The hotel setting for the - campaign. - dynamic_search_ads_setting (google.ads.googleads.v19.resources.types.Campaign.DynamicSearchAdsSetting): - The setting for controlling Dynamic Search - Ads (DSA). - shopping_setting (google.ads.googleads.v19.resources.types.Campaign.ShoppingSetting): - The setting for controlling Shopping - campaigns. - targeting_setting (google.ads.googleads.v19.common.types.TargetingSetting): - Setting for targeting related features. - audience_setting (google.ads.googleads.v19.resources.types.Campaign.AudienceSetting): - Immutable. Setting for audience related - features. - - This field is a member of `oneof`_ ``_audience_setting``. - geo_target_type_setting (google.ads.googleads.v19.resources.types.Campaign.GeoTargetTypeSetting): - The setting for ads geotargeting. - local_campaign_setting (google.ads.googleads.v19.resources.types.Campaign.LocalCampaignSetting): - The setting for local campaign. - app_campaign_setting (google.ads.googleads.v19.resources.types.Campaign.AppCampaignSetting): - The setting related to App Campaign. - labels (MutableSequence[str]): - Output only. The resource names of labels - attached to this campaign. - experiment_type (google.ads.googleads.v19.enums.types.CampaignExperimentTypeEnum.CampaignExperimentType): - Output only. The type of campaign: normal, - draft, or experiment. - base_campaign (str): - Output only. The resource name of the base campaign of a - draft or experiment campaign. For base campaigns, this is - equal to ``resource_name``. - - This field is read-only. - - This field is a member of `oneof`_ ``_base_campaign``. - campaign_budget (str): - The resource name of the campaign budget of - the campaign. - - This field is a member of `oneof`_ ``_campaign_budget``. - bidding_strategy_type (google.ads.googleads.v19.enums.types.BiddingStrategyTypeEnum.BiddingStrategyType): - Output only. The type of bidding strategy. - - A bidding strategy can be created by setting either the - bidding scheme to create a standard bidding strategy or the - ``bidding_strategy`` field to create a portfolio bidding - strategy. - - This field is read-only. - accessible_bidding_strategy (str): - Output only. Resource name of AccessibleBiddingStrategy, a - read-only view of the unrestricted attributes of the - attached portfolio bidding strategy identified by - 'bidding_strategy'. Empty, if the campaign does not use a - portfolio strategy. Unrestricted strategy attributes are - available to all customers with whom the strategy is shared - and are read from the AccessibleBiddingStrategy resource. In - contrast, restricted attributes are only available to the - owner customer of the strategy and their managers. - Restricted attributes can only be read from the - BiddingStrategy resource. - start_date (str): - The date when campaign started in serving - customer's timezone in YYYY-MM-DD format. - - This field is a member of `oneof`_ ``_start_date``. - campaign_group (str): - The resource name of the campaign group that - this campaign belongs to. - - This field is a member of `oneof`_ ``_campaign_group``. - end_date (str): - The last day of the campaign in serving - customer's timezone in YYYY-MM-DD format. On - create, defaults to 2037-12-30, which means the - campaign will run indefinitely. To set an - existing campaign to run indefinitely, set this - field to 2037-12-30. - - This field is a member of `oneof`_ ``_end_date``. - final_url_suffix (str): - Suffix used to append query parameters to - landing pages that are served with parallel - tracking. - - This field is a member of `oneof`_ ``_final_url_suffix``. - frequency_caps (MutableSequence[google.ads.googleads.v19.common.types.FrequencyCapEntry]): - A list that limits how often each user will - see this campaign's ads. - video_brand_safety_suitability (google.ads.googleads.v19.enums.types.BrandSafetySuitabilityEnum.BrandSafetySuitability): - Brand Safety setting at the individual - campaign level. Allows for selecting an - inventory type to show your ads on content that - is the right fit for your brand. See - https://support.google.com/google-ads/answer/7515513. - vanity_pharma (google.ads.googleads.v19.resources.types.Campaign.VanityPharma): - Describes how unbranded pharma ads will be - displayed. - selective_optimization (google.ads.googleads.v19.resources.types.Campaign.SelectiveOptimization): - Selective optimization setting for this campaign, which - includes a set of conversion actions to optimize this - campaign towards. This feature only applies to app campaigns - that use MULTI_CHANNEL as AdvertisingChannelType and - APP_CAMPAIGN or APP_CAMPAIGN_FOR_ENGAGEMENT as - AdvertisingChannelSubType. - optimization_goal_setting (google.ads.googleads.v19.resources.types.Campaign.OptimizationGoalSetting): - Optimization goal setting for this campaign, - which includes a set of optimization goal types. - tracking_setting (google.ads.googleads.v19.resources.types.Campaign.TrackingSetting): - Output only. Campaign-level settings for - tracking information. - payment_mode (google.ads.googleads.v19.enums.types.PaymentModeEnum.PaymentMode): - Payment mode for the campaign. - optimization_score (float): - Output only. Optimization score of the - campaign. - Optimization score is an estimate of how well a - campaign is set to perform. It ranges from 0% - (0.0) to 100% (1.0), with 100% indicating that - the campaign is performing at full potential. - This field is null for unscored campaigns. - - See "About optimization score" at - https://support.google.com/google-ads/answer/9061546. - - This field is read-only. - - This field is a member of `oneof`_ ``_optimization_score``. - excluded_parent_asset_field_types (MutableSequence[google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType]): - The asset field types that should be excluded - from this campaign. Asset links with these field - types will not be inherited by this campaign - from the upper level. - excluded_parent_asset_set_types (MutableSequence[google.ads.googleads.v19.enums.types.AssetSetTypeEnum.AssetSetType]): - The asset set types that should be excluded from this - campaign. Asset set links with these types will not be - inherited by this campaign from the upper level. Location - group types (GMB_DYNAMIC_LOCATION_GROUP, - CHAIN_DYNAMIC_LOCATION_GROUP, and STATIC_LOCATION_GROUP) are - child types of LOCATION_SYNC. Therefore, if LOCATION_SYNC is - set for this field, all location group asset sets are not - allowed to be linked to this campaign, and all Location - Extension (LE) and Affiliate Location Extensions (ALE) will - not be served under this campaign. Only LOCATION_SYNC is - currently supported. - url_expansion_opt_out (bool): - Represents opting out of URL expansion to - more targeted URLs. If opted out (true), only - the final URLs in the asset group or URLs - specified in the advertiser's Google Merchant - Center or business data feeds are targeted. If - opted in (false), the entire domain will be - targeted. This field can only be set for - Performance Max campaigns, where the default - value is false. - - This field is a member of `oneof`_ ``_url_expansion_opt_out``. - performance_max_upgrade (google.ads.googleads.v19.resources.types.Campaign.PerformanceMaxUpgrade): - Output only. Information about campaigns - being upgraded to Performance Max. - hotel_property_asset_set (str): - Immutable. The resource name for a set of - hotel properties for Performance Max for travel - goals campaigns. - - This field is a member of `oneof`_ ``_hotel_property_asset_set``. - listing_type (google.ads.googleads.v19.enums.types.ListingTypeEnum.ListingType): - Immutable. Listing type of ads served for - this campaign. Field is restricted for usage - with Performance Max campaigns. - - This field is a member of `oneof`_ ``_listing_type``. - asset_automation_settings (MutableSequence[google.ads.googleads.v19.resources.types.Campaign.AssetAutomationSetting]): - Contains the opt-in/out status of each - AssetAutomationType. See documentation of each - asset automation type enum for default opt - in/out behavior. - keyword_match_type (google.ads.googleads.v19.enums.types.CampaignKeywordMatchTypeEnum.CampaignKeywordMatchType): - Keyword match type of Campaign. Set to BROAD - to set broad matching for all keywords in a - campaign. - brand_guidelines_enabled (bool): - Immutable. Whether Brand Guidelines are - enabled for this Campaign. Only applicable to - Performance Max campaigns. If enabled, business - name and logo assets must be linked as - CampaignAssets instead of AssetGroupAssets. - - Writable only at campaign creation. Set to true - to enable Brand Guidelines when creating a new - Performance Max campaign. - - Immutable after creation. This field cannot be - modified using standard update operations after - the campaign has been created. - - For existing campaigns: To enable Brand - Guidelines on a campaign after it has been - created, use the - CampaignService.EnablePMaxBrandGuidelines - method, which is a separate operation. It is not - possible to disable Brand Guidelines for an - existing campaign. - - Incompatible with Travel Goals: This feature is - not supported for Performance Max campaigns with - Travel Goals. Attempting to set this field to - true for a Travel Goals campaign will result in - an error. - - This field is a member of `oneof`_ ``_brand_guidelines_enabled``. - brand_guidelines (google.ads.googleads.v19.resources.types.Campaign.BrandGuidelines): - These settings control how your brand appears - in automatically generated assets and formats - within this campaign. Note: These settings can - only be used for Performance Max campaigns that - have Brand Guidelines enabled. - contains_eu_political_advertising (google.ads.googleads.v19.enums.types.EuPoliticalAdvertisingStatusEnum.EuPoliticalAdvertisingStatus): - The advertiser should self-declare whether - this campaign contains political advertising - content targeted towards the European Union. - bidding_strategy (str): - The resource name of the portfolio bidding - strategy used by the campaign. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - commission (google.ads.googleads.v19.common.types.Commission): - Commission is an automatic bidding strategy - in which the advertiser pays a certain portion - of the conversion value. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - manual_cpa (google.ads.googleads.v19.common.types.ManualCpa): - Standard Manual CPA bidding strategy. - Manual bidding strategy that allows advertiser - to set the bid per advertiser-specified action. - Supported only for Local Services campaigns. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - manual_cpc (google.ads.googleads.v19.common.types.ManualCpc): - Standard Manual CPC bidding strategy. - Manual click-based bidding where user pays per - click. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - manual_cpm (google.ads.googleads.v19.common.types.ManualCpm): - Standard Manual CPM bidding strategy. - Manual impression-based bidding where user pays - per thousand impressions. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - manual_cpv (google.ads.googleads.v19.common.types.ManualCpv): - A bidding strategy that pays a configurable - amount per video view. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - maximize_conversions (google.ads.googleads.v19.common.types.MaximizeConversions): - Standard Maximize Conversions bidding - strategy that automatically maximizes number of - conversions while spending your budget. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - maximize_conversion_value (google.ads.googleads.v19.common.types.MaximizeConversionValue): - Standard Maximize Conversion Value bidding - strategy that automatically sets bids to - maximize revenue while spending your budget. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - target_cpa (google.ads.googleads.v19.common.types.TargetCpa): - Standard Target CPA bidding strategy that - automatically sets bids to help get as many - conversions as possible at the target - cost-per-acquisition (CPA) you set. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - target_impression_share (google.ads.googleads.v19.common.types.TargetImpressionShare): - Target Impression Share bidding strategy. An - automated bidding strategy that sets bids to - achieve a chosen percentage of impressions. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - target_roas (google.ads.googleads.v19.common.types.TargetRoas): - Standard Target ROAS bidding strategy that - automatically maximizes revenue while averaging - a specific target return on ad spend (ROAS). - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - target_spend (google.ads.googleads.v19.common.types.TargetSpend): - Standard Target Spend bidding strategy that - automatically sets your bids to help get as many - clicks as possible within your budget. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - percent_cpc (google.ads.googleads.v19.common.types.PercentCpc): - Standard Percent Cpc bidding strategy where - bids are a fraction of the advertised price for - some good or service. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - target_cpm (google.ads.googleads.v19.common.types.TargetCpm): - A bidding strategy that automatically - optimizes cost per thousand impressions. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - fixed_cpm (google.ads.googleads.v19.common.types.FixedCpm): - A manual bidding strategy with a fixed CPM. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - target_cpv (google.ads.googleads.v19.common.types.TargetCpv): - An automated bidding strategy that sets bids - to optimize performance given the target CPV you - set. - - This field is a member of `oneof`_ ``campaign_bidding_strategy``. - """ - - class PerformanceMaxUpgrade(proto.Message): - r"""Information about a campaign being upgraded to Performance - Max. - - Attributes: - performance_max_campaign (str): - Output only. The resource name of the - Performance Max campaign the campaign is - upgraded to. - pre_upgrade_campaign (str): - Output only. The resource name of the legacy - campaign upgraded to Performance Max. - status (google.ads.googleads.v19.enums.types.PerformanceMaxUpgradeStatusEnum.PerformanceMaxUpgradeStatus): - Output only. The upgrade status of a campaign - requested to be upgraded to Performance Max. - """ - - performance_max_campaign: str = proto.Field( - proto.STRING, - number=1, - ) - pre_upgrade_campaign: str = proto.Field( - proto.STRING, - number=2, - ) - status: ( - performance_max_upgrade_status.PerformanceMaxUpgradeStatusEnum.PerformanceMaxUpgradeStatus - ) = proto.Field( - proto.ENUM, - number=3, - enum=performance_max_upgrade_status.PerformanceMaxUpgradeStatusEnum.PerformanceMaxUpgradeStatus, - ) - - class NetworkSettings(proto.Message): - r"""The network settings for the campaign. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - target_google_search (bool): - Whether ads will be served with google.com - search results. - - This field is a member of `oneof`_ ``_target_google_search``. - target_search_network (bool): - Whether ads will be served on partner sites in the Google - Search Network (requires ``target_google_search`` to also be - ``true``). - - This field is a member of `oneof`_ ``_target_search_network``. - target_content_network (bool): - Whether ads will be served on specified - placements in the Google Display Network. - Placements are specified using the Placement - criterion. - - This field is a member of `oneof`_ ``_target_content_network``. - target_partner_search_network (bool): - Whether ads will be served on the Google - Partner Network. This is available only to some - select Google partner accounts. - - This field is a member of `oneof`_ ``_target_partner_search_network``. - target_youtube (bool): - Whether ads will be served on YouTube. - - This field is a member of `oneof`_ ``_target_youtube``. - target_google_tv_network (bool): - Whether ads will be served on the Google TV - network. - - This field is a member of `oneof`_ ``_target_google_tv_network``. - """ - - target_google_search: bool = proto.Field( - proto.BOOL, - number=5, - optional=True, - ) - target_search_network: bool = proto.Field( - proto.BOOL, - number=6, - optional=True, - ) - target_content_network: bool = proto.Field( - proto.BOOL, - number=7, - optional=True, - ) - target_partner_search_network: bool = proto.Field( - proto.BOOL, - number=8, - optional=True, - ) - target_youtube: bool = proto.Field( - proto.BOOL, - number=9, - optional=True, - ) - target_google_tv_network: bool = proto.Field( - proto.BOOL, - number=10, - optional=True, - ) - - class HotelSettingInfo(proto.Message): - r"""Campaign-level settings for hotel ads. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - hotel_center_id (int): - Immutable. The linked Hotel Center account. - - This field is a member of `oneof`_ ``_hotel_center_id``. - """ - - hotel_center_id: int = proto.Field( - proto.INT64, - number=2, - optional=True, - ) - - class DynamicSearchAdsSetting(proto.Message): - r"""The setting for controlling Dynamic Search Ads (DSA). - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - domain_name (str): - Required. The Internet domain name that this - setting represents, for example, "google.com" or - "www.google.com". - language_code (str): - Required. The language code specifying the - language of the domain, for example, "en". - use_supplied_urls_only (bool): - Whether the campaign uses advertiser supplied - URLs exclusively. - - This field is a member of `oneof`_ ``_use_supplied_urls_only``. - """ - - domain_name: str = proto.Field( - proto.STRING, - number=6, - ) - language_code: str = proto.Field( - proto.STRING, - number=7, - ) - use_supplied_urls_only: bool = proto.Field( - proto.BOOL, - number=8, - optional=True, - ) - - class ShoppingSetting(proto.Message): - r"""The setting for Shopping campaigns. Defines the universe of - products that can be advertised by the campaign, and how this - campaign interacts with other Shopping campaigns. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - merchant_id (int): - ID of the Merchant Center account. - This field is required for create operations. - This field is immutable for Shopping campaigns. - - This field is a member of `oneof`_ ``_merchant_id``. - feed_label (str): - Feed label of products to include in the campaign. Only one - of feed_label or sales_country can be set. If used instead - of sales_country, the feed_label field accepts country codes - in the same format for example: 'XX'. Otherwise can be any - string used for feed label in Google Merchant Center. - campaign_priority (int): - Priority of the campaign. Campaigns with - numerically higher priorities take precedence - over those with lower priorities. This field is - required for Shopping campaigns, with values - between 0 and 2, inclusive. - This field is optional for Smart Shopping - campaigns, but must be equal to 3 if set. - - This field is a member of `oneof`_ ``_campaign_priority``. - enable_local (bool): - Whether to include local products. - - This field is a member of `oneof`_ ``_enable_local``. - use_vehicle_inventory (bool): - Immutable. Whether to target Vehicle Listing inventory. This - field is supported only in Smart Shopping Campaigns. For - setting Vehicle Listing inventory in Performance Max - campaigns, use ``listing_type`` instead. - advertising_partner_ids (MutableSequence[int]): - Immutable. The list of Google Ads accounts - IDs of advertising partners cooperating within - the campaign. This feature is currently - available only for accounts having an - advertising partner link. This feature is - currently supported only for Performance Max, - Shopping, Search and Demand Gen campaign types. - disable_product_feed (bool): - Disable the optional product feed. This field - is currently supported only for Demand Gen - campaigns. See - https://support.google.com/google-ads/answer/13721750 - to learn more about this feature. - - This field is a member of `oneof`_ ``_disable_product_feed``. - """ - - merchant_id: int = proto.Field( - proto.INT64, - number=5, - optional=True, - ) - feed_label: str = proto.Field( - proto.STRING, - number=10, - ) - campaign_priority: int = proto.Field( - proto.INT32, - number=7, - optional=True, - ) - enable_local: bool = proto.Field( - proto.BOOL, - number=8, - optional=True, - ) - use_vehicle_inventory: bool = proto.Field( - proto.BOOL, - number=9, - ) - advertising_partner_ids: MutableSequence[int] = proto.RepeatedField( - proto.INT64, - number=11, - ) - disable_product_feed: bool = proto.Field( - proto.BOOL, - number=12, - optional=True, - ) - - class TrackingSetting(proto.Message): - r"""Campaign-level settings for tracking information. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - tracking_url (str): - Output only. The url used for dynamic - tracking. - - This field is a member of `oneof`_ ``_tracking_url``. - """ - - tracking_url: str = proto.Field( - proto.STRING, - number=2, - optional=True, - ) - - class GeoTargetTypeSetting(proto.Message): - r"""Represents a collection of settings related to ads - geotargeting. - - Attributes: - positive_geo_target_type (google.ads.googleads.v19.enums.types.PositiveGeoTargetTypeEnum.PositiveGeoTargetType): - The setting used for positive geotargeting in - this particular campaign. - negative_geo_target_type (google.ads.googleads.v19.enums.types.NegativeGeoTargetTypeEnum.NegativeGeoTargetType): - The setting used for negative geotargeting in - this particular campaign. - """ - - positive_geo_target_type: ( - gage_positive_geo_target_type.PositiveGeoTargetTypeEnum.PositiveGeoTargetType - ) = proto.Field( - proto.ENUM, - number=1, - enum=gage_positive_geo_target_type.PositiveGeoTargetTypeEnum.PositiveGeoTargetType, - ) - negative_geo_target_type: ( - gage_negative_geo_target_type.NegativeGeoTargetTypeEnum.NegativeGeoTargetType - ) = proto.Field( - proto.ENUM, - number=2, - enum=gage_negative_geo_target_type.NegativeGeoTargetTypeEnum.NegativeGeoTargetType, - ) - - class LocalCampaignSetting(proto.Message): - r"""Campaign setting for local campaigns. - - Attributes: - location_source_type (google.ads.googleads.v19.enums.types.LocationSourceTypeEnum.LocationSourceType): - The location source type for this local - campaign. - """ - - location_source_type: ( - gage_location_source_type.LocationSourceTypeEnum.LocationSourceType - ) = proto.Field( - proto.ENUM, - number=1, - enum=gage_location_source_type.LocationSourceTypeEnum.LocationSourceType, - ) - - class AppCampaignSetting(proto.Message): - r"""Campaign-level settings for App Campaigns. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - bidding_strategy_goal_type (google.ads.googleads.v19.enums.types.AppCampaignBiddingStrategyGoalTypeEnum.AppCampaignBiddingStrategyGoalType): - Represents the goal which the bidding - strategy of this app campaign should optimize - towards. - app_id (str): - Immutable. A string that uniquely identifies - a mobile application. - - This field is a member of `oneof`_ ``_app_id``. - app_store (google.ads.googleads.v19.enums.types.AppCampaignAppStoreEnum.AppCampaignAppStore): - Immutable. The application store that - distributes this specific app. - """ - - bidding_strategy_goal_type: ( - app_campaign_bidding_strategy_goal_type.AppCampaignBiddingStrategyGoalTypeEnum.AppCampaignBiddingStrategyGoalType - ) = proto.Field( - proto.ENUM, - number=1, - enum=app_campaign_bidding_strategy_goal_type.AppCampaignBiddingStrategyGoalTypeEnum.AppCampaignBiddingStrategyGoalType, - ) - app_id: str = proto.Field( - proto.STRING, - number=4, - optional=True, - ) - app_store: ( - app_campaign_app_store.AppCampaignAppStoreEnum.AppCampaignAppStore - ) = proto.Field( - proto.ENUM, - number=3, - enum=app_campaign_app_store.AppCampaignAppStoreEnum.AppCampaignAppStore, - ) - - class VanityPharma(proto.Message): - r"""Describes how unbranded pharma ads will be displayed. - - Attributes: - vanity_pharma_display_url_mode (google.ads.googleads.v19.enums.types.VanityPharmaDisplayUrlModeEnum.VanityPharmaDisplayUrlMode): - The display mode for vanity pharma URLs. - vanity_pharma_text (google.ads.googleads.v19.enums.types.VanityPharmaTextEnum.VanityPharmaText): - The text that will be displayed in display - URL of the text ad when website description is - the selected display mode for vanity pharma - URLs. - """ - - vanity_pharma_display_url_mode: ( - gage_vanity_pharma_display_url_mode.VanityPharmaDisplayUrlModeEnum.VanityPharmaDisplayUrlMode - ) = proto.Field( - proto.ENUM, - number=1, - enum=gage_vanity_pharma_display_url_mode.VanityPharmaDisplayUrlModeEnum.VanityPharmaDisplayUrlMode, - ) - vanity_pharma_text: ( - gage_vanity_pharma_text.VanityPharmaTextEnum.VanityPharmaText - ) = proto.Field( - proto.ENUM, - number=2, - enum=gage_vanity_pharma_text.VanityPharmaTextEnum.VanityPharmaText, - ) - - class SelectiveOptimization(proto.Message): - r"""Selective optimization setting for this campaign, which includes a - set of conversion actions to optimize this campaign towards. This - feature only applies to app campaigns that use MULTI_CHANNEL as - AdvertisingChannelType and APP_CAMPAIGN or - APP_CAMPAIGN_FOR_ENGAGEMENT as AdvertisingChannelSubType. - - Attributes: - conversion_actions (MutableSequence[str]): - The selected set of resource names for - conversion actions for optimizing this campaign. - """ - - conversion_actions: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=2, - ) - - class OptimizationGoalSetting(proto.Message): - r"""Optimization goal setting for this campaign, which includes a - set of optimization goal types. - - Attributes: - optimization_goal_types (MutableSequence[google.ads.googleads.v19.enums.types.OptimizationGoalTypeEnum.OptimizationGoalType]): - The list of optimization goal types. - """ - - optimization_goal_types: MutableSequence[ - optimization_goal_type.OptimizationGoalTypeEnum.OptimizationGoalType - ] = proto.RepeatedField( - proto.ENUM, - number=1, - enum=optimization_goal_type.OptimizationGoalTypeEnum.OptimizationGoalType, - ) - - class AudienceSetting(proto.Message): - r"""Settings for the audience targeting. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - use_audience_grouped (bool): - Immutable. If true, this campaign uses an - Audience resource for audience targeting. If - false, this campaign may use audience segment - criteria instead. - - This field is a member of `oneof`_ ``_use_audience_grouped``. - """ - - use_audience_grouped: bool = proto.Field( - proto.BOOL, - number=1, - optional=True, - ) - - class LocalServicesCampaignSettings(proto.Message): - r"""Settings for LocalServicesCampaign subresource. - - Attributes: - category_bids (MutableSequence[google.ads.googleads.v19.resources.types.Campaign.CategoryBid]): - Categorical level bids associated with MANUAL_CPA bidding - strategy. - """ - - category_bids: MutableSequence["Campaign.CategoryBid"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message="Campaign.CategoryBid", - ) - ) - - class CategoryBid(proto.Message): - r"""Category bids in LocalServicesReportingCampaignSettings. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - category_id (str): - Category for which the bid will be associated with. For - example, xcat:service_area_business_plumber. - - This field is a member of `oneof`_ ``_category_id``. - manual_cpa_bid_micros (int): - Manual CPA bid for the category. Bid must be - greater than the reserve price associated for - that category. Value is in micros and in the - advertiser's currency. - - This field is a member of `oneof`_ ``_manual_cpa_bid_micros``. - target_cpa_bid_micros (int): - Target CPA bid for the category. Value is in - micros and in the advertiser's currency. - - This field is a member of `oneof`_ ``_target_cpa_bid_micros``. - """ - - category_id: str = proto.Field( - proto.STRING, - number=1, - optional=True, - ) - manual_cpa_bid_micros: int = proto.Field( - proto.INT64, - number=2, - optional=True, - ) - target_cpa_bid_micros: int = proto.Field( - proto.INT64, - number=3, - optional=True, - ) - - class TravelCampaignSettings(proto.Message): - r"""Settings for Travel campaign. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - travel_account_id (int): - Immutable. The Travel account ID associated - with the Travel campaign. - - This field is a member of `oneof`_ ``_travel_account_id``. - """ - - travel_account_id: int = proto.Field( - proto.INT64, - number=1, - optional=True, - ) - - class DemandGenCampaignSettings(proto.Message): - r"""Settings for Demand Gen campaign. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - upgraded_targeting (bool): - Immutable. Specifies whether this campaign uses upgraded - targeting options. When this field is set to ``true``, you - can use location and language targeting at the ad group - level as opposed to the standard campaign-level targeting. - This field defaults to ``true``, and can only be set when - creating a campaign. - - This field is a member of `oneof`_ ``_upgraded_targeting``. - """ - - upgraded_targeting: bool = proto.Field( - proto.BOOL, - number=1, - optional=True, - ) - - class VideoCampaignSettings(proto.Message): - r"""Settings for Video campaign. - - Attributes: - video_ad_inventory_control (google.ads.googleads.v19.resources.types.Campaign.VideoCampaignSettings.VideoAdInventoryControl): - Inventory control for video responsive ads in - reach campaigns. - """ - - class VideoAdInventoryControl(proto.Message): - r"""For campaigns using video responsive ads inventory controls - determine on which inventories the ads can be shown. This only - applies for campaigns with the bidding strategies TARGET_CPM and - FIXED_CPM. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - allow_in_stream (bool): - Determine if video responsive ads can be used - for in-stream video ads. - - This field is a member of `oneof`_ ``_allow_in_stream``. - allow_in_feed (bool): - Determine if video responsive ads can be used - for in-feed video ads. - - This field is a member of `oneof`_ ``_allow_in_feed``. - allow_shorts (bool): - Determine if video responsive ads can be used - as shorts format. - - This field is a member of `oneof`_ ``_allow_shorts``. - """ - - allow_in_stream: bool = proto.Field( - proto.BOOL, - number=1, - optional=True, - ) - allow_in_feed: bool = proto.Field( - proto.BOOL, - number=2, - optional=True, - ) - allow_shorts: bool = proto.Field( - proto.BOOL, - number=3, - optional=True, - ) - - video_ad_inventory_control: ( - "Campaign.VideoCampaignSettings.VideoAdInventoryControl" - ) = proto.Field( - proto.MESSAGE, - number=1, - message="Campaign.VideoCampaignSettings.VideoAdInventoryControl", - ) - - class PmaxCampaignSettings(proto.Message): - r"""Settings for Performance Max campaigns. - - Attributes: - brand_targeting_overrides (google.ads.googleads.v19.resources.types.Campaign.PmaxCampaignSettings.BrandTargetingOverrides): - Overrides of brand targeting for various ad - types. - """ - - class BrandTargetingOverrides(proto.Message): - r"""Overrides of brand targeting for various ad types. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - ignore_exclusions_for_shopping_ads (bool): - If true, brand exclusions are ignored for - Shopping ads. - - This field is a member of `oneof`_ ``_ignore_exclusions_for_shopping_ads``. - """ - - ignore_exclusions_for_shopping_ads: bool = proto.Field( - proto.BOOL, - number=1, - optional=True, - ) - - brand_targeting_overrides: ( - "Campaign.PmaxCampaignSettings.BrandTargetingOverrides" - ) = proto.Field( - proto.MESSAGE, - number=1, - message="Campaign.PmaxCampaignSettings.BrandTargetingOverrides", - ) - - class AssetAutomationSetting(proto.Message): - r"""Asset automation setting contains pair of AssetAutomationType - and the asset automation opt-in/out status - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - asset_automation_type (google.ads.googleads.v19.enums.types.AssetAutomationTypeEnum.AssetAutomationType): - The asset automation type advertiser would - like to opt-in/out. - - This field is a member of `oneof`_ ``_asset_automation_type``. - asset_automation_status (google.ads.googleads.v19.enums.types.AssetAutomationStatusEnum.AssetAutomationStatus): - The opt-in/out status of asset automation - type. - - This field is a member of `oneof`_ ``_asset_automation_status``. - """ - - asset_automation_type: ( - gage_asset_automation_type.AssetAutomationTypeEnum.AssetAutomationType - ) = proto.Field( - proto.ENUM, - number=1, - optional=True, - enum=gage_asset_automation_type.AssetAutomationTypeEnum.AssetAutomationType, - ) - asset_automation_status: ( - gage_asset_automation_status.AssetAutomationStatusEnum.AssetAutomationStatus - ) = proto.Field( - proto.ENUM, - number=2, - optional=True, - enum=gage_asset_automation_status.AssetAutomationStatusEnum.AssetAutomationStatus, - ) - - class BrandGuidelines(proto.Message): - r"""Settings that control the visual appearance of your brand in - a campaign's automatically generated assets and formats. Only - applicable to Performance Max campaigns. - - Attributes: - main_color (str): - The main brand color, entered as a hex code (e.g., #00ff00). - You must provide the main_color if you provide an - accent_color. - accent_color (str): - The accent brand color, entered as a hex code (e.g., - #00ff00). You must provide the accent_color if you provide a - main_color. - predefined_font_family (str): - The brand's font family. Must be one of the - following Google Fonts (case sensitive): Open - Sans, Roboto, Montserrat, Poppins, Lato, Oswald, - Playfair Display, Roboto Slab. - """ - - main_color: str = proto.Field( - proto.STRING, - number=1, - ) - accent_color: str = proto.Field( - proto.STRING, - number=2, - ) - predefined_font_family: str = proto.Field( - proto.STRING, - number=3, - ) - - resource_name: str = proto.Field( - proto.STRING, - number=1, - ) - id: int = proto.Field( - proto.INT64, - number=59, - optional=True, - ) - name: str = proto.Field( - proto.STRING, - number=58, - optional=True, - ) - primary_status: ( - campaign_primary_status.CampaignPrimaryStatusEnum.CampaignPrimaryStatus - ) = proto.Field( - proto.ENUM, - number=81, - enum=campaign_primary_status.CampaignPrimaryStatusEnum.CampaignPrimaryStatus, - ) - primary_status_reasons: MutableSequence[ - campaign_primary_status_reason.CampaignPrimaryStatusReasonEnum.CampaignPrimaryStatusReason - ] = proto.RepeatedField( - proto.ENUM, - number=82, - enum=campaign_primary_status_reason.CampaignPrimaryStatusReasonEnum.CampaignPrimaryStatusReason, - ) - status: campaign_status.CampaignStatusEnum.CampaignStatus = proto.Field( - proto.ENUM, - number=5, - enum=campaign_status.CampaignStatusEnum.CampaignStatus, - ) - serving_status: ( - campaign_serving_status.CampaignServingStatusEnum.CampaignServingStatus - ) = proto.Field( - proto.ENUM, - number=21, - enum=campaign_serving_status.CampaignServingStatusEnum.CampaignServingStatus, - ) - bidding_strategy_system_status: ( - gage_bidding_strategy_system_status.BiddingStrategySystemStatusEnum.BiddingStrategySystemStatus - ) = proto.Field( - proto.ENUM, - number=78, - enum=gage_bidding_strategy_system_status.BiddingStrategySystemStatusEnum.BiddingStrategySystemStatus, - ) - ad_serving_optimization_status: ( - gage_ad_serving_optimization_status.AdServingOptimizationStatusEnum.AdServingOptimizationStatus - ) = proto.Field( - proto.ENUM, - number=8, - enum=gage_ad_serving_optimization_status.AdServingOptimizationStatusEnum.AdServingOptimizationStatus, - ) - advertising_channel_type: ( - gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType - ) = proto.Field( - proto.ENUM, - number=9, - enum=gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType, - ) - advertising_channel_sub_type: ( - gage_advertising_channel_sub_type.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType - ) = proto.Field( - proto.ENUM, - number=10, - enum=gage_advertising_channel_sub_type.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType, - ) - tracking_url_template: str = proto.Field( - proto.STRING, - number=60, - optional=True, - ) - url_custom_parameters: MutableSequence[custom_parameter.CustomParameter] = ( - proto.RepeatedField( - proto.MESSAGE, - number=12, - message=custom_parameter.CustomParameter, - ) - ) - local_services_campaign_settings: LocalServicesCampaignSettings = ( - proto.Field( - proto.MESSAGE, - number=75, - message=LocalServicesCampaignSettings, - ) - ) - travel_campaign_settings: TravelCampaignSettings = proto.Field( - proto.MESSAGE, - number=85, - message=TravelCampaignSettings, - ) - demand_gen_campaign_settings: DemandGenCampaignSettings = proto.Field( - proto.MESSAGE, - number=91, - message=DemandGenCampaignSettings, - ) - video_campaign_settings: VideoCampaignSettings = proto.Field( - proto.MESSAGE, - number=94, - message=VideoCampaignSettings, - ) - pmax_campaign_settings: PmaxCampaignSettings = proto.Field( - proto.MESSAGE, - number=97, - message=PmaxCampaignSettings, - ) - real_time_bidding_setting: ( - gagc_real_time_bidding_setting.RealTimeBiddingSetting - ) = proto.Field( - proto.MESSAGE, - number=39, - message=gagc_real_time_bidding_setting.RealTimeBiddingSetting, - ) - network_settings: NetworkSettings = proto.Field( - proto.MESSAGE, - number=14, - message=NetworkSettings, - ) - hotel_setting: HotelSettingInfo = proto.Field( - proto.MESSAGE, - number=32, - message=HotelSettingInfo, - ) - dynamic_search_ads_setting: DynamicSearchAdsSetting = proto.Field( - proto.MESSAGE, - number=33, - message=DynamicSearchAdsSetting, - ) - shopping_setting: ShoppingSetting = proto.Field( - proto.MESSAGE, - number=36, - message=ShoppingSetting, - ) - targeting_setting: gagc_targeting_setting.TargetingSetting = proto.Field( - proto.MESSAGE, - number=43, - message=gagc_targeting_setting.TargetingSetting, - ) - audience_setting: AudienceSetting = proto.Field( - proto.MESSAGE, - number=73, - optional=True, - message=AudienceSetting, - ) - geo_target_type_setting: GeoTargetTypeSetting = proto.Field( - proto.MESSAGE, - number=47, - message=GeoTargetTypeSetting, - ) - local_campaign_setting: LocalCampaignSetting = proto.Field( - proto.MESSAGE, - number=50, - message=LocalCampaignSetting, - ) - app_campaign_setting: AppCampaignSetting = proto.Field( - proto.MESSAGE, - number=51, - message=AppCampaignSetting, - ) - labels: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=61, - ) - experiment_type: ( - campaign_experiment_type.CampaignExperimentTypeEnum.CampaignExperimentType - ) = proto.Field( - proto.ENUM, - number=17, - enum=campaign_experiment_type.CampaignExperimentTypeEnum.CampaignExperimentType, - ) - base_campaign: str = proto.Field( - proto.STRING, - number=56, - optional=True, - ) - campaign_budget: str = proto.Field( - proto.STRING, - number=62, - optional=True, - ) - bidding_strategy_type: ( - gage_bidding_strategy_type.BiddingStrategyTypeEnum.BiddingStrategyType - ) = proto.Field( - proto.ENUM, - number=22, - enum=gage_bidding_strategy_type.BiddingStrategyTypeEnum.BiddingStrategyType, - ) - accessible_bidding_strategy: str = proto.Field( - proto.STRING, - number=71, - ) - start_date: str = proto.Field( - proto.STRING, - number=63, - optional=True, - ) - campaign_group: str = proto.Field( - proto.STRING, - number=76, - optional=True, - ) - end_date: str = proto.Field( - proto.STRING, - number=64, - optional=True, - ) - final_url_suffix: str = proto.Field( - proto.STRING, - number=65, - optional=True, - ) - frequency_caps: MutableSequence[frequency_cap.FrequencyCapEntry] = ( - proto.RepeatedField( - proto.MESSAGE, - number=40, - message=frequency_cap.FrequencyCapEntry, - ) - ) - video_brand_safety_suitability: ( - brand_safety_suitability.BrandSafetySuitabilityEnum.BrandSafetySuitability - ) = proto.Field( - proto.ENUM, - number=42, - enum=brand_safety_suitability.BrandSafetySuitabilityEnum.BrandSafetySuitability, - ) - vanity_pharma: VanityPharma = proto.Field( - proto.MESSAGE, - number=44, - message=VanityPharma, - ) - selective_optimization: SelectiveOptimization = proto.Field( - proto.MESSAGE, - number=45, - message=SelectiveOptimization, - ) - optimization_goal_setting: OptimizationGoalSetting = proto.Field( - proto.MESSAGE, - number=54, - message=OptimizationGoalSetting, - ) - tracking_setting: TrackingSetting = proto.Field( - proto.MESSAGE, - number=46, - message=TrackingSetting, - ) - payment_mode: gage_payment_mode.PaymentModeEnum.PaymentMode = proto.Field( - proto.ENUM, - number=52, - enum=gage_payment_mode.PaymentModeEnum.PaymentMode, - ) - optimization_score: float = proto.Field( - proto.DOUBLE, - number=66, - optional=True, - ) - excluded_parent_asset_field_types: MutableSequence[ - asset_field_type.AssetFieldTypeEnum.AssetFieldType - ] = proto.RepeatedField( - proto.ENUM, - number=69, - enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, - ) - excluded_parent_asset_set_types: MutableSequence[ - asset_set_type.AssetSetTypeEnum.AssetSetType - ] = proto.RepeatedField( - proto.ENUM, - number=80, - enum=asset_set_type.AssetSetTypeEnum.AssetSetType, - ) - url_expansion_opt_out: bool = proto.Field( - proto.BOOL, - number=72, - optional=True, - ) - performance_max_upgrade: PerformanceMaxUpgrade = proto.Field( - proto.MESSAGE, - number=77, - message=PerformanceMaxUpgrade, - ) - hotel_property_asset_set: str = proto.Field( - proto.STRING, - number=83, - optional=True, - ) - listing_type: gage_listing_type.ListingTypeEnum.ListingType = proto.Field( - proto.ENUM, - number=86, - optional=True, - enum=gage_listing_type.ListingTypeEnum.ListingType, - ) - asset_automation_settings: MutableSequence[AssetAutomationSetting] = ( - proto.RepeatedField( - proto.MESSAGE, - number=88, - message=AssetAutomationSetting, - ) - ) - keyword_match_type: ( - campaign_keyword_match_type.CampaignKeywordMatchTypeEnum.CampaignKeywordMatchType - ) = proto.Field( - proto.ENUM, - number=90, - enum=campaign_keyword_match_type.CampaignKeywordMatchTypeEnum.CampaignKeywordMatchType, - ) - brand_guidelines_enabled: bool = proto.Field( - proto.BOOL, - number=96, - optional=True, - ) - brand_guidelines: BrandGuidelines = proto.Field( - proto.MESSAGE, - number=98, - message=BrandGuidelines, - ) - contains_eu_political_advertising: ( - eu_political_advertising_status.EuPoliticalAdvertisingStatusEnum.EuPoliticalAdvertisingStatus - ) = proto.Field( - proto.ENUM, - number=102, - enum=eu_political_advertising_status.EuPoliticalAdvertisingStatusEnum.EuPoliticalAdvertisingStatus, - ) - bidding_strategy: str = proto.Field( - proto.STRING, - number=67, - oneof="campaign_bidding_strategy", - ) - commission: bidding.Commission = proto.Field( - proto.MESSAGE, - number=49, - oneof="campaign_bidding_strategy", - message=bidding.Commission, - ) - manual_cpa: bidding.ManualCpa = proto.Field( - proto.MESSAGE, - number=74, - oneof="campaign_bidding_strategy", - message=bidding.ManualCpa, - ) - manual_cpc: bidding.ManualCpc = proto.Field( - proto.MESSAGE, - number=24, - oneof="campaign_bidding_strategy", - message=bidding.ManualCpc, - ) - manual_cpm: bidding.ManualCpm = proto.Field( - proto.MESSAGE, - number=25, - oneof="campaign_bidding_strategy", - message=bidding.ManualCpm, - ) - manual_cpv: bidding.ManualCpv = proto.Field( - proto.MESSAGE, - number=37, - oneof="campaign_bidding_strategy", - message=bidding.ManualCpv, - ) - maximize_conversions: bidding.MaximizeConversions = proto.Field( - proto.MESSAGE, - number=30, - oneof="campaign_bidding_strategy", - message=bidding.MaximizeConversions, - ) - maximize_conversion_value: bidding.MaximizeConversionValue = proto.Field( - proto.MESSAGE, - number=31, - oneof="campaign_bidding_strategy", - message=bidding.MaximizeConversionValue, - ) - target_cpa: bidding.TargetCpa = proto.Field( - proto.MESSAGE, - number=26, - oneof="campaign_bidding_strategy", - message=bidding.TargetCpa, - ) - target_impression_share: bidding.TargetImpressionShare = proto.Field( - proto.MESSAGE, - number=48, - oneof="campaign_bidding_strategy", - message=bidding.TargetImpressionShare, - ) - target_roas: bidding.TargetRoas = proto.Field( - proto.MESSAGE, - number=29, - oneof="campaign_bidding_strategy", - message=bidding.TargetRoas, - ) - target_spend: bidding.TargetSpend = proto.Field( - proto.MESSAGE, - number=27, - oneof="campaign_bidding_strategy", - message=bidding.TargetSpend, - ) - percent_cpc: bidding.PercentCpc = proto.Field( - proto.MESSAGE, - number=34, - oneof="campaign_bidding_strategy", - message=bidding.PercentCpc, - ) - target_cpm: bidding.TargetCpm = proto.Field( - proto.MESSAGE, - number=41, - oneof="campaign_bidding_strategy", - message=bidding.TargetCpm, - ) - fixed_cpm: bidding.FixedCpm = proto.Field( - proto.MESSAGE, - number=92, - oneof="campaign_bidding_strategy", - message=bidding.FixedCpm, - ) - target_cpv: bidding.TargetCpv = proto.Field( - proto.MESSAGE, - number=93, - oneof="campaign_bidding_strategy", - message=bidding.TargetCpv, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/display_keyword_view.py b/google/ads/googleads/v19/resources/types/display_keyword_view.py deleted file mode 100644 index 4abd65479..000000000 --- a/google/ads/googleads/v19/resources/types/display_keyword_view.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - - -import proto # type: ignore - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", - manifest={ - "DisplayKeywordView", - }, -) - - -class DisplayKeywordView(proto.Message): - r"""A display keyword view. - - Attributes: - resource_name (str): - Output only. The resource name of the display keyword view. - Display Keyword view resource names have the form: - - ``customers/{customer_id}/displayKeywordViews/{ad_group_id}~{criterion_id}`` - """ - - resource_name: str = proto.Field( - proto.STRING, - number=1, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/per_store_view.py b/google/ads/googleads/v19/resources/types/per_store_view.py deleted file mode 100644 index 920725017..000000000 --- a/google/ads/googleads/v19/resources/types/per_store_view.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - - -import proto # type: ignore - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", - manifest={ - "PerStoreView", - }, -) - - -class PerStoreView(proto.Message): - r"""A per store view. - This view provides per store impression reach and local action - conversion stats for advertisers. - - Attributes: - resource_name (str): - Output only. The resource name of the per store view. Per - Store view resource names have the form: - - ``customers/{customer_id}/perStoreViews/{place_id}`` - place_id (str): - Output only. The place ID of the per store - view. - """ - - resource_name: str = proto.Field( - proto.STRING, - number=1, - ) - place_id: str = proto.Field( - proto.STRING, - number=2, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/shared_criterion.py b/google/ads/googleads/v19/resources/types/shared_criterion.py deleted file mode 100644 index 28f1e9258..000000000 --- a/google/ads/googleads/v19/resources/types/shared_criterion.py +++ /dev/null @@ -1,156 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - - -import proto # type: ignore - -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.enums.types import criterion_type - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", - manifest={ - "SharedCriterion", - }, -) - - -class SharedCriterion(proto.Message): - r"""A criterion belonging to a shared set. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - resource_name (str): - Immutable. The resource name of the shared criterion. Shared - set resource names have the form: - - ``customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}`` - shared_set (str): - Immutable. The shared set to which the shared - criterion belongs. - - This field is a member of `oneof`_ ``_shared_set``. - criterion_id (int): - Output only. The ID of the criterion. - - This field is ignored for mutates. - - This field is a member of `oneof`_ ``_criterion_id``. - type_ (google.ads.googleads.v19.enums.types.CriterionTypeEnum.CriterionType): - Output only. The type of the criterion. - keyword (google.ads.googleads.v19.common.types.KeywordInfo): - Immutable. Keyword. - - This field is a member of `oneof`_ ``criterion``. - youtube_video (google.ads.googleads.v19.common.types.YouTubeVideoInfo): - Immutable. YouTube Video. - - This field is a member of `oneof`_ ``criterion``. - youtube_channel (google.ads.googleads.v19.common.types.YouTubeChannelInfo): - Immutable. YouTube Channel. - - This field is a member of `oneof`_ ``criterion``. - placement (google.ads.googleads.v19.common.types.PlacementInfo): - Immutable. Placement. - - This field is a member of `oneof`_ ``criterion``. - mobile_app_category (google.ads.googleads.v19.common.types.MobileAppCategoryInfo): - Immutable. Mobile App Category. - - This field is a member of `oneof`_ ``criterion``. - mobile_application (google.ads.googleads.v19.common.types.MobileApplicationInfo): - Immutable. Mobile application. - - This field is a member of `oneof`_ ``criterion``. - brand (google.ads.googleads.v19.common.types.BrandInfo): - Immutable. Brand. - - This field is a member of `oneof`_ ``criterion``. - """ - - resource_name: str = proto.Field( - proto.STRING, - number=1, - ) - shared_set: str = proto.Field( - proto.STRING, - number=10, - optional=True, - ) - criterion_id: int = proto.Field( - proto.INT64, - number=11, - optional=True, - ) - type_: criterion_type.CriterionTypeEnum.CriterionType = proto.Field( - proto.ENUM, - number=4, - enum=criterion_type.CriterionTypeEnum.CriterionType, - ) - keyword: criteria.KeywordInfo = proto.Field( - proto.MESSAGE, - number=3, - oneof="criterion", - message=criteria.KeywordInfo, - ) - youtube_video: criteria.YouTubeVideoInfo = proto.Field( - proto.MESSAGE, - number=5, - oneof="criterion", - message=criteria.YouTubeVideoInfo, - ) - youtube_channel: criteria.YouTubeChannelInfo = proto.Field( - proto.MESSAGE, - number=6, - oneof="criterion", - message=criteria.YouTubeChannelInfo, - ) - placement: criteria.PlacementInfo = proto.Field( - proto.MESSAGE, - number=7, - oneof="criterion", - message=criteria.PlacementInfo, - ) - mobile_app_category: criteria.MobileAppCategoryInfo = proto.Field( - proto.MESSAGE, - number=8, - oneof="criterion", - message=criteria.MobileAppCategoryInfo, - ) - mobile_application: criteria.MobileApplicationInfo = proto.Field( - proto.MESSAGE, - number=9, - oneof="criterion", - message=criteria.MobileApplicationInfo, - ) - brand: criteria.BrandInfo = proto.Field( - proto.MESSAGE, - number=12, - oneof="criterion", - message=criteria.BrandInfo, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/shared_set.py b/google/ads/googleads/v19/resources/types/shared_set.py deleted file mode 100644 index 4b829ced8..000000000 --- a/google/ads/googleads/v19/resources/types/shared_set.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - - -import proto # type: ignore - -from google.ads.googleads.v19.enums.types import shared_set_status -from google.ads.googleads.v19.enums.types import shared_set_type - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", - manifest={ - "SharedSet", - }, -) - - -class SharedSet(proto.Message): - r"""SharedSets are used for sharing criterion exclusions across - multiple campaigns. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - resource_name (str): - Immutable. The resource name of the shared set. Shared set - resource names have the form: - - ``customers/{customer_id}/sharedSets/{shared_set_id}`` - id (int): - Output only. The ID of this shared set. Read - only. - - This field is a member of `oneof`_ ``_id``. - type_ (google.ads.googleads.v19.enums.types.SharedSetTypeEnum.SharedSetType): - Immutable. The type of this shared set: each - shared set holds only a single kind of resource. - Required. Immutable. - name (str): - The name of this shared set. Required. - Shared Sets must have names that are unique - among active shared sets of the same type. - The length of this string should be between 1 - and 255 UTF-8 bytes, inclusive. - - This field is a member of `oneof`_ ``_name``. - status (google.ads.googleads.v19.enums.types.SharedSetStatusEnum.SharedSetStatus): - Output only. The status of this shared set. - Read only. - member_count (int): - Output only. The number of shared criteria - within this shared set. Read only. - - This field is a member of `oneof`_ ``_member_count``. - reference_count (int): - Output only. The number of campaigns - associated with this shared set. Read only. - - This field is a member of `oneof`_ ``_reference_count``. - """ - - resource_name: str = proto.Field( - proto.STRING, - number=1, - ) - id: int = proto.Field( - proto.INT64, - number=8, - optional=True, - ) - type_: shared_set_type.SharedSetTypeEnum.SharedSetType = proto.Field( - proto.ENUM, - number=3, - enum=shared_set_type.SharedSetTypeEnum.SharedSetType, - ) - name: str = proto.Field( - proto.STRING, - number=9, - optional=True, - ) - status: shared_set_status.SharedSetStatusEnum.SharedSetStatus = proto.Field( - proto.ENUM, - number=5, - enum=shared_set_status.SharedSetStatusEnum.SharedSetStatus, - ) - member_count: int = proto.Field( - proto.INT64, - number=10, - optional=True, - ) - reference_count: int = proto.Field( - proto.INT64, - number=11, - optional=True, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/shopping_performance_view.py b/google/ads/googleads/v19/resources/types/shopping_performance_view.py deleted file mode 100644 index 5cdc5373e..000000000 --- a/google/ads/googleads/v19/resources/types/shopping_performance_view.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - - -import proto # type: ignore - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", - manifest={ - "ShoppingPerformanceView", - }, -) - - -class ShoppingPerformanceView(proto.Message): - r"""Shopping performance view. - Provides Shopping campaign statistics aggregated at several - product dimension levels. Product dimension values from Merchant - Center such as brand, category, custom attributes, product - condition and product type will reflect the state of each - dimension as of the date and time when the corresponding event - was recorded. - - Attributes: - resource_name (str): - Output only. The resource name of the Shopping performance - view. Shopping performance view resource names have the - form: ``customers/{customer_id}/shoppingPerformanceView`` - """ - - resource_name: str = proto.Field( - proto.STRING, - number=1, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/__init__.py b/google/ads/googleads/v19/services/__init__.py deleted file mode 100644 index 962a98b42..000000000 --- a/google/ads/googleads/v19/services/__init__.py +++ /dev/null @@ -1,1336 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .types.account_budget_proposal_service import ( - AccountBudgetProposalOperation, - MutateAccountBudgetProposalRequest, - MutateAccountBudgetProposalResponse, - MutateAccountBudgetProposalResult, -) -from .types.account_link_service import ( - AccountLinkOperation, - CreateAccountLinkRequest, - CreateAccountLinkResponse, - MutateAccountLinkRequest, - MutateAccountLinkResponse, - MutateAccountLinkResult, -) -from .types.ad_group_ad_label_service import ( - AdGroupAdLabelOperation, - MutateAdGroupAdLabelResult, - MutateAdGroupAdLabelsRequest, - MutateAdGroupAdLabelsResponse, -) -from .types.ad_group_ad_service import ( - AdGroupAdOperation, - AssetsWithFieldType, - MutateAdGroupAdResult, - MutateAdGroupAdsRequest, - MutateAdGroupAdsResponse, - RemoveAutomaticallyCreatedAssetsRequest, -) -from .types.ad_group_asset_service import ( - AdGroupAssetOperation, - MutateAdGroupAssetResult, - MutateAdGroupAssetsRequest, - MutateAdGroupAssetsResponse, -) -from .types.ad_group_asset_set_service import ( - AdGroupAssetSetOperation, - MutateAdGroupAssetSetResult, - MutateAdGroupAssetSetsRequest, - MutateAdGroupAssetSetsResponse, -) -from .types.ad_group_bid_modifier_service import ( - AdGroupBidModifierOperation, - MutateAdGroupBidModifierResult, - MutateAdGroupBidModifiersRequest, - MutateAdGroupBidModifiersResponse, -) -from .types.ad_group_criterion_customizer_service import ( - AdGroupCriterionCustomizerOperation, - MutateAdGroupCriterionCustomizerResult, - MutateAdGroupCriterionCustomizersRequest, - MutateAdGroupCriterionCustomizersResponse, -) -from .types.ad_group_criterion_label_service import ( - AdGroupCriterionLabelOperation, - MutateAdGroupCriterionLabelResult, - MutateAdGroupCriterionLabelsRequest, - MutateAdGroupCriterionLabelsResponse, -) -from .types.ad_group_criterion_service import ( - AdGroupCriterionOperation, - MutateAdGroupCriteriaRequest, - MutateAdGroupCriteriaResponse, - MutateAdGroupCriterionResult, -) -from .types.ad_group_customizer_service import ( - AdGroupCustomizerOperation, - MutateAdGroupCustomizerResult, - MutateAdGroupCustomizersRequest, - MutateAdGroupCustomizersResponse, -) -from .types.ad_group_label_service import ( - AdGroupLabelOperation, - MutateAdGroupLabelResult, - MutateAdGroupLabelsRequest, - MutateAdGroupLabelsResponse, -) -from .types.ad_group_service import ( - AdGroupOperation, - MutateAdGroupResult, - MutateAdGroupsRequest, - MutateAdGroupsResponse, -) -from .types.ad_parameter_service import ( - AdParameterOperation, - MutateAdParameterResult, - MutateAdParametersRequest, - MutateAdParametersResponse, -) -from .types.ad_service import ( - AdOperation, - MutateAdResult, - MutateAdsRequest, - MutateAdsResponse, -) -from .types.asset_group_asset_service import ( - AssetGroupAssetOperation, - MutateAssetGroupAssetResult, - MutateAssetGroupAssetsRequest, - MutateAssetGroupAssetsResponse, -) -from .types.asset_group_listing_group_filter_service import ( - AssetGroupListingGroupFilterOperation, - MutateAssetGroupListingGroupFilterResult, - MutateAssetGroupListingGroupFiltersRequest, - MutateAssetGroupListingGroupFiltersResponse, -) -from .types.asset_group_service import ( - AssetGroupOperation, - MutateAssetGroupResult, - MutateAssetGroupsRequest, - MutateAssetGroupsResponse, -) -from .types.asset_group_signal_service import ( - AssetGroupSignalOperation, - MutateAssetGroupSignalResult, - MutateAssetGroupSignalsRequest, - MutateAssetGroupSignalsResponse, -) -from .types.asset_service import ( - AssetOperation, - MutateAssetResult, - MutateAssetsRequest, - MutateAssetsResponse, -) -from .types.asset_set_asset_service import ( - AssetSetAssetOperation, - MutateAssetSetAssetResult, - MutateAssetSetAssetsRequest, - MutateAssetSetAssetsResponse, -) -from .types.asset_set_service import ( - AssetSetOperation, - MutateAssetSetResult, - MutateAssetSetsRequest, - MutateAssetSetsResponse, -) -from .types.audience_insights_service import ( - AudienceCompositionAttribute, - AudienceCompositionAttributeCluster, - AudienceCompositionMetrics, - AudienceCompositionSection, - AudienceOverlapItem, - BasicInsightsAudience, - DimensionOverlapResult, - GenerateAudienceCompositionInsightsRequest, - GenerateAudienceCompositionInsightsResponse, - GenerateAudienceOverlapInsightsRequest, - GenerateAudienceOverlapInsightsResponse, - GenerateInsightsFinderReportRequest, - GenerateInsightsFinderReportResponse, - GenerateSuggestedTargetingInsightsRequest, - GenerateSuggestedTargetingInsightsResponse, - GenerateTargetingSuggestionMetricsRequest, - GenerateTargetingSuggestionMetricsResponse, - InsightsAudience, - InsightsAudienceAttributeGroup, - InsightsAudienceDefinition, - InsightsAudienceDescription, - ListAudienceInsightsAttributesRequest, - ListAudienceInsightsAttributesResponse, - ListInsightsEligibleDatesRequest, - ListInsightsEligibleDatesResponse, - TargetingSuggestionMetrics, -) -from .types.audience_service import ( - AudienceOperation, - MutateAudienceResult, - MutateAudiencesRequest, - MutateAudiencesResponse, -) -from .types.batch_job_service import ( - AddBatchJobOperationsRequest, - AddBatchJobOperationsResponse, - BatchJobOperation, - BatchJobResult, - ListBatchJobResultsRequest, - ListBatchJobResultsResponse, - MutateBatchJobRequest, - MutateBatchJobResponse, - MutateBatchJobResult, - RunBatchJobRequest, -) -from .types.bidding_data_exclusion_service import ( - BiddingDataExclusionOperation, - MutateBiddingDataExclusionsRequest, - MutateBiddingDataExclusionsResponse, - MutateBiddingDataExclusionsResult, -) -from .types.bidding_seasonality_adjustment_service import ( - BiddingSeasonalityAdjustmentOperation, - MutateBiddingSeasonalityAdjustmentsRequest, - MutateBiddingSeasonalityAdjustmentsResponse, - MutateBiddingSeasonalityAdjustmentsResult, -) -from .types.bidding_strategy_service import ( - BiddingStrategyOperation, - MutateBiddingStrategiesRequest, - MutateBiddingStrategiesResponse, - MutateBiddingStrategyResult, -) -from .types.billing_setup_service import ( - BillingSetupOperation, - MutateBillingSetupRequest, - MutateBillingSetupResponse, - MutateBillingSetupResult, -) -from .types.brand_suggestion_service import ( - BrandSuggestion, - SuggestBrandsRequest, - SuggestBrandsResponse, -) -from .types.campaign_asset_service import ( - CampaignAssetOperation, - MutateCampaignAssetResult, - MutateCampaignAssetsRequest, - MutateCampaignAssetsResponse, -) -from .types.campaign_asset_set_service import ( - CampaignAssetSetOperation, - MutateCampaignAssetSetResult, - MutateCampaignAssetSetsRequest, - MutateCampaignAssetSetsResponse, -) -from .types.campaign_bid_modifier_service import ( - CampaignBidModifierOperation, - MutateCampaignBidModifierResult, - MutateCampaignBidModifiersRequest, - MutateCampaignBidModifiersResponse, -) -from .types.campaign_budget_service import ( - CampaignBudgetOperation, - MutateCampaignBudgetResult, - MutateCampaignBudgetsRequest, - MutateCampaignBudgetsResponse, -) -from .types.campaign_conversion_goal_service import ( - CampaignConversionGoalOperation, - MutateCampaignConversionGoalResult, - MutateCampaignConversionGoalsRequest, - MutateCampaignConversionGoalsResponse, -) -from .types.campaign_criterion_service import ( - CampaignCriterionOperation, - MutateCampaignCriteriaRequest, - MutateCampaignCriteriaResponse, - MutateCampaignCriterionResult, -) -from .types.campaign_customizer_service import ( - CampaignCustomizerOperation, - MutateCampaignCustomizerResult, - MutateCampaignCustomizersRequest, - MutateCampaignCustomizersResponse, -) -from .types.campaign_draft_service import ( - CampaignDraftOperation, - ListCampaignDraftAsyncErrorsRequest, - ListCampaignDraftAsyncErrorsResponse, - MutateCampaignDraftResult, - MutateCampaignDraftsRequest, - MutateCampaignDraftsResponse, - PromoteCampaignDraftRequest, -) -from .types.campaign_group_service import ( - CampaignGroupOperation, - MutateCampaignGroupResult, - MutateCampaignGroupsRequest, - MutateCampaignGroupsResponse, -) -from .types.campaign_label_service import ( - CampaignLabelOperation, - MutateCampaignLabelResult, - MutateCampaignLabelsRequest, - MutateCampaignLabelsResponse, -) -from .types.campaign_lifecycle_goal_service import ( - CampaignLifecycleGoalOperation, - ConfigureCampaignLifecycleGoalsRequest, - ConfigureCampaignLifecycleGoalsResponse, - ConfigureCampaignLifecycleGoalsResult, -) -from .types.campaign_service import ( - BrandCampaignAssets, - CampaignOperation, - EnablementResult, - EnableOperation, - EnablePMaxBrandGuidelinesRequest, - EnablePMaxBrandGuidelinesResponse, - MutateCampaignResult, - MutateCampaignsRequest, - MutateCampaignsResponse, -) -from .types.campaign_shared_set_service import ( - CampaignSharedSetOperation, - MutateCampaignSharedSetResult, - MutateCampaignSharedSetsRequest, - MutateCampaignSharedSetsResponse, -) -from .types.content_creator_insights_service import ( - GenerateCreatorInsightsRequest, - GenerateCreatorInsightsResponse, - GenerateTrendingInsightsRequest, - GenerateTrendingInsightsResponse, - SearchAudience, - SearchTopics, - TrendInsight, - TrendInsightMetrics, - YouTubeChannelInsights, - YouTubeCreatorInsights, - YouTubeMetrics, -) -from .types.conversion_action_service import ( - ConversionActionOperation, - MutateConversionActionResult, - MutateConversionActionsRequest, - MutateConversionActionsResponse, -) -from .types.conversion_adjustment_upload_service import ( - ConversionAdjustment, - ConversionAdjustmentResult, - GclidDateTimePair, - RestatementValue, - UploadConversionAdjustmentsRequest, - UploadConversionAdjustmentsResponse, -) -from .types.conversion_custom_variable_service import ( - ConversionCustomVariableOperation, - MutateConversionCustomVariableResult, - MutateConversionCustomVariablesRequest, - MutateConversionCustomVariablesResponse, -) -from .types.conversion_goal_campaign_config_service import ( - ConversionGoalCampaignConfigOperation, - MutateConversionGoalCampaignConfigResult, - MutateConversionGoalCampaignConfigsRequest, - MutateConversionGoalCampaignConfigsResponse, -) -from .types.conversion_upload_service import ( - CallConversion, - CallConversionResult, - CartData, - ClickConversion, - ClickConversionResult, - CustomVariable, - ExternalAttributionData, - SessionAttributeKeyValuePair, - SessionAttributesKeyValuePairs, - UploadCallConversionsRequest, - UploadCallConversionsResponse, - UploadClickConversionsRequest, - UploadClickConversionsResponse, -) -from .types.conversion_value_rule_service import ( - ConversionValueRuleOperation, - MutateConversionValueRuleResult, - MutateConversionValueRulesRequest, - MutateConversionValueRulesResponse, -) -from .types.conversion_value_rule_set_service import ( - ConversionValueRuleSetOperation, - MutateConversionValueRuleSetResult, - MutateConversionValueRuleSetsRequest, - MutateConversionValueRuleSetsResponse, -) -from .types.custom_audience_service import ( - CustomAudienceOperation, - MutateCustomAudienceResult, - MutateCustomAudiencesRequest, - MutateCustomAudiencesResponse, -) -from .types.custom_conversion_goal_service import ( - CustomConversionGoalOperation, - MutateCustomConversionGoalResult, - MutateCustomConversionGoalsRequest, - MutateCustomConversionGoalsResponse, -) -from .types.custom_interest_service import ( - CustomInterestOperation, - MutateCustomInterestResult, - MutateCustomInterestsRequest, - MutateCustomInterestsResponse, -) -from .types.customer_asset_service import ( - CustomerAssetOperation, - MutateCustomerAssetResult, - MutateCustomerAssetsRequest, - MutateCustomerAssetsResponse, -) -from .types.customer_asset_set_service import ( - CustomerAssetSetOperation, - MutateCustomerAssetSetResult, - MutateCustomerAssetSetsRequest, - MutateCustomerAssetSetsResponse, -) -from .types.customer_client_link_service import ( - CustomerClientLinkOperation, - MutateCustomerClientLinkRequest, - MutateCustomerClientLinkResponse, - MutateCustomerClientLinkResult, -) -from .types.customer_conversion_goal_service import ( - CustomerConversionGoalOperation, - MutateCustomerConversionGoalResult, - MutateCustomerConversionGoalsRequest, - MutateCustomerConversionGoalsResponse, -) -from .types.customer_customizer_service import ( - CustomerCustomizerOperation, - MutateCustomerCustomizerResult, - MutateCustomerCustomizersRequest, - MutateCustomerCustomizersResponse, -) -from .types.customer_label_service import ( - CustomerLabelOperation, - MutateCustomerLabelResult, - MutateCustomerLabelsRequest, - MutateCustomerLabelsResponse, -) -from .types.customer_lifecycle_goal_service import ( - ConfigureCustomerLifecycleGoalsRequest, - ConfigureCustomerLifecycleGoalsResponse, - ConfigureCustomerLifecycleGoalsResult, - CustomerLifecycleGoalOperation, -) -from .types.customer_manager_link_service import ( - CustomerManagerLinkOperation, - MoveManagerLinkRequest, - MoveManagerLinkResponse, - MutateCustomerManagerLinkRequest, - MutateCustomerManagerLinkResponse, - MutateCustomerManagerLinkResult, -) -from .types.customer_negative_criterion_service import ( - CustomerNegativeCriterionOperation, - MutateCustomerNegativeCriteriaRequest, - MutateCustomerNegativeCriteriaResponse, - MutateCustomerNegativeCriteriaResult, -) -from .types.customer_service import ( - CreateCustomerClientRequest, - CreateCustomerClientResponse, - CustomerOperation, - ListAccessibleCustomersRequest, - ListAccessibleCustomersResponse, - MutateCustomerRequest, - MutateCustomerResponse, - MutateCustomerResult, -) -from .types.customer_sk_ad_network_conversion_value_schema_service import ( - CustomerSkAdNetworkConversionValueSchemaOperation, - MutateCustomerSkAdNetworkConversionValueSchemaRequest, - MutateCustomerSkAdNetworkConversionValueSchemaResponse, - MutateCustomerSkAdNetworkConversionValueSchemaResult, -) -from .types.customer_user_access_invitation_service import ( - CustomerUserAccessInvitationOperation, - MutateCustomerUserAccessInvitationRequest, - MutateCustomerUserAccessInvitationResponse, - MutateCustomerUserAccessInvitationResult, -) -from .types.customer_user_access_service import ( - CustomerUserAccessOperation, - MutateCustomerUserAccessRequest, - MutateCustomerUserAccessResponse, - MutateCustomerUserAccessResult, -) -from .types.customizer_attribute_service import ( - CustomizerAttributeOperation, - MutateCustomizerAttributeResult, - MutateCustomizerAttributesRequest, - MutateCustomizerAttributesResponse, -) -from .types.data_link_service import ( - CreateDataLinkRequest, - CreateDataLinkResponse, - RemoveDataLinkRequest, - RemoveDataLinkResponse, - UpdateDataLinkRequest, - UpdateDataLinkResponse, -) -from .types.experiment_arm_service import ( - ExperimentArmOperation, - MutateExperimentArmResult, - MutateExperimentArmsRequest, - MutateExperimentArmsResponse, -) -from .types.experiment_service import ( - CampaignBudgetMapping, - EndExperimentRequest, - ExperimentOperation, - GraduateExperimentRequest, - ListExperimentAsyncErrorsRequest, - ListExperimentAsyncErrorsResponse, - MutateExperimentResult, - MutateExperimentsRequest, - MutateExperimentsResponse, - PromoteExperimentMetadata, - PromoteExperimentRequest, - ScheduleExperimentMetadata, - ScheduleExperimentRequest, -) -from .types.geo_target_constant_service import ( - GeoTargetConstantSuggestion, - SuggestGeoTargetConstantsRequest, - SuggestGeoTargetConstantsResponse, -) -from .types.google_ads_field_service import ( - GetGoogleAdsFieldRequest, - SearchGoogleAdsFieldsRequest, - SearchGoogleAdsFieldsResponse, -) -from .types.google_ads_service import ( - GoogleAdsRow, - MutateGoogleAdsRequest, - MutateGoogleAdsResponse, - MutateOperation, - MutateOperationResponse, - SearchGoogleAdsRequest, - SearchGoogleAdsResponse, - SearchGoogleAdsStreamRequest, - SearchGoogleAdsStreamResponse, - SearchSettings, -) -from .types.identity_verification_service import ( - GetIdentityVerificationRequest, - GetIdentityVerificationResponse, - IdentityVerification, - IdentityVerificationProgress, - IdentityVerificationRequirement, - StartIdentityVerificationRequest, -) -from .types.invoice_service import ( - ListInvoicesRequest, - ListInvoicesResponse, -) -from .types.keyword_plan_ad_group_keyword_service import ( - KeywordPlanAdGroupKeywordOperation, - MutateKeywordPlanAdGroupKeywordResult, - MutateKeywordPlanAdGroupKeywordsRequest, - MutateKeywordPlanAdGroupKeywordsResponse, -) -from .types.keyword_plan_ad_group_service import ( - KeywordPlanAdGroupOperation, - MutateKeywordPlanAdGroupResult, - MutateKeywordPlanAdGroupsRequest, - MutateKeywordPlanAdGroupsResponse, -) -from .types.keyword_plan_campaign_keyword_service import ( - KeywordPlanCampaignKeywordOperation, - MutateKeywordPlanCampaignKeywordResult, - MutateKeywordPlanCampaignKeywordsRequest, - MutateKeywordPlanCampaignKeywordsResponse, -) -from .types.keyword_plan_campaign_service import ( - KeywordPlanCampaignOperation, - MutateKeywordPlanCampaignResult, - MutateKeywordPlanCampaignsRequest, - MutateKeywordPlanCampaignsResponse, -) -from .types.keyword_plan_idea_service import ( - AdGroupKeywordSuggestion, - BiddableKeyword, - CampaignToForecast, - CriterionBidModifier, - ForecastAdGroup, - GenerateAdGroupThemesRequest, - GenerateAdGroupThemesResponse, - GenerateKeywordForecastMetricsRequest, - GenerateKeywordForecastMetricsResponse, - GenerateKeywordHistoricalMetricsRequest, - GenerateKeywordHistoricalMetricsResponse, - GenerateKeywordHistoricalMetricsResult, - GenerateKeywordIdeaResponse, - GenerateKeywordIdeaResult, - GenerateKeywordIdeasRequest, - KeywordAndUrlSeed, - KeywordForecastMetrics, - KeywordSeed, - ManualCpcBiddingStrategy, - MaximizeClicksBiddingStrategy, - MaximizeConversionsBiddingStrategy, - SiteSeed, - UnusableAdGroup, - UrlSeed, -) -from .types.keyword_plan_service import ( - KeywordPlanOperation, - MutateKeywordPlansRequest, - MutateKeywordPlansResponse, - MutateKeywordPlansResult, -) -from .types.keyword_theme_constant_service import ( - SuggestKeywordThemeConstantsRequest, - SuggestKeywordThemeConstantsResponse, -) -from .types.label_service import ( - LabelOperation, - MutateLabelResult, - MutateLabelsRequest, - MutateLabelsResponse, -) -from .types.local_services_lead_service import ( - AppendLeadConversationRequest, - AppendLeadConversationResponse, - Conversation, - ConversationOrError, - ProvideLeadFeedbackRequest, - ProvideLeadFeedbackResponse, - SurveyDissatisfied, - SurveySatisfied, -) -from .types.offline_user_data_job_service import ( - AddOfflineUserDataJobOperationsRequest, - AddOfflineUserDataJobOperationsResponse, - CreateOfflineUserDataJobRequest, - CreateOfflineUserDataJobResponse, - OfflineUserDataJobOperation, - RunOfflineUserDataJobRequest, -) -from .types.payments_account_service import ( - ListPaymentsAccountsRequest, - ListPaymentsAccountsResponse, -) -from .types.product_link_invitation_service import ( - CreateProductLinkInvitationRequest, - CreateProductLinkInvitationResponse, - RemoveProductLinkInvitationRequest, - RemoveProductLinkInvitationResponse, - UpdateProductLinkInvitationRequest, - UpdateProductLinkInvitationResponse, -) -from .types.product_link_service import ( - CreateProductLinkRequest, - CreateProductLinkResponse, - RemoveProductLinkRequest, - RemoveProductLinkResponse, -) -from .types.reach_plan_service import ( - AdvancedProductTargeting, - AudienceTargeting, - CampaignDuration, - ConversionRateSuggestion, - EffectiveFrequencyBreakdown, - EffectiveFrequencyLimit, - Forecast, - ForecastMetricOptions, - FrequencyCap, - GenerateConversionRatesRequest, - GenerateConversionRatesResponse, - GenerateReachForecastRequest, - GenerateReachForecastResponse, - ListPlannableLocationsRequest, - ListPlannableLocationsResponse, - ListPlannableProductsRequest, - ListPlannableProductsResponse, - OnTargetAudienceMetrics, - PlannableLocation, - PlannableTargeting, - PlannedProduct, - PlannedProductForecast, - PlannedProductReachForecast, - ProductMetadata, - ReachCurve, - ReachForecast, - SurfaceTargeting, - SurfaceTargetingCombinations, - TargetFrequencySettings, - Targeting, - YouTubeSelectLineUp, - YouTubeSelectSettings, -) -from .types.recommendation_service import ( - ApplyRecommendationOperation, - ApplyRecommendationRequest, - ApplyRecommendationResponse, - ApplyRecommendationResult, - DismissRecommendationRequest, - DismissRecommendationResponse, - GenerateRecommendationsRequest, - GenerateRecommendationsResponse, -) -from .types.recommendation_subscription_service import ( - MutateRecommendationSubscriptionRequest, - MutateRecommendationSubscriptionResponse, - MutateRecommendationSubscriptionResult, - RecommendationSubscriptionOperation, -) -from .types.remarketing_action_service import ( - MutateRemarketingActionResult, - MutateRemarketingActionsRequest, - MutateRemarketingActionsResponse, - RemarketingActionOperation, -) -from .types.shareable_preview_service import ( - AssetGroupIdentifier, - GenerateShareablePreviewsRequest, - GenerateShareablePreviewsResponse, - ShareablePreview, - ShareablePreviewOrError, - ShareablePreviewResult, -) -from .types.shared_criterion_service import ( - MutateSharedCriteriaRequest, - MutateSharedCriteriaResponse, - MutateSharedCriterionResult, - SharedCriterionOperation, -) -from .types.shared_set_service import ( - MutateSharedSetResult, - MutateSharedSetsRequest, - MutateSharedSetsResponse, - SharedSetOperation, -) -from .types.smart_campaign_setting_service import ( - GetSmartCampaignStatusRequest, - GetSmartCampaignStatusResponse, - MutateSmartCampaignSettingResult, - MutateSmartCampaignSettingsRequest, - MutateSmartCampaignSettingsResponse, - SmartCampaignEligibleDetails, - SmartCampaignEndedDetails, - SmartCampaignNotEligibleDetails, - SmartCampaignPausedDetails, - SmartCampaignRemovedDetails, - SmartCampaignSettingOperation, -) -from .types.smart_campaign_suggest_service import ( - SmartCampaignSuggestionInfo, - SuggestKeywordThemesRequest, - SuggestKeywordThemesResponse, - SuggestSmartCampaignAdRequest, - SuggestSmartCampaignAdResponse, - SuggestSmartCampaignBudgetOptionsRequest, - SuggestSmartCampaignBudgetOptionsResponse, -) -from .types.third_party_app_analytics_link_service import ( - RegenerateShareableLinkIdRequest, - RegenerateShareableLinkIdResponse, -) -from .types.travel_asset_suggestion_service import ( - HotelAssetSuggestion, - HotelImageAsset, - HotelTextAsset, - SuggestTravelAssetsRequest, - SuggestTravelAssetsResponse, -) -from .types.user_data_service import ( - UploadUserDataRequest, - UploadUserDataResponse, - UserDataOperation, -) -from .types.user_list_customer_type_service import ( - MutateUserListCustomerTypeResult, - MutateUserListCustomerTypesRequest, - MutateUserListCustomerTypesResponse, - UserListCustomerTypeOperation, -) -from .types.user_list_service import ( - MutateUserListResult, - MutateUserListsRequest, - MutateUserListsResponse, - UserListOperation, -) - -__all__ = ( - "AccountBudgetProposalOperation", - "MutateAccountBudgetProposalRequest", - "MutateAccountBudgetProposalResponse", - "MutateAccountBudgetProposalResult", - "AccountLinkOperation", - "CreateAccountLinkRequest", - "CreateAccountLinkResponse", - "MutateAccountLinkRequest", - "MutateAccountLinkResponse", - "MutateAccountLinkResult", - "AdGroupAdLabelOperation", - "MutateAdGroupAdLabelResult", - "MutateAdGroupAdLabelsRequest", - "MutateAdGroupAdLabelsResponse", - "AdGroupAdOperation", - "AssetsWithFieldType", - "MutateAdGroupAdResult", - "MutateAdGroupAdsRequest", - "MutateAdGroupAdsResponse", - "RemoveAutomaticallyCreatedAssetsRequest", - "AdGroupAssetOperation", - "MutateAdGroupAssetResult", - "MutateAdGroupAssetsRequest", - "MutateAdGroupAssetsResponse", - "AdGroupAssetSetOperation", - "MutateAdGroupAssetSetResult", - "MutateAdGroupAssetSetsRequest", - "MutateAdGroupAssetSetsResponse", - "AdGroupBidModifierOperation", - "MutateAdGroupBidModifierResult", - "MutateAdGroupBidModifiersRequest", - "MutateAdGroupBidModifiersResponse", - "AdGroupCriterionCustomizerOperation", - "MutateAdGroupCriterionCustomizerResult", - "MutateAdGroupCriterionCustomizersRequest", - "MutateAdGroupCriterionCustomizersResponse", - "AdGroupCriterionLabelOperation", - "MutateAdGroupCriterionLabelResult", - "MutateAdGroupCriterionLabelsRequest", - "MutateAdGroupCriterionLabelsResponse", - "AdGroupCriterionOperation", - "MutateAdGroupCriteriaRequest", - "MutateAdGroupCriteriaResponse", - "MutateAdGroupCriterionResult", - "AdGroupCustomizerOperation", - "MutateAdGroupCustomizerResult", - "MutateAdGroupCustomizersRequest", - "MutateAdGroupCustomizersResponse", - "AdGroupLabelOperation", - "MutateAdGroupLabelResult", - "MutateAdGroupLabelsRequest", - "MutateAdGroupLabelsResponse", - "AdGroupOperation", - "MutateAdGroupResult", - "MutateAdGroupsRequest", - "MutateAdGroupsResponse", - "AdParameterOperation", - "MutateAdParameterResult", - "MutateAdParametersRequest", - "MutateAdParametersResponse", - "AdOperation", - "MutateAdResult", - "MutateAdsRequest", - "MutateAdsResponse", - "AssetGroupAssetOperation", - "MutateAssetGroupAssetResult", - "MutateAssetGroupAssetsRequest", - "MutateAssetGroupAssetsResponse", - "AssetGroupListingGroupFilterOperation", - "MutateAssetGroupListingGroupFilterResult", - "MutateAssetGroupListingGroupFiltersRequest", - "MutateAssetGroupListingGroupFiltersResponse", - "AssetGroupOperation", - "MutateAssetGroupResult", - "MutateAssetGroupsRequest", - "MutateAssetGroupsResponse", - "AssetGroupSignalOperation", - "MutateAssetGroupSignalResult", - "MutateAssetGroupSignalsRequest", - "MutateAssetGroupSignalsResponse", - "AssetOperation", - "MutateAssetResult", - "MutateAssetsRequest", - "MutateAssetsResponse", - "AssetSetAssetOperation", - "MutateAssetSetAssetResult", - "MutateAssetSetAssetsRequest", - "MutateAssetSetAssetsResponse", - "AssetSetOperation", - "MutateAssetSetResult", - "MutateAssetSetsRequest", - "MutateAssetSetsResponse", - "AudienceCompositionAttribute", - "AudienceCompositionAttributeCluster", - "AudienceCompositionMetrics", - "AudienceCompositionSection", - "AudienceOverlapItem", - "BasicInsightsAudience", - "DimensionOverlapResult", - "GenerateAudienceCompositionInsightsRequest", - "GenerateAudienceCompositionInsightsResponse", - "GenerateAudienceOverlapInsightsRequest", - "GenerateAudienceOverlapInsightsResponse", - "GenerateInsightsFinderReportRequest", - "GenerateInsightsFinderReportResponse", - "GenerateSuggestedTargetingInsightsRequest", - "GenerateSuggestedTargetingInsightsResponse", - "GenerateTargetingSuggestionMetricsRequest", - "GenerateTargetingSuggestionMetricsResponse", - "InsightsAudience", - "InsightsAudienceAttributeGroup", - "InsightsAudienceDefinition", - "InsightsAudienceDescription", - "ListAudienceInsightsAttributesRequest", - "ListAudienceInsightsAttributesResponse", - "ListInsightsEligibleDatesRequest", - "ListInsightsEligibleDatesResponse", - "TargetingSuggestionMetrics", - "AudienceOperation", - "MutateAudienceResult", - "MutateAudiencesRequest", - "MutateAudiencesResponse", - "AddBatchJobOperationsRequest", - "AddBatchJobOperationsResponse", - "BatchJobOperation", - "BatchJobResult", - "ListBatchJobResultsRequest", - "ListBatchJobResultsResponse", - "MutateBatchJobRequest", - "MutateBatchJobResponse", - "MutateBatchJobResult", - "RunBatchJobRequest", - "BiddingDataExclusionOperation", - "MutateBiddingDataExclusionsRequest", - "MutateBiddingDataExclusionsResponse", - "MutateBiddingDataExclusionsResult", - "BiddingSeasonalityAdjustmentOperation", - "MutateBiddingSeasonalityAdjustmentsRequest", - "MutateBiddingSeasonalityAdjustmentsResponse", - "MutateBiddingSeasonalityAdjustmentsResult", - "BiddingStrategyOperation", - "MutateBiddingStrategiesRequest", - "MutateBiddingStrategiesResponse", - "MutateBiddingStrategyResult", - "BillingSetupOperation", - "MutateBillingSetupRequest", - "MutateBillingSetupResponse", - "MutateBillingSetupResult", - "BrandSuggestion", - "SuggestBrandsRequest", - "SuggestBrandsResponse", - "CampaignAssetOperation", - "MutateCampaignAssetResult", - "MutateCampaignAssetsRequest", - "MutateCampaignAssetsResponse", - "CampaignAssetSetOperation", - "MutateCampaignAssetSetResult", - "MutateCampaignAssetSetsRequest", - "MutateCampaignAssetSetsResponse", - "CampaignBidModifierOperation", - "MutateCampaignBidModifierResult", - "MutateCampaignBidModifiersRequest", - "MutateCampaignBidModifiersResponse", - "CampaignBudgetOperation", - "MutateCampaignBudgetResult", - "MutateCampaignBudgetsRequest", - "MutateCampaignBudgetsResponse", - "CampaignConversionGoalOperation", - "MutateCampaignConversionGoalResult", - "MutateCampaignConversionGoalsRequest", - "MutateCampaignConversionGoalsResponse", - "CampaignCriterionOperation", - "MutateCampaignCriteriaRequest", - "MutateCampaignCriteriaResponse", - "MutateCampaignCriterionResult", - "CampaignCustomizerOperation", - "MutateCampaignCustomizerResult", - "MutateCampaignCustomizersRequest", - "MutateCampaignCustomizersResponse", - "CampaignDraftOperation", - "ListCampaignDraftAsyncErrorsRequest", - "ListCampaignDraftAsyncErrorsResponse", - "MutateCampaignDraftResult", - "MutateCampaignDraftsRequest", - "MutateCampaignDraftsResponse", - "PromoteCampaignDraftRequest", - "CampaignGroupOperation", - "MutateCampaignGroupResult", - "MutateCampaignGroupsRequest", - "MutateCampaignGroupsResponse", - "CampaignLabelOperation", - "MutateCampaignLabelResult", - "MutateCampaignLabelsRequest", - "MutateCampaignLabelsResponse", - "CampaignLifecycleGoalOperation", - "ConfigureCampaignLifecycleGoalsRequest", - "ConfigureCampaignLifecycleGoalsResponse", - "ConfigureCampaignLifecycleGoalsResult", - "BrandCampaignAssets", - "CampaignOperation", - "EnablementResult", - "EnableOperation", - "EnablePMaxBrandGuidelinesRequest", - "EnablePMaxBrandGuidelinesResponse", - "MutateCampaignResult", - "MutateCampaignsRequest", - "MutateCampaignsResponse", - "CampaignSharedSetOperation", - "MutateCampaignSharedSetResult", - "MutateCampaignSharedSetsRequest", - "MutateCampaignSharedSetsResponse", - "GenerateCreatorInsightsRequest", - "GenerateCreatorInsightsResponse", - "GenerateTrendingInsightsRequest", - "GenerateTrendingInsightsResponse", - "SearchAudience", - "SearchTopics", - "TrendInsight", - "TrendInsightMetrics", - "YouTubeChannelInsights", - "YouTubeCreatorInsights", - "YouTubeMetrics", - "ConversionActionOperation", - "MutateConversionActionResult", - "MutateConversionActionsRequest", - "MutateConversionActionsResponse", - "ConversionAdjustment", - "ConversionAdjustmentResult", - "GclidDateTimePair", - "RestatementValue", - "UploadConversionAdjustmentsRequest", - "UploadConversionAdjustmentsResponse", - "ConversionCustomVariableOperation", - "MutateConversionCustomVariableResult", - "MutateConversionCustomVariablesRequest", - "MutateConversionCustomVariablesResponse", - "ConversionGoalCampaignConfigOperation", - "MutateConversionGoalCampaignConfigResult", - "MutateConversionGoalCampaignConfigsRequest", - "MutateConversionGoalCampaignConfigsResponse", - "CallConversion", - "CallConversionResult", - "CartData", - "ClickConversion", - "ClickConversionResult", - "CustomVariable", - "ExternalAttributionData", - "SessionAttributeKeyValuePair", - "SessionAttributesKeyValuePairs", - "UploadCallConversionsRequest", - "UploadCallConversionsResponse", - "UploadClickConversionsRequest", - "UploadClickConversionsResponse", - "ConversionValueRuleOperation", - "MutateConversionValueRuleResult", - "MutateConversionValueRulesRequest", - "MutateConversionValueRulesResponse", - "ConversionValueRuleSetOperation", - "MutateConversionValueRuleSetResult", - "MutateConversionValueRuleSetsRequest", - "MutateConversionValueRuleSetsResponse", - "CustomAudienceOperation", - "MutateCustomAudienceResult", - "MutateCustomAudiencesRequest", - "MutateCustomAudiencesResponse", - "CustomConversionGoalOperation", - "MutateCustomConversionGoalResult", - "MutateCustomConversionGoalsRequest", - "MutateCustomConversionGoalsResponse", - "CustomInterestOperation", - "MutateCustomInterestResult", - "MutateCustomInterestsRequest", - "MutateCustomInterestsResponse", - "CustomerAssetOperation", - "MutateCustomerAssetResult", - "MutateCustomerAssetsRequest", - "MutateCustomerAssetsResponse", - "CustomerAssetSetOperation", - "MutateCustomerAssetSetResult", - "MutateCustomerAssetSetsRequest", - "MutateCustomerAssetSetsResponse", - "CustomerClientLinkOperation", - "MutateCustomerClientLinkRequest", - "MutateCustomerClientLinkResponse", - "MutateCustomerClientLinkResult", - "CustomerConversionGoalOperation", - "MutateCustomerConversionGoalResult", - "MutateCustomerConversionGoalsRequest", - "MutateCustomerConversionGoalsResponse", - "CustomerCustomizerOperation", - "MutateCustomerCustomizerResult", - "MutateCustomerCustomizersRequest", - "MutateCustomerCustomizersResponse", - "CustomerLabelOperation", - "MutateCustomerLabelResult", - "MutateCustomerLabelsRequest", - "MutateCustomerLabelsResponse", - "ConfigureCustomerLifecycleGoalsRequest", - "ConfigureCustomerLifecycleGoalsResponse", - "ConfigureCustomerLifecycleGoalsResult", - "CustomerLifecycleGoalOperation", - "CustomerManagerLinkOperation", - "MoveManagerLinkRequest", - "MoveManagerLinkResponse", - "MutateCustomerManagerLinkRequest", - "MutateCustomerManagerLinkResponse", - "MutateCustomerManagerLinkResult", - "CustomerNegativeCriterionOperation", - "MutateCustomerNegativeCriteriaRequest", - "MutateCustomerNegativeCriteriaResponse", - "MutateCustomerNegativeCriteriaResult", - "CreateCustomerClientRequest", - "CreateCustomerClientResponse", - "CustomerOperation", - "ListAccessibleCustomersRequest", - "ListAccessibleCustomersResponse", - "MutateCustomerRequest", - "MutateCustomerResponse", - "MutateCustomerResult", - "CustomerSkAdNetworkConversionValueSchemaOperation", - "MutateCustomerSkAdNetworkConversionValueSchemaRequest", - "MutateCustomerSkAdNetworkConversionValueSchemaResponse", - "MutateCustomerSkAdNetworkConversionValueSchemaResult", - "CustomerUserAccessInvitationOperation", - "MutateCustomerUserAccessInvitationRequest", - "MutateCustomerUserAccessInvitationResponse", - "MutateCustomerUserAccessInvitationResult", - "CustomerUserAccessOperation", - "MutateCustomerUserAccessRequest", - "MutateCustomerUserAccessResponse", - "MutateCustomerUserAccessResult", - "CustomizerAttributeOperation", - "MutateCustomizerAttributeResult", - "MutateCustomizerAttributesRequest", - "MutateCustomizerAttributesResponse", - "CreateDataLinkRequest", - "CreateDataLinkResponse", - "RemoveDataLinkRequest", - "RemoveDataLinkResponse", - "UpdateDataLinkRequest", - "UpdateDataLinkResponse", - "ExperimentArmOperation", - "MutateExperimentArmResult", - "MutateExperimentArmsRequest", - "MutateExperimentArmsResponse", - "CampaignBudgetMapping", - "EndExperimentRequest", - "ExperimentOperation", - "GraduateExperimentRequest", - "ListExperimentAsyncErrorsRequest", - "ListExperimentAsyncErrorsResponse", - "MutateExperimentResult", - "MutateExperimentsRequest", - "MutateExperimentsResponse", - "PromoteExperimentMetadata", - "PromoteExperimentRequest", - "ScheduleExperimentMetadata", - "ScheduleExperimentRequest", - "GeoTargetConstantSuggestion", - "SuggestGeoTargetConstantsRequest", - "SuggestGeoTargetConstantsResponse", - "GetGoogleAdsFieldRequest", - "SearchGoogleAdsFieldsRequest", - "SearchGoogleAdsFieldsResponse", - "GoogleAdsRow", - "MutateGoogleAdsRequest", - "MutateGoogleAdsResponse", - "MutateOperation", - "MutateOperationResponse", - "SearchGoogleAdsRequest", - "SearchGoogleAdsResponse", - "SearchGoogleAdsStreamRequest", - "SearchGoogleAdsStreamResponse", - "SearchSettings", - "GetIdentityVerificationRequest", - "GetIdentityVerificationResponse", - "IdentityVerification", - "IdentityVerificationProgress", - "IdentityVerificationRequirement", - "StartIdentityVerificationRequest", - "ListInvoicesRequest", - "ListInvoicesResponse", - "KeywordPlanAdGroupKeywordOperation", - "MutateKeywordPlanAdGroupKeywordResult", - "MutateKeywordPlanAdGroupKeywordsRequest", - "MutateKeywordPlanAdGroupKeywordsResponse", - "KeywordPlanAdGroupOperation", - "MutateKeywordPlanAdGroupResult", - "MutateKeywordPlanAdGroupsRequest", - "MutateKeywordPlanAdGroupsResponse", - "KeywordPlanCampaignKeywordOperation", - "MutateKeywordPlanCampaignKeywordResult", - "MutateKeywordPlanCampaignKeywordsRequest", - "MutateKeywordPlanCampaignKeywordsResponse", - "KeywordPlanCampaignOperation", - "MutateKeywordPlanCampaignResult", - "MutateKeywordPlanCampaignsRequest", - "MutateKeywordPlanCampaignsResponse", - "AdGroupKeywordSuggestion", - "BiddableKeyword", - "CampaignToForecast", - "CriterionBidModifier", - "ForecastAdGroup", - "GenerateAdGroupThemesRequest", - "GenerateAdGroupThemesResponse", - "GenerateKeywordForecastMetricsRequest", - "GenerateKeywordForecastMetricsResponse", - "GenerateKeywordHistoricalMetricsRequest", - "GenerateKeywordHistoricalMetricsResponse", - "GenerateKeywordHistoricalMetricsResult", - "GenerateKeywordIdeaResponse", - "GenerateKeywordIdeaResult", - "GenerateKeywordIdeasRequest", - "KeywordAndUrlSeed", - "KeywordForecastMetrics", - "KeywordSeed", - "ManualCpcBiddingStrategy", - "MaximizeClicksBiddingStrategy", - "MaximizeConversionsBiddingStrategy", - "SiteSeed", - "UnusableAdGroup", - "UrlSeed", - "KeywordPlanOperation", - "MutateKeywordPlansRequest", - "MutateKeywordPlansResponse", - "MutateKeywordPlansResult", - "SuggestKeywordThemeConstantsRequest", - "SuggestKeywordThemeConstantsResponse", - "LabelOperation", - "MutateLabelResult", - "MutateLabelsRequest", - "MutateLabelsResponse", - "AppendLeadConversationRequest", - "AppendLeadConversationResponse", - "Conversation", - "ConversationOrError", - "ProvideLeadFeedbackRequest", - "ProvideLeadFeedbackResponse", - "SurveyDissatisfied", - "SurveySatisfied", - "AddOfflineUserDataJobOperationsRequest", - "AddOfflineUserDataJobOperationsResponse", - "CreateOfflineUserDataJobRequest", - "CreateOfflineUserDataJobResponse", - "OfflineUserDataJobOperation", - "RunOfflineUserDataJobRequest", - "ListPaymentsAccountsRequest", - "ListPaymentsAccountsResponse", - "CreateProductLinkInvitationRequest", - "CreateProductLinkInvitationResponse", - "RemoveProductLinkInvitationRequest", - "RemoveProductLinkInvitationResponse", - "UpdateProductLinkInvitationRequest", - "UpdateProductLinkInvitationResponse", - "CreateProductLinkRequest", - "CreateProductLinkResponse", - "RemoveProductLinkRequest", - "RemoveProductLinkResponse", - "AdvancedProductTargeting", - "AudienceTargeting", - "CampaignDuration", - "ConversionRateSuggestion", - "EffectiveFrequencyBreakdown", - "EffectiveFrequencyLimit", - "Forecast", - "ForecastMetricOptions", - "FrequencyCap", - "GenerateConversionRatesRequest", - "GenerateConversionRatesResponse", - "GenerateReachForecastRequest", - "GenerateReachForecastResponse", - "ListPlannableLocationsRequest", - "ListPlannableLocationsResponse", - "ListPlannableProductsRequest", - "ListPlannableProductsResponse", - "OnTargetAudienceMetrics", - "PlannableLocation", - "PlannableTargeting", - "PlannedProduct", - "PlannedProductForecast", - "PlannedProductReachForecast", - "ProductMetadata", - "ReachCurve", - "ReachForecast", - "SurfaceTargeting", - "SurfaceTargetingCombinations", - "TargetFrequencySettings", - "Targeting", - "YouTubeSelectLineUp", - "YouTubeSelectSettings", - "ApplyRecommendationOperation", - "ApplyRecommendationRequest", - "ApplyRecommendationResponse", - "ApplyRecommendationResult", - "DismissRecommendationRequest", - "DismissRecommendationResponse", - "GenerateRecommendationsRequest", - "GenerateRecommendationsResponse", - "MutateRecommendationSubscriptionRequest", - "MutateRecommendationSubscriptionResponse", - "MutateRecommendationSubscriptionResult", - "RecommendationSubscriptionOperation", - "MutateRemarketingActionResult", - "MutateRemarketingActionsRequest", - "MutateRemarketingActionsResponse", - "RemarketingActionOperation", - "AssetGroupIdentifier", - "GenerateShareablePreviewsRequest", - "GenerateShareablePreviewsResponse", - "ShareablePreview", - "ShareablePreviewOrError", - "ShareablePreviewResult", - "MutateSharedCriteriaRequest", - "MutateSharedCriteriaResponse", - "MutateSharedCriterionResult", - "SharedCriterionOperation", - "MutateSharedSetResult", - "MutateSharedSetsRequest", - "MutateSharedSetsResponse", - "SharedSetOperation", - "GetSmartCampaignStatusRequest", - "GetSmartCampaignStatusResponse", - "MutateSmartCampaignSettingResult", - "MutateSmartCampaignSettingsRequest", - "MutateSmartCampaignSettingsResponse", - "SmartCampaignEligibleDetails", - "SmartCampaignEndedDetails", - "SmartCampaignNotEligibleDetails", - "SmartCampaignPausedDetails", - "SmartCampaignRemovedDetails", - "SmartCampaignSettingOperation", - "SmartCampaignSuggestionInfo", - "SuggestKeywordThemesRequest", - "SuggestKeywordThemesResponse", - "SuggestSmartCampaignAdRequest", - "SuggestSmartCampaignAdResponse", - "SuggestSmartCampaignBudgetOptionsRequest", - "SuggestSmartCampaignBudgetOptionsResponse", - "RegenerateShareableLinkIdRequest", - "RegenerateShareableLinkIdResponse", - "HotelAssetSuggestion", - "HotelImageAsset", - "HotelTextAsset", - "SuggestTravelAssetsRequest", - "SuggestTravelAssetsResponse", - "UploadUserDataRequest", - "UploadUserDataResponse", - "UserDataOperation", - "MutateUserListCustomerTypeResult", - "MutateUserListCustomerTypesRequest", - "MutateUserListCustomerTypesResponse", - "UserListCustomerTypeOperation", - "MutateUserListResult", - "MutateUserListsRequest", - "MutateUserListsResponse", - "UserListOperation", -) diff --git a/google/ads/googleads/v19/services/services/account_budget_proposal_service/async_client.py b/google/ads/googleads/v19/services/services/account_budget_proposal_service/async_client.py deleted file mode 100644 index 8a4f76b4f..000000000 --- a/google/ads/googleads/v19/services/services/account_budget_proposal_service/async_client.py +++ /dev/null @@ -1,458 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - account_budget_proposal_service, -) -from .transports.base import ( - AccountBudgetProposalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import AccountBudgetProposalServiceClient - -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 AccountBudgetProposalServiceAsyncClient: - """A service for managing account-level budgets through - proposals. - A proposal is a request to create a new budget or make changes - to an existing one. - - Mutates: - - The CREATE operation creates a new proposal. - UPDATE operations aren't supported. - The REMOVE operation cancels a pending proposal. - """ - - _client: AccountBudgetProposalServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AccountBudgetProposalServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - AccountBudgetProposalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - AccountBudgetProposalServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AccountBudgetProposalServiceClient._DEFAULT_UNIVERSE - - account_budget_path = staticmethod( - AccountBudgetProposalServiceClient.account_budget_path - ) - parse_account_budget_path = staticmethod( - AccountBudgetProposalServiceClient.parse_account_budget_path - ) - account_budget_proposal_path = staticmethod( - AccountBudgetProposalServiceClient.account_budget_proposal_path - ) - parse_account_budget_proposal_path = staticmethod( - AccountBudgetProposalServiceClient.parse_account_budget_proposal_path - ) - billing_setup_path = staticmethod( - AccountBudgetProposalServiceClient.billing_setup_path - ) - parse_billing_setup_path = staticmethod( - AccountBudgetProposalServiceClient.parse_billing_setup_path - ) - common_billing_account_path = staticmethod( - AccountBudgetProposalServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AccountBudgetProposalServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AccountBudgetProposalServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AccountBudgetProposalServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AccountBudgetProposalServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AccountBudgetProposalServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AccountBudgetProposalServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AccountBudgetProposalServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AccountBudgetProposalServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AccountBudgetProposalServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AccountBudgetProposalServiceAsyncClient: The constructed client. - """ - return AccountBudgetProposalServiceClient.from_service_account_info.__func__(AccountBudgetProposalServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AccountBudgetProposalServiceAsyncClient: The constructed client. - """ - return AccountBudgetProposalServiceClient.from_service_account_file.__func__(AccountBudgetProposalServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AccountBudgetProposalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AccountBudgetProposalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AccountBudgetProposalServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AccountBudgetProposalServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AccountBudgetProposalServiceTransport, - Callable[..., AccountBudgetProposalServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the account budget proposal service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AccountBudgetProposalServiceTransport,Callable[..., AccountBudgetProposalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AccountBudgetProposalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AccountBudgetProposalServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AccountBudgetProposalServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AccountBudgetProposalService", - "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.ads.googleads.v19.services.AccountBudgetProposalService", - "credentialsType": None, - } - ), - ) - - async def mutate_account_budget_proposal( - self, - request: Optional[ - Union[ - account_budget_proposal_service.MutateAccountBudgetProposalRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - account_budget_proposal_service.AccountBudgetProposalOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> account_budget_proposal_service.MutateAccountBudgetProposalResponse: - r"""Creates, updates, or removes account budget proposals. Operation - statuses are returned. - - List of thrown errors: `AccountBudgetProposalError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `DatabaseError <>`__ `DateError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAccountBudgetProposalRequest, dict]]): - The request object. Request message for - [AccountBudgetProposalService.MutateAccountBudgetProposal][google.ads.googleads.v19.services.AccountBudgetProposalService.MutateAccountBudgetProposal]. - customer_id (:class:`str`): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (:class:`google.ads.googleads.v19.services.types.AccountBudgetProposalOperation`): - Required. The operation to perform on - an individual account-level budget - proposal. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAccountBudgetProposalResponse: - Response message for account-level - budget mutate operations. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - account_budget_proposal_service.MutateAccountBudgetProposalRequest, - ): - request = account_budget_proposal_service.MutateAccountBudgetProposalRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_account_budget_proposal - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AccountBudgetProposalServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AccountBudgetProposalServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/account_budget_proposal_service/client.py b/google/ads/googleads/v19/services/services/account_budget_proposal_service/client.py deleted file mode 100644 index fe32d138c..000000000 --- a/google/ads/googleads/v19/services/services/account_budget_proposal_service/client.py +++ /dev/null @@ -1,945 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - account_budget_proposal_service, -) -from .transports.base import ( - AccountBudgetProposalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import AccountBudgetProposalServiceGrpcTransport -from .transports.grpc_asyncio import ( - AccountBudgetProposalServiceGrpcAsyncIOTransport, -) - - -class AccountBudgetProposalServiceClientMeta(type): - """Metaclass for the AccountBudgetProposalService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AccountBudgetProposalServiceTransport]] - _transport_registry["grpc"] = AccountBudgetProposalServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AccountBudgetProposalServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AccountBudgetProposalServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AccountBudgetProposalServiceClient( - metaclass=AccountBudgetProposalServiceClientMeta -): - """A service for managing account-level budgets through - proposals. - A proposal is a request to create a new budget or make changes - to an existing one. - - Mutates: - - The CREATE operation creates a new proposal. - UPDATE operations aren't supported. - The REMOVE operation cancels a pending proposal. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AccountBudgetProposalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AccountBudgetProposalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AccountBudgetProposalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AccountBudgetProposalServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def account_budget_path( - customer_id: str, - account_budget_id: str, - ) -> str: - """Returns a fully-qualified account_budget string.""" - return ( - "customers/{customer_id}/accountBudgets/{account_budget_id}".format( - customer_id=customer_id, - account_budget_id=account_budget_id, - ) - ) - - @staticmethod - def parse_account_budget_path(path: str) -> Dict[str, str]: - """Parses a account_budget path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/accountBudgets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def account_budget_proposal_path( - customer_id: str, - account_budget_proposal_id: str, - ) -> str: - """Returns a fully-qualified account_budget_proposal string.""" - return "customers/{customer_id}/accountBudgetProposals/{account_budget_proposal_id}".format( - customer_id=customer_id, - account_budget_proposal_id=account_budget_proposal_id, - ) - - @staticmethod - def parse_account_budget_proposal_path(path: str) -> Dict[str, str]: - """Parses a account_budget_proposal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/accountBudgetProposals/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def billing_setup_path( - customer_id: str, - billing_setup_id: str, - ) -> str: - """Returns a fully-qualified billing_setup string.""" - return ( - "customers/{customer_id}/billingSetups/{billing_setup_id}".format( - customer_id=customer_id, - billing_setup_id=billing_setup_id, - ) - ) - - @staticmethod - def parse_billing_setup_path(path: str) -> Dict[str, str]: - """Parses a billing_setup path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/billingSetups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - AccountBudgetProposalServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - AccountBudgetProposalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = AccountBudgetProposalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AccountBudgetProposalServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AccountBudgetProposalServiceTransport, - Callable[..., AccountBudgetProposalServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the account budget proposal service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AccountBudgetProposalServiceTransport,Callable[..., AccountBudgetProposalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AccountBudgetProposalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AccountBudgetProposalServiceClient._read_environment_variables() - self._client_cert_source = ( - AccountBudgetProposalServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AccountBudgetProposalServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AccountBudgetProposalServiceTransport - ) - if transport_provided: - # transport is a AccountBudgetProposalServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - AccountBudgetProposalServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AccountBudgetProposalServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AccountBudgetProposalServiceTransport], - Callable[..., AccountBudgetProposalServiceTransport], - ] = ( - AccountBudgetProposalServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AccountBudgetProposalServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AccountBudgetProposalServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AccountBudgetProposalService", - "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.ads.googleads.v19.services.AccountBudgetProposalService", - "credentialsType": None, - } - ), - ) - - def mutate_account_budget_proposal( - self, - request: Optional[ - Union[ - account_budget_proposal_service.MutateAccountBudgetProposalRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - account_budget_proposal_service.AccountBudgetProposalOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> account_budget_proposal_service.MutateAccountBudgetProposalResponse: - r"""Creates, updates, or removes account budget proposals. Operation - statuses are returned. - - List of thrown errors: `AccountBudgetProposalError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `DatabaseError <>`__ `DateError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAccountBudgetProposalRequest, dict]): - The request object. Request message for - [AccountBudgetProposalService.MutateAccountBudgetProposal][google.ads.googleads.v19.services.AccountBudgetProposalService.MutateAccountBudgetProposal]. - customer_id (str): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (google.ads.googleads.v19.services.types.AccountBudgetProposalOperation): - Required. The operation to perform on - an individual account-level budget - proposal. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAccountBudgetProposalResponse: - Response message for account-level - budget mutate operations. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - account_budget_proposal_service.MutateAccountBudgetProposalRequest, - ): - request = account_budget_proposal_service.MutateAccountBudgetProposalRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_account_budget_proposal - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AccountBudgetProposalServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AccountBudgetProposalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/base.py b/google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/base.py deleted file mode 100644 index de9fa82d5..000000000 --- a/google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - account_budget_proposal_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AccountBudgetProposalServiceTransport(abc.ABC): - """Abstract transport class for AccountBudgetProposalService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_account_budget_proposal: gapic_v1.method.wrap_method( - self.mutate_account_budget_proposal, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_account_budget_proposal( - self, - ) -> Callable[ - [account_budget_proposal_service.MutateAccountBudgetProposalRequest], - Union[ - account_budget_proposal_service.MutateAccountBudgetProposalResponse, - Awaitable[ - account_budget_proposal_service.MutateAccountBudgetProposalResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AccountBudgetProposalServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/grpc.py b/google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/grpc.py deleted file mode 100644 index 41138da41..000000000 --- a/google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/grpc.py +++ /dev/null @@ -1,402 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - account_budget_proposal_service, -) -from .base import AccountBudgetProposalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AccountBudgetProposalService", - "rpcName": str(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.ads.googleads.v19.services.AccountBudgetProposalService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AccountBudgetProposalServiceGrpcTransport( - AccountBudgetProposalServiceTransport -): - """gRPC backend transport for AccountBudgetProposalService. - - A service for managing account-level budgets through - proposals. - A proposal is a request to create a new budget or make changes - to an existing one. - - Mutates: - - The CREATE operation creates a new proposal. - UPDATE operations aren't supported. - The REMOVE operation cancels a pending proposal. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_account_budget_proposal( - self, - ) -> Callable[ - [account_budget_proposal_service.MutateAccountBudgetProposalRequest], - account_budget_proposal_service.MutateAccountBudgetProposalResponse, - ]: - r"""Return a callable for the mutate account budget proposal method over gRPC. - - Creates, updates, or removes account budget proposals. Operation - statuses are returned. - - List of thrown errors: `AccountBudgetProposalError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `DatabaseError <>`__ `DateError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `StringLengthError <>`__ - - Returns: - Callable[[~.MutateAccountBudgetProposalRequest], - ~.MutateAccountBudgetProposalResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_account_budget_proposal" not in self._stubs: - self._stubs["mutate_account_budget_proposal"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AccountBudgetProposalService/MutateAccountBudgetProposal", - request_serializer=account_budget_proposal_service.MutateAccountBudgetProposalRequest.serialize, - response_deserializer=account_budget_proposal_service.MutateAccountBudgetProposalResponse.deserialize, - ) - ) - return self._stubs["mutate_account_budget_proposal"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AccountBudgetProposalServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/grpc_asyncio.py deleted file mode 100644 index 771c066cd..000000000 --- a/google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,425 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - account_budget_proposal_service, -) -from .base import AccountBudgetProposalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AccountBudgetProposalService", - "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.ads.googleads.v19.services.AccountBudgetProposalService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AccountBudgetProposalServiceGrpcAsyncIOTransport( - AccountBudgetProposalServiceTransport -): - """gRPC AsyncIO backend transport for AccountBudgetProposalService. - - A service for managing account-level budgets through - proposals. - A proposal is a request to create a new budget or make changes - to an existing one. - - Mutates: - - The CREATE operation creates a new proposal. - UPDATE operations aren't supported. - The REMOVE operation cancels a pending proposal. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_account_budget_proposal( - self, - ) -> Callable[ - [account_budget_proposal_service.MutateAccountBudgetProposalRequest], - Awaitable[ - account_budget_proposal_service.MutateAccountBudgetProposalResponse - ], - ]: - r"""Return a callable for the mutate account budget proposal method over gRPC. - - Creates, updates, or removes account budget proposals. Operation - statuses are returned. - - List of thrown errors: `AccountBudgetProposalError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `DatabaseError <>`__ `DateError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `StringLengthError <>`__ - - Returns: - Callable[[~.MutateAccountBudgetProposalRequest], - Awaitable[~.MutateAccountBudgetProposalResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_account_budget_proposal" not in self._stubs: - self._stubs["mutate_account_budget_proposal"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AccountBudgetProposalService/MutateAccountBudgetProposal", - request_serializer=account_budget_proposal_service.MutateAccountBudgetProposalRequest.serialize, - response_deserializer=account_budget_proposal_service.MutateAccountBudgetProposalResponse.deserialize, - ) - ) - return self._stubs["mutate_account_budget_proposal"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_account_budget_proposal: self._wrap_method( - self.mutate_account_budget_proposal, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AccountBudgetProposalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/account_link_service/async_client.py b/google/ads/googleads/v19/services/services/account_link_service/async_client.py deleted file mode 100644 index a85c5bd73..000000000 --- a/google/ads/googleads/v19/services/services/account_link_service/async_client.py +++ /dev/null @@ -1,532 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.resources.types import ( - account_link as gagr_account_link, -) -from google.ads.googleads.v19.services.types import account_link_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AccountLinkServiceTransport, DEFAULT_CLIENT_INFO -from .client import AccountLinkServiceClient - -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 AccountLinkServiceAsyncClient: - """This service allows management of links between Google Ads - accounts and other accounts. - """ - - _client: AccountLinkServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AccountLinkServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AccountLinkServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AccountLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AccountLinkServiceClient._DEFAULT_UNIVERSE - - account_link_path = staticmethod(AccountLinkServiceClient.account_link_path) - parse_account_link_path = staticmethod( - AccountLinkServiceClient.parse_account_link_path - ) - common_billing_account_path = staticmethod( - AccountLinkServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AccountLinkServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AccountLinkServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AccountLinkServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AccountLinkServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AccountLinkServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AccountLinkServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AccountLinkServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AccountLinkServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AccountLinkServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AccountLinkServiceAsyncClient: The constructed client. - """ - return AccountLinkServiceClient.from_service_account_info.__func__(AccountLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AccountLinkServiceAsyncClient: The constructed client. - """ - return AccountLinkServiceClient.from_service_account_file.__func__(AccountLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AccountLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AccountLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AccountLinkServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AccountLinkServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AccountLinkServiceTransport, - Callable[..., AccountLinkServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the account link service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AccountLinkServiceTransport,Callable[..., AccountLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AccountLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AccountLinkServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AccountLinkServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AccountLinkService", - "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.ads.googleads.v19.services.AccountLinkService", - "credentialsType": None, - } - ), - ) - - async def create_account_link( - self, - request: Optional[ - Union[account_link_service.CreateAccountLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - account_link: Optional[gagr_account_link.AccountLink] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> account_link_service.CreateAccountLinkResponse: - r"""Creates an account link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ThirdPartyAppAnalyticsLinkError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.CreateAccountLinkRequest, dict]]): - The request object. Request message for - [AccountLinkService.CreateAccountLink][google.ads.googleads.v19.services.AccountLinkService.CreateAccountLink]. - customer_id (:class:`str`): - Required. The ID of the customer for - which the account link is created. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - account_link (:class:`google.ads.googleads.v19.resources.types.AccountLink`): - Required. The account link to be - created. - - This corresponds to the ``account_link`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateAccountLinkResponse: - Response message for - [AccountLinkService.CreateAccountLink][google.ads.googleads.v19.services.AccountLinkService.CreateAccountLink]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, account_link] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, account_link_service.CreateAccountLinkRequest - ): - request = account_link_service.CreateAccountLinkRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if account_link is not None: - request.account_link = account_link - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.create_account_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def mutate_account_link( - self, - request: Optional[ - Union[account_link_service.MutateAccountLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[account_link_service.AccountLinkOperation] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> account_link_service.MutateAccountLinkResponse: - r"""Creates or removes an account link. From V5, create is not - supported through AccountLinkService.MutateAccountLink. Use - AccountLinkService.CreateAccountLink instead. - - List of thrown errors: `AccountLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAccountLinkRequest, dict]]): - The request object. Request message for - [AccountLinkService.MutateAccountLink][google.ads.googleads.v19.services.AccountLinkService.MutateAccountLink]. - customer_id (:class:`str`): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (:class:`google.ads.googleads.v19.services.types.AccountLinkOperation`): - Required. The operation to perform on - the link. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAccountLinkResponse: - Response message for account link - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, account_link_service.MutateAccountLinkRequest - ): - request = account_link_service.MutateAccountLinkRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_account_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AccountLinkServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AccountLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/account_link_service/client.py b/google/ads/googleads/v19/services/services/account_link_service/client.py deleted file mode 100644 index 57300c200..000000000 --- a/google/ads/googleads/v19/services/services/account_link_service/client.py +++ /dev/null @@ -1,971 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.resources.types import ( - account_link as gagr_account_link, -) -from google.ads.googleads.v19.services.types import account_link_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AccountLinkServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AccountLinkServiceGrpcTransport -from .transports.grpc_asyncio import AccountLinkServiceGrpcAsyncIOTransport - - -class AccountLinkServiceClientMeta(type): - """Metaclass for the AccountLinkService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AccountLinkServiceTransport]] - _transport_registry["grpc"] = AccountLinkServiceGrpcTransport - _transport_registry["grpc_asyncio"] = AccountLinkServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AccountLinkServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AccountLinkServiceClient(metaclass=AccountLinkServiceClientMeta): - """This service allows management of links between Google Ads - accounts and other accounts. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AccountLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AccountLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AccountLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AccountLinkServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def account_link_path( - customer_id: str, - account_link_id: str, - ) -> str: - """Returns a fully-qualified account_link string.""" - return "customers/{customer_id}/accountLinks/{account_link_id}".format( - customer_id=customer_id, - account_link_id=account_link_id, - ) - - @staticmethod - def parse_account_link_path(path: str) -> Dict[str, str]: - """Parses a account_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/accountLinks/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AccountLinkServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AccountLinkServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AccountLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AccountLinkServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AccountLinkServiceTransport, - Callable[..., AccountLinkServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the account link service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AccountLinkServiceTransport,Callable[..., AccountLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AccountLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AccountLinkServiceClient._read_environment_variables() - self._client_cert_source = ( - AccountLinkServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = AccountLinkServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, AccountLinkServiceTransport) - if transport_provided: - # transport is a AccountLinkServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AccountLinkServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AccountLinkServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AccountLinkServiceTransport], - Callable[..., AccountLinkServiceTransport], - ] = ( - AccountLinkServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., AccountLinkServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AccountLinkServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AccountLinkService", - "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.ads.googleads.v19.services.AccountLinkService", - "credentialsType": None, - } - ), - ) - - def create_account_link( - self, - request: Optional[ - Union[account_link_service.CreateAccountLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - account_link: Optional[gagr_account_link.AccountLink] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> account_link_service.CreateAccountLinkResponse: - r"""Creates an account link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ThirdPartyAppAnalyticsLinkError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.CreateAccountLinkRequest, dict]): - The request object. Request message for - [AccountLinkService.CreateAccountLink][google.ads.googleads.v19.services.AccountLinkService.CreateAccountLink]. - customer_id (str): - Required. The ID of the customer for - which the account link is created. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - account_link (google.ads.googleads.v19.resources.types.AccountLink): - Required. The account link to be - created. - - This corresponds to the ``account_link`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateAccountLinkResponse: - Response message for - [AccountLinkService.CreateAccountLink][google.ads.googleads.v19.services.AccountLinkService.CreateAccountLink]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, account_link] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, account_link_service.CreateAccountLinkRequest - ): - request = account_link_service.CreateAccountLinkRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if account_link is not None: - request.account_link = account_link - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.create_account_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def mutate_account_link( - self, - request: Optional[ - Union[account_link_service.MutateAccountLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[account_link_service.AccountLinkOperation] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> account_link_service.MutateAccountLinkResponse: - r"""Creates or removes an account link. From V5, create is not - supported through AccountLinkService.MutateAccountLink. Use - AccountLinkService.CreateAccountLink instead. - - List of thrown errors: `AccountLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAccountLinkRequest, dict]): - The request object. Request message for - [AccountLinkService.MutateAccountLink][google.ads.googleads.v19.services.AccountLinkService.MutateAccountLink]. - customer_id (str): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (google.ads.googleads.v19.services.types.AccountLinkOperation): - Required. The operation to perform on - the link. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAccountLinkResponse: - Response message for account link - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, account_link_service.MutateAccountLinkRequest - ): - request = account_link_service.MutateAccountLinkRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_account_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AccountLinkServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AccountLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/account_link_service/transports/base.py b/google/ads/googleads/v19/services/services/account_link_service/transports/base.py deleted file mode 100644 index f95a4cc4a..000000000 --- a/google/ads/googleads/v19/services/services/account_link_service/transports/base.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import account_link_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AccountLinkServiceTransport(abc.ABC): - """Abstract transport class for AccountLinkService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.create_account_link: gapic_v1.method.wrap_method( - self.create_account_link, - default_timeout=None, - client_info=client_info, - ), - self.mutate_account_link: gapic_v1.method.wrap_method( - self.mutate_account_link, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def create_account_link( - self, - ) -> Callable[ - [account_link_service.CreateAccountLinkRequest], - Union[ - account_link_service.CreateAccountLinkResponse, - Awaitable[account_link_service.CreateAccountLinkResponse], - ], - ]: - raise NotImplementedError() - - @property - def mutate_account_link( - self, - ) -> Callable[ - [account_link_service.MutateAccountLinkRequest], - Union[ - account_link_service.MutateAccountLinkResponse, - Awaitable[account_link_service.MutateAccountLinkResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AccountLinkServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/account_link_service/transports/grpc.py b/google/ads/googleads/v19/services/services/account_link_service/transports/grpc.py deleted file mode 100644 index e813ad295..000000000 --- a/google/ads/googleads/v19/services/services/account_link_service/transports/grpc.py +++ /dev/null @@ -1,426 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import account_link_service -from .base import AccountLinkServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AccountLinkService", - "rpcName": str(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.ads.googleads.v19.services.AccountLinkService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AccountLinkServiceGrpcTransport(AccountLinkServiceTransport): - """gRPC backend transport for AccountLinkService. - - This service allows management of links between Google Ads - accounts and other accounts. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def create_account_link( - self, - ) -> Callable[ - [account_link_service.CreateAccountLinkRequest], - account_link_service.CreateAccountLinkResponse, - ]: - r"""Return a callable for the create account link method over gRPC. - - Creates an account link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ThirdPartyAppAnalyticsLinkError <>`__ - - Returns: - Callable[[~.CreateAccountLinkRequest], - ~.CreateAccountLinkResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_account_link" not in self._stubs: - self._stubs["create_account_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AccountLinkService/CreateAccountLink", - request_serializer=account_link_service.CreateAccountLinkRequest.serialize, - response_deserializer=account_link_service.CreateAccountLinkResponse.deserialize, - ) - ) - return self._stubs["create_account_link"] - - @property - def mutate_account_link( - self, - ) -> Callable[ - [account_link_service.MutateAccountLinkRequest], - account_link_service.MutateAccountLinkResponse, - ]: - r"""Return a callable for the mutate account link method over gRPC. - - Creates or removes an account link. From V5, create is not - supported through AccountLinkService.MutateAccountLink. Use - AccountLinkService.CreateAccountLink instead. - - List of thrown errors: `AccountLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateAccountLinkRequest], - ~.MutateAccountLinkResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_account_link" not in self._stubs: - self._stubs["mutate_account_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AccountLinkService/MutateAccountLink", - request_serializer=account_link_service.MutateAccountLinkRequest.serialize, - response_deserializer=account_link_service.MutateAccountLinkResponse.deserialize, - ) - ) - return self._stubs["mutate_account_link"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AccountLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/account_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/account_link_service/transports/grpc_asyncio.py deleted file mode 100644 index f27c66c38..000000000 --- a/google/ads/googleads/v19/services/services/account_link_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,452 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import account_link_service -from .base import AccountLinkServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AccountLinkService", - "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.ads.googleads.v19.services.AccountLinkService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AccountLinkServiceGrpcAsyncIOTransport(AccountLinkServiceTransport): - """gRPC AsyncIO backend transport for AccountLinkService. - - This service allows management of links between Google Ads - accounts and other accounts. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def create_account_link( - self, - ) -> Callable[ - [account_link_service.CreateAccountLinkRequest], - Awaitable[account_link_service.CreateAccountLinkResponse], - ]: - r"""Return a callable for the create account link method over gRPC. - - Creates an account link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ThirdPartyAppAnalyticsLinkError <>`__ - - Returns: - Callable[[~.CreateAccountLinkRequest], - Awaitable[~.CreateAccountLinkResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_account_link" not in self._stubs: - self._stubs["create_account_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AccountLinkService/CreateAccountLink", - request_serializer=account_link_service.CreateAccountLinkRequest.serialize, - response_deserializer=account_link_service.CreateAccountLinkResponse.deserialize, - ) - ) - return self._stubs["create_account_link"] - - @property - def mutate_account_link( - self, - ) -> Callable[ - [account_link_service.MutateAccountLinkRequest], - Awaitable[account_link_service.MutateAccountLinkResponse], - ]: - r"""Return a callable for the mutate account link method over gRPC. - - Creates or removes an account link. From V5, create is not - supported through AccountLinkService.MutateAccountLink. Use - AccountLinkService.CreateAccountLink instead. - - List of thrown errors: `AccountLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateAccountLinkRequest], - Awaitable[~.MutateAccountLinkResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_account_link" not in self._stubs: - self._stubs["mutate_account_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AccountLinkService/MutateAccountLink", - request_serializer=account_link_service.MutateAccountLinkRequest.serialize, - response_deserializer=account_link_service.MutateAccountLinkResponse.deserialize, - ) - ) - return self._stubs["mutate_account_link"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.create_account_link: self._wrap_method( - self.create_account_link, - default_timeout=None, - client_info=client_info, - ), - self.mutate_account_link: self._wrap_method( - self.mutate_account_link, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AccountLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/async_client.py b/google/ads/googleads/v19/services/services/ad_group_ad_label_service/async_client.py deleted file mode 100644 index 9edd695bf..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/async_client.py +++ /dev/null @@ -1,436 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_ad_label_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdGroupAdLabelServiceTransport, DEFAULT_CLIENT_INFO -from .client import AdGroupAdLabelServiceClient - -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 AdGroupAdLabelServiceAsyncClient: - """Service to manage labels on ad group ads.""" - - _client: AdGroupAdLabelServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdGroupAdLabelServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AdGroupAdLabelServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AdGroupAdLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AdGroupAdLabelServiceClient._DEFAULT_UNIVERSE - - ad_group_ad_path = staticmethod( - AdGroupAdLabelServiceClient.ad_group_ad_path - ) - parse_ad_group_ad_path = staticmethod( - AdGroupAdLabelServiceClient.parse_ad_group_ad_path - ) - ad_group_ad_label_path = staticmethod( - AdGroupAdLabelServiceClient.ad_group_ad_label_path - ) - parse_ad_group_ad_label_path = staticmethod( - AdGroupAdLabelServiceClient.parse_ad_group_ad_label_path - ) - label_path = staticmethod(AdGroupAdLabelServiceClient.label_path) - parse_label_path = staticmethod( - AdGroupAdLabelServiceClient.parse_label_path - ) - common_billing_account_path = staticmethod( - AdGroupAdLabelServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdGroupAdLabelServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AdGroupAdLabelServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AdGroupAdLabelServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdGroupAdLabelServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdGroupAdLabelServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AdGroupAdLabelServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AdGroupAdLabelServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdGroupAdLabelServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdGroupAdLabelServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAdLabelServiceAsyncClient: The constructed client. - """ - return AdGroupAdLabelServiceClient.from_service_account_info.__func__(AdGroupAdLabelServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAdLabelServiceAsyncClient: The constructed client. - """ - return AdGroupAdLabelServiceClient.from_service_account_file.__func__(AdGroupAdLabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdGroupAdLabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdGroupAdLabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupAdLabelServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdGroupAdLabelServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupAdLabelServiceTransport, - Callable[..., AdGroupAdLabelServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group ad label service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupAdLabelServiceTransport,Callable[..., AdGroupAdLabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupAdLabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdGroupAdLabelServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdGroupAdLabelServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupAdLabelService", - "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.ads.googleads.v19.services.AdGroupAdLabelService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_group_ad_labels( - self, - request: Optional[ - Union[ad_group_ad_label_service.MutateAdGroupAdLabelsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_ad_label_service.AdGroupAdLabelOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_ad_label_service.MutateAdGroupAdLabelsResponse: - r"""Creates and removes ad group ad labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdGroupAdLabelsRequest, dict]]): - The request object. Request message for - [AdGroupAdLabelService.MutateAdGroupAdLabels][google.ads.googleads.v19.services.AdGroupAdLabelService.MutateAdGroupAdLabels]. - customer_id (:class:`str`): - Required. ID of the customer whose ad - group ad labels are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdGroupAdLabelOperation]`): - Required. The list of operations to - perform on ad group ad labels. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupAdLabelsResponse: - Response message for an ad group ad - labels mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_ad_label_service.MutateAdGroupAdLabelsRequest - ): - request = ad_group_ad_label_service.MutateAdGroupAdLabelsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_group_ad_labels - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AdGroupAdLabelServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdGroupAdLabelServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/client.py b/google/ads/googleads/v19/services/services/ad_group_ad_label_service/client.py deleted file mode 100644 index d37e17513..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/client.py +++ /dev/null @@ -1,929 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ad_group_ad_label_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdGroupAdLabelServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AdGroupAdLabelServiceGrpcTransport -from .transports.grpc_asyncio import AdGroupAdLabelServiceGrpcAsyncIOTransport - - -class AdGroupAdLabelServiceClientMeta(type): - """Metaclass for the AdGroupAdLabelService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdGroupAdLabelServiceTransport]] - _transport_registry["grpc"] = AdGroupAdLabelServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AdGroupAdLabelServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdGroupAdLabelServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdGroupAdLabelServiceClient(metaclass=AdGroupAdLabelServiceClientMeta): - """Service to manage labels on ad group ads.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAdLabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAdLabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdGroupAdLabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupAdLabelServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_group_ad_path( - customer_id: str, - ad_group_id: str, - ad_id: str, - ) -> str: - """Returns a fully-qualified ad_group_ad string.""" - return ( - "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ad_id=ad_id, - ) - ) - - @staticmethod - def parse_ad_group_ad_path(path: str) -> Dict[str, str]: - """Parses a ad_group_ad path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_ad_label_path( - customer_id: str, - ad_group_id: str, - ad_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_ad_label string.""" - return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ad_id=ad_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_ad_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def label_path( - customer_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified label string.""" - return "customers/{customer_id}/labels/{label_id}".format( - customer_id=customer_id, - label_id=label_id, - ) - - @staticmethod - def parse_label_path(path: str) -> Dict[str, str]: - """Parses a label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/labels/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AdGroupAdLabelServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AdGroupAdLabelServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AdGroupAdLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdGroupAdLabelServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupAdLabelServiceTransport, - Callable[..., AdGroupAdLabelServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group ad label service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupAdLabelServiceTransport,Callable[..., AdGroupAdLabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupAdLabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdGroupAdLabelServiceClient._read_environment_variables() - self._client_cert_source = ( - AdGroupAdLabelServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AdGroupAdLabelServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AdGroupAdLabelServiceTransport - ) - if transport_provided: - # transport is a AdGroupAdLabelServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AdGroupAdLabelServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdGroupAdLabelServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdGroupAdLabelServiceTransport], - Callable[..., AdGroupAdLabelServiceTransport], - ] = ( - AdGroupAdLabelServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AdGroupAdLabelServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdGroupAdLabelServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupAdLabelService", - "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.ads.googleads.v19.services.AdGroupAdLabelService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_group_ad_labels( - self, - request: Optional[ - Union[ad_group_ad_label_service.MutateAdGroupAdLabelsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_ad_label_service.AdGroupAdLabelOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_ad_label_service.MutateAdGroupAdLabelsResponse: - r"""Creates and removes ad group ad labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdGroupAdLabelsRequest, dict]): - The request object. Request message for - [AdGroupAdLabelService.MutateAdGroupAdLabels][google.ads.googleads.v19.services.AdGroupAdLabelService.MutateAdGroupAdLabels]. - customer_id (str): - Required. ID of the customer whose ad - group ad labels are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupAdLabelOperation]): - Required. The list of operations to - perform on ad group ad labels. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupAdLabelsResponse: - Response message for an ad group ad - labels mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_ad_label_service.MutateAdGroupAdLabelsRequest - ): - request = ad_group_ad_label_service.MutateAdGroupAdLabelsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_ad_group_ad_labels - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdGroupAdLabelServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdGroupAdLabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/base.py deleted file mode 100644 index 97f82f3c4..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ad_group_ad_label_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdGroupAdLabelServiceTransport(abc.ABC): - """Abstract transport class for AdGroupAdLabelService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_group_ad_labels: gapic_v1.method.wrap_method( - self.mutate_ad_group_ad_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_group_ad_labels( - self, - ) -> Callable[ - [ad_group_ad_label_service.MutateAdGroupAdLabelsRequest], - Union[ - ad_group_ad_label_service.MutateAdGroupAdLabelsResponse, - Awaitable[ad_group_ad_label_service.MutateAdGroupAdLabelsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdGroupAdLabelServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/grpc.py deleted file mode 100644 index a3fd5d5d9..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/grpc.py +++ /dev/null @@ -1,388 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ad_group_ad_label_service -from .base import AdGroupAdLabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdGroupAdLabelService", - "rpcName": str(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.ads.googleads.v19.services.AdGroupAdLabelService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupAdLabelServiceGrpcTransport(AdGroupAdLabelServiceTransport): - """gRPC backend transport for AdGroupAdLabelService. - - Service to manage labels on ad group ads. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_group_ad_labels( - self, - ) -> Callable[ - [ad_group_ad_label_service.MutateAdGroupAdLabelsRequest], - ad_group_ad_label_service.MutateAdGroupAdLabelsResponse, - ]: - r"""Return a callable for the mutate ad group ad labels method over gRPC. - - Creates and removes ad group ad labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateAdGroupAdLabelsRequest], - ~.MutateAdGroupAdLabelsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_ad_labels" not in self._stubs: - self._stubs["mutate_ad_group_ad_labels"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupAdLabelService/MutateAdGroupAdLabels", - request_serializer=ad_group_ad_label_service.MutateAdGroupAdLabelsRequest.serialize, - response_deserializer=ad_group_ad_label_service.MutateAdGroupAdLabelsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_ad_labels"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdGroupAdLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/grpc_asyncio.py deleted file mode 100644 index 7ec3353d8..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_ad_label_service -from .base import AdGroupAdLabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdGroupAdLabelService", - "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.ads.googleads.v19.services.AdGroupAdLabelService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupAdLabelServiceGrpcAsyncIOTransport(AdGroupAdLabelServiceTransport): - """gRPC AsyncIO backend transport for AdGroupAdLabelService. - - Service to manage labels on ad group ads. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_group_ad_labels( - self, - ) -> Callable[ - [ad_group_ad_label_service.MutateAdGroupAdLabelsRequest], - Awaitable[ad_group_ad_label_service.MutateAdGroupAdLabelsResponse], - ]: - r"""Return a callable for the mutate ad group ad labels method over gRPC. - - Creates and removes ad group ad labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateAdGroupAdLabelsRequest], - Awaitable[~.MutateAdGroupAdLabelsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_ad_labels" not in self._stubs: - self._stubs["mutate_ad_group_ad_labels"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupAdLabelService/MutateAdGroupAdLabels", - request_serializer=ad_group_ad_label_service.MutateAdGroupAdLabelsRequest.serialize, - response_deserializer=ad_group_ad_label_service.MutateAdGroupAdLabelsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_ad_labels"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_group_ad_labels: self._wrap_method( - self.mutate_ad_group_ad_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdGroupAdLabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_service/async_client.py b/google/ads/googleads/v19/services/services/ad_group_ad_service/async_client.py deleted file mode 100644 index 6427ff415..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_ad_service/async_client.py +++ /dev/null @@ -1,554 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_ad_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdGroupAdServiceTransport, DEFAULT_CLIENT_INFO -from .client import AdGroupAdServiceClient - -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 AdGroupAdServiceAsyncClient: - """Service to manage ads in an ad group.""" - - _client: AdGroupAdServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdGroupAdServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AdGroupAdServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AdGroupAdServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AdGroupAdServiceClient._DEFAULT_UNIVERSE - - ad_path = staticmethod(AdGroupAdServiceClient.ad_path) - parse_ad_path = staticmethod(AdGroupAdServiceClient.parse_ad_path) - ad_group_path = staticmethod(AdGroupAdServiceClient.ad_group_path) - parse_ad_group_path = staticmethod( - AdGroupAdServiceClient.parse_ad_group_path - ) - ad_group_ad_path = staticmethod(AdGroupAdServiceClient.ad_group_ad_path) - parse_ad_group_ad_path = staticmethod( - AdGroupAdServiceClient.parse_ad_group_ad_path - ) - ad_group_ad_label_path = staticmethod( - AdGroupAdServiceClient.ad_group_ad_label_path - ) - parse_ad_group_ad_label_path = staticmethod( - AdGroupAdServiceClient.parse_ad_group_ad_label_path - ) - asset_path = staticmethod(AdGroupAdServiceClient.asset_path) - parse_asset_path = staticmethod(AdGroupAdServiceClient.parse_asset_path) - common_billing_account_path = staticmethod( - AdGroupAdServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdGroupAdServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(AdGroupAdServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - AdGroupAdServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdGroupAdServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdGroupAdServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AdGroupAdServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AdGroupAdServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdGroupAdServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdGroupAdServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAdServiceAsyncClient: The constructed client. - """ - return AdGroupAdServiceClient.from_service_account_info.__func__(AdGroupAdServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAdServiceAsyncClient: The constructed client. - """ - return AdGroupAdServiceClient.from_service_account_file.__func__(AdGroupAdServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdGroupAdServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdGroupAdServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupAdServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdGroupAdServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupAdServiceTransport, - Callable[..., AdGroupAdServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group ad service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupAdServiceTransport,Callable[..., AdGroupAdServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupAdServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdGroupAdServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdGroupAdServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupAdService", - "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.ads.googleads.v19.services.AdGroupAdService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_group_ads( - self, - request: Optional[ - Union[ad_group_ad_service.MutateAdGroupAdsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_ad_service.AdGroupAdOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_ad_service.MutateAdGroupAdsResponse: - r"""Creates, updates, or removes ads. Operation statuses are - returned. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdGroupAdError <>`__ `AdSharingError <>`__ `AdxError <>`__ - `AssetError <>`__ `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CollectionSizeError <>`__ `ContextError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FeedAttributeReferenceError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `FunctionError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ - `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `PolicyFindingError <>`__ - `PolicyValidationParameterError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ `UrlFieldError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdGroupAdsRequest, dict]]): - The request object. Request message for - [AdGroupAdService.MutateAdGroupAds][google.ads.googleads.v19.services.AdGroupAdService.MutateAdGroupAds]. - customer_id (:class:`str`): - Required. The ID of the customer - whose ads are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdGroupAdOperation]`): - Required. The list of operations to - perform on individual ads. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupAdsResponse: - Response message for an ad group ad - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, ad_group_ad_service.MutateAdGroupAdsRequest): - request = ad_group_ad_service.MutateAdGroupAdsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_group_ads - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def remove_automatically_created_assets( - self, - request: Optional[ - Union[ - ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest, - dict, - ] - ] = None, - *, - ad_group_ad: Optional[str] = None, - assets_with_field_type: Optional[ - MutableSequence[ad_group_ad_service.AssetsWithFieldType] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> None: - r"""Remove automatically created assets from an ad. - - List of thrown errors: `AdError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ - `AutomaticallyCreatedAssetRemovalError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.RemoveAutomaticallyCreatedAssetsRequest, dict]]): - The request object. Request message for - [AdGroupAdService.RemoveAutomaticallyCreatedAssetsRequest][]. - ad_group_ad (:class:`str`): - Required. The resource name of the - AdGroupAd from which to remove - automatically created assets. - - This corresponds to the ``ad_group_ad`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - assets_with_field_type (:class:`MutableSequence[google.ads.googleads.v19.services.types.AssetsWithFieldType]`): - Required. List of assets with field - type to be removed from the AdGroupAd. - - This corresponds to the ``assets_with_field_type`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 - # gotten any keyword arguments that map to the request. - flattened_params = [ad_group_ad, assets_with_field_type] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest - ): - request = ( - ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if ad_group_ad is not None: - request.ad_group_ad = ad_group_ad - if assets_with_field_type: - request.assets_with_field_type.extend(assets_with_field_type) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.remove_automatically_created_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("ad_group_ad", request.ad_group_ad),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - async def __aenter__(self) -> "AdGroupAdServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdGroupAdServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_service/client.py b/google/ads/googleads/v19/services/services/ad_group_ad_service/client.py deleted file mode 100644 index 6b637b27e..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_ad_service/client.py +++ /dev/null @@ -1,1077 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ad_group_ad_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdGroupAdServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AdGroupAdServiceGrpcTransport -from .transports.grpc_asyncio import AdGroupAdServiceGrpcAsyncIOTransport - - -class AdGroupAdServiceClientMeta(type): - """Metaclass for the AdGroupAdService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdGroupAdServiceTransport]] - _transport_registry["grpc"] = AdGroupAdServiceGrpcTransport - _transport_registry["grpc_asyncio"] = AdGroupAdServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdGroupAdServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdGroupAdServiceClient(metaclass=AdGroupAdServiceClientMeta): - """Service to manage ads in an ad group.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAdServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAdServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdGroupAdServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupAdServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_path( - customer_id: str, - ad_id: str, - ) -> str: - """Returns a fully-qualified ad string.""" - return "customers/{customer_id}/ads/{ad_id}".format( - customer_id=customer_id, - ad_id=ad_id, - ) - - @staticmethod - def parse_ad_path(path: str) -> Dict[str, str]: - """Parses a ad path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/ads/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_path( - customer_id: str, - ad_group_id: str, - ) -> str: - """Returns a fully-qualified ad_group string.""" - return "customers/{customer_id}/adGroups/{ad_group_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ) - - @staticmethod - def parse_ad_group_path(path: str) -> Dict[str, str]: - """Parses a ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_ad_path( - customer_id: str, - ad_group_id: str, - ad_id: str, - ) -> str: - """Returns a fully-qualified ad_group_ad string.""" - return ( - "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ad_id=ad_id, - ) - ) - - @staticmethod - def parse_ad_group_ad_path(path: str) -> Dict[str, str]: - """Parses a ad_group_ad path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_ad_label_path( - customer_id: str, - ad_group_id: str, - ad_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_ad_label string.""" - return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ad_id=ad_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_ad_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_path( - customer_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset string.""" - return "customers/{customer_id}/assets/{asset_id}".format( - customer_id=customer_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_path(path: str) -> Dict[str, str]: - """Parses a asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assets/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AdGroupAdServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AdGroupAdServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AdGroupAdServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdGroupAdServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupAdServiceTransport, - Callable[..., AdGroupAdServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group ad service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupAdServiceTransport,Callable[..., AdGroupAdServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupAdServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdGroupAdServiceClient._read_environment_variables() - self._client_cert_source = ( - AdGroupAdServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = AdGroupAdServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, AdGroupAdServiceTransport) - if transport_provided: - # transport is a AdGroupAdServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AdGroupAdServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdGroupAdServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdGroupAdServiceTransport], - Callable[..., AdGroupAdServiceTransport], - ] = ( - AdGroupAdServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., AdGroupAdServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdGroupAdServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupAdService", - "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.ads.googleads.v19.services.AdGroupAdService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_group_ads( - self, - request: Optional[ - Union[ad_group_ad_service.MutateAdGroupAdsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_ad_service.AdGroupAdOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_ad_service.MutateAdGroupAdsResponse: - r"""Creates, updates, or removes ads. Operation statuses are - returned. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdGroupAdError <>`__ `AdSharingError <>`__ `AdxError <>`__ - `AssetError <>`__ `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CollectionSizeError <>`__ `ContextError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FeedAttributeReferenceError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `FunctionError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ - `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `PolicyFindingError <>`__ - `PolicyValidationParameterError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ `UrlFieldError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdGroupAdsRequest, dict]): - The request object. Request message for - [AdGroupAdService.MutateAdGroupAds][google.ads.googleads.v19.services.AdGroupAdService.MutateAdGroupAds]. - customer_id (str): - Required. The ID of the customer - whose ads are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupAdOperation]): - Required. The list of operations to - perform on individual ads. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupAdsResponse: - Response message for an ad group ad - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, ad_group_ad_service.MutateAdGroupAdsRequest): - request = ad_group_ad_service.MutateAdGroupAdsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_ad_group_ads - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def remove_automatically_created_assets( - self, - request: Optional[ - Union[ - ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest, - dict, - ] - ] = None, - *, - ad_group_ad: Optional[str] = None, - assets_with_field_type: Optional[ - MutableSequence[ad_group_ad_service.AssetsWithFieldType] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> None: - r"""Remove automatically created assets from an ad. - - List of thrown errors: `AdError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ - `AutomaticallyCreatedAssetRemovalError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.RemoveAutomaticallyCreatedAssetsRequest, dict]): - The request object. Request message for - [AdGroupAdService.RemoveAutomaticallyCreatedAssetsRequest][]. - ad_group_ad (str): - Required. The resource name of the - AdGroupAd from which to remove - automatically created assets. - - This corresponds to the ``ad_group_ad`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - assets_with_field_type (MutableSequence[google.ads.googleads.v19.services.types.AssetsWithFieldType]): - Required. List of assets with field - type to be removed from the AdGroupAd. - - This corresponds to the ``assets_with_field_type`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 - # gotten any keyword arguments that map to the request. - flattened_params = [ad_group_ad, assets_with_field_type] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest - ): - request = ( - ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if ad_group_ad is not None: - request.ad_group_ad = ad_group_ad - if assets_with_field_type is not None: - request.assets_with_field_type = assets_with_field_type - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.remove_automatically_created_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("ad_group_ad", request.ad_group_ad),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - def __enter__(self) -> "AdGroupAdServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdGroupAdServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_group_ad_service/transports/base.py deleted file mode 100644 index 3decc9146..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_ad_service/transports/base.py +++ /dev/null @@ -1,187 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ad_group_ad_service -from google.protobuf import empty_pb2 # type: ignore - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdGroupAdServiceTransport(abc.ABC): - """Abstract transport class for AdGroupAdService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_group_ads: gapic_v1.method.wrap_method( - self.mutate_ad_group_ads, - default_timeout=None, - client_info=client_info, - ), - self.remove_automatically_created_assets: gapic_v1.method.wrap_method( - self.remove_automatically_created_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_group_ads( - self, - ) -> Callable[ - [ad_group_ad_service.MutateAdGroupAdsRequest], - Union[ - ad_group_ad_service.MutateAdGroupAdsResponse, - Awaitable[ad_group_ad_service.MutateAdGroupAdsResponse], - ], - ]: - raise NotImplementedError() - - @property - def remove_automatically_created_assets( - self, - ) -> Callable[ - [ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest], - Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdGroupAdServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_group_ad_service/transports/grpc.py deleted file mode 100644 index bac61f2e0..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_ad_service/transports/grpc.py +++ /dev/null @@ -1,441 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ad_group_ad_service -from google.protobuf import empty_pb2 # type: ignore -from .base import AdGroupAdServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdGroupAdService", - "rpcName": str(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.ads.googleads.v19.services.AdGroupAdService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupAdServiceGrpcTransport(AdGroupAdServiceTransport): - """gRPC backend transport for AdGroupAdService. - - Service to manage ads in an ad group. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_group_ads( - self, - ) -> Callable[ - [ad_group_ad_service.MutateAdGroupAdsRequest], - ad_group_ad_service.MutateAdGroupAdsResponse, - ]: - r"""Return a callable for the mutate ad group ads method over gRPC. - - Creates, updates, or removes ads. Operation statuses are - returned. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdGroupAdError <>`__ `AdSharingError <>`__ `AdxError <>`__ - `AssetError <>`__ `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CollectionSizeError <>`__ `ContextError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FeedAttributeReferenceError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `FunctionError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ - `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `PolicyFindingError <>`__ - `PolicyValidationParameterError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateAdGroupAdsRequest], - ~.MutateAdGroupAdsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_ads" not in self._stubs: - self._stubs["mutate_ad_group_ads"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupAdService/MutateAdGroupAds", - request_serializer=ad_group_ad_service.MutateAdGroupAdsRequest.serialize, - response_deserializer=ad_group_ad_service.MutateAdGroupAdsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_ads"] - - @property - def remove_automatically_created_assets( - self, - ) -> Callable[ - [ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest], - empty_pb2.Empty, - ]: - r"""Return a callable for the remove automatically created - assets method over gRPC. - - Remove automatically created assets from an ad. - - List of thrown errors: `AdError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ - `AutomaticallyCreatedAssetRemovalError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.RemoveAutomaticallyCreatedAssetsRequest], - ~.Empty]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "remove_automatically_created_assets" not in self._stubs: - self._stubs["remove_automatically_created_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupAdService/RemoveAutomaticallyCreatedAssets", - request_serializer=ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - ) - return self._stubs["remove_automatically_created_assets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdGroupAdServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_group_ad_service/transports/grpc_asyncio.py deleted file mode 100644 index a61f353f8..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_ad_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,467 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_ad_service -from google.protobuf import empty_pb2 # type: ignore -from .base import AdGroupAdServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdGroupAdService", - "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.ads.googleads.v19.services.AdGroupAdService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupAdServiceGrpcAsyncIOTransport(AdGroupAdServiceTransport): - """gRPC AsyncIO backend transport for AdGroupAdService. - - Service to manage ads in an ad group. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_group_ads( - self, - ) -> Callable[ - [ad_group_ad_service.MutateAdGroupAdsRequest], - Awaitable[ad_group_ad_service.MutateAdGroupAdsResponse], - ]: - r"""Return a callable for the mutate ad group ads method over gRPC. - - Creates, updates, or removes ads. Operation statuses are - returned. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdGroupAdError <>`__ `AdSharingError <>`__ `AdxError <>`__ - `AssetError <>`__ `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CollectionSizeError <>`__ `ContextError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FeedAttributeReferenceError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `FunctionError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ - `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `PolicyFindingError <>`__ - `PolicyValidationParameterError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateAdGroupAdsRequest], - Awaitable[~.MutateAdGroupAdsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_ads" not in self._stubs: - self._stubs["mutate_ad_group_ads"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupAdService/MutateAdGroupAds", - request_serializer=ad_group_ad_service.MutateAdGroupAdsRequest.serialize, - response_deserializer=ad_group_ad_service.MutateAdGroupAdsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_ads"] - - @property - def remove_automatically_created_assets( - self, - ) -> Callable[ - [ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest], - Awaitable[empty_pb2.Empty], - ]: - r"""Return a callable for the remove automatically created - assets method over gRPC. - - Remove automatically created assets from an ad. - - List of thrown errors: `AdError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ - `AutomaticallyCreatedAssetRemovalError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.RemoveAutomaticallyCreatedAssetsRequest], - Awaitable[~.Empty]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "remove_automatically_created_assets" not in self._stubs: - self._stubs["remove_automatically_created_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupAdService/RemoveAutomaticallyCreatedAssets", - request_serializer=ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - ) - return self._stubs["remove_automatically_created_assets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_group_ads: self._wrap_method( - self.mutate_ad_group_ads, - default_timeout=None, - client_info=client_info, - ), - self.remove_automatically_created_assets: self._wrap_method( - self.remove_automatically_created_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdGroupAdServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_service/async_client.py b/google/ads/googleads/v19/services/services/ad_group_asset_service/async_client.py deleted file mode 100644 index 2b0d9d496..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_asset_service/async_client.py +++ /dev/null @@ -1,431 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdGroupAssetServiceTransport, DEFAULT_CLIENT_INFO -from .client import AdGroupAssetServiceClient - -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 AdGroupAssetServiceAsyncClient: - """Service to manage ad group assets.""" - - _client: AdGroupAssetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdGroupAssetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AdGroupAssetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AdGroupAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AdGroupAssetServiceClient._DEFAULT_UNIVERSE - - ad_group_path = staticmethod(AdGroupAssetServiceClient.ad_group_path) - parse_ad_group_path = staticmethod( - AdGroupAssetServiceClient.parse_ad_group_path - ) - ad_group_asset_path = staticmethod( - AdGroupAssetServiceClient.ad_group_asset_path - ) - parse_ad_group_asset_path = staticmethod( - AdGroupAssetServiceClient.parse_ad_group_asset_path - ) - asset_path = staticmethod(AdGroupAssetServiceClient.asset_path) - parse_asset_path = staticmethod(AdGroupAssetServiceClient.parse_asset_path) - common_billing_account_path = staticmethod( - AdGroupAssetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdGroupAssetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AdGroupAssetServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AdGroupAssetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdGroupAssetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdGroupAssetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AdGroupAssetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AdGroupAssetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdGroupAssetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdGroupAssetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAssetServiceAsyncClient: The constructed client. - """ - return AdGroupAssetServiceClient.from_service_account_info.__func__(AdGroupAssetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAssetServiceAsyncClient: The constructed client. - """ - return AdGroupAssetServiceClient.from_service_account_file.__func__(AdGroupAssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdGroupAssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdGroupAssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupAssetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdGroupAssetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupAssetServiceTransport, - Callable[..., AdGroupAssetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group asset service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupAssetServiceTransport,Callable[..., AdGroupAssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupAssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdGroupAssetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdGroupAssetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupAssetService", - "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.ads.googleads.v19.services.AdGroupAssetService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_group_assets( - self, - request: Optional[ - Union[ad_group_asset_service.MutateAdGroupAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_asset_service.AdGroupAssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_asset_service.MutateAdGroupAssetsResponse: - r"""Creates, updates, or removes ad group assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdGroupAssetsRequest, dict]]): - The request object. Request message for - [AdGroupAssetService.MutateAdGroupAssets][google.ads.googleads.v19.services.AdGroupAssetService.MutateAdGroupAssets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose ad group assets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdGroupAssetOperation]`): - Required. The list of operations to - perform on individual ad group assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupAssetsResponse: - Response message for an ad group - asset mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_asset_service.MutateAdGroupAssetsRequest - ): - request = ad_group_asset_service.MutateAdGroupAssetsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_group_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AdGroupAssetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdGroupAssetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_service/client.py b/google/ads/googleads/v19/services/services/ad_group_asset_service/client.py deleted file mode 100644 index a106a0056..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_asset_service/client.py +++ /dev/null @@ -1,920 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ad_group_asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdGroupAssetServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AdGroupAssetServiceGrpcTransport -from .transports.grpc_asyncio import AdGroupAssetServiceGrpcAsyncIOTransport - - -class AdGroupAssetServiceClientMeta(type): - """Metaclass for the AdGroupAssetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdGroupAssetServiceTransport]] - _transport_registry["grpc"] = AdGroupAssetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AdGroupAssetServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdGroupAssetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdGroupAssetServiceClient(metaclass=AdGroupAssetServiceClientMeta): - """Service to manage ad group assets.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdGroupAssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupAssetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_group_path( - customer_id: str, - ad_group_id: str, - ) -> str: - """Returns a fully-qualified ad_group string.""" - return "customers/{customer_id}/adGroups/{ad_group_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ) - - @staticmethod - def parse_ad_group_path(path: str) -> Dict[str, str]: - """Parses a ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_asset_path( - customer_id: str, - ad_group_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified ad_group_asset string.""" - return "customers/{customer_id}/adGroupAssets/{ad_group_id}~{asset_id}~{field_type}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_ad_group_asset_path(path: str) -> Dict[str, str]: - """Parses a ad_group_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_path( - customer_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset string.""" - return "customers/{customer_id}/assets/{asset_id}".format( - customer_id=customer_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_path(path: str) -> Dict[str, str]: - """Parses a asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assets/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AdGroupAssetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AdGroupAssetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AdGroupAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdGroupAssetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupAssetServiceTransport, - Callable[..., AdGroupAssetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group asset service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupAssetServiceTransport,Callable[..., AdGroupAssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupAssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdGroupAssetServiceClient._read_environment_variables() - self._client_cert_source = ( - AdGroupAssetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = AdGroupAssetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, AdGroupAssetServiceTransport) - if transport_provided: - # transport is a AdGroupAssetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AdGroupAssetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdGroupAssetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdGroupAssetServiceTransport], - Callable[..., AdGroupAssetServiceTransport], - ] = ( - AdGroupAssetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AdGroupAssetServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdGroupAssetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupAssetService", - "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.ads.googleads.v19.services.AdGroupAssetService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_group_assets( - self, - request: Optional[ - Union[ad_group_asset_service.MutateAdGroupAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_asset_service.AdGroupAssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_asset_service.MutateAdGroupAssetsResponse: - r"""Creates, updates, or removes ad group assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdGroupAssetsRequest, dict]): - The request object. Request message for - [AdGroupAssetService.MutateAdGroupAssets][google.ads.googleads.v19.services.AdGroupAssetService.MutateAdGroupAssets]. - customer_id (str): - Required. The ID of the customer - whose ad group assets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupAssetOperation]): - Required. The list of operations to - perform on individual ad group assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupAssetsResponse: - Response message for an ad group - asset mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_asset_service.MutateAdGroupAssetsRequest - ): - request = ad_group_asset_service.MutateAdGroupAssetsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_ad_group_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdGroupAssetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdGroupAssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_group_asset_service/transports/base.py deleted file mode 100644 index 7a89b962c..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_asset_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ad_group_asset_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdGroupAssetServiceTransport(abc.ABC): - """Abstract transport class for AdGroupAssetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_group_assets: gapic_v1.method.wrap_method( - self.mutate_ad_group_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_group_assets( - self, - ) -> Callable[ - [ad_group_asset_service.MutateAdGroupAssetsRequest], - Union[ - ad_group_asset_service.MutateAdGroupAssetsResponse, - Awaitable[ad_group_asset_service.MutateAdGroupAssetsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdGroupAssetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_group_asset_service/transports/grpc.py deleted file mode 100644 index bd00f664e..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_asset_service/transports/grpc.py +++ /dev/null @@ -1,388 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ad_group_asset_service -from .base import AdGroupAssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdGroupAssetService", - "rpcName": str(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.ads.googleads.v19.services.AdGroupAssetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupAssetServiceGrpcTransport(AdGroupAssetServiceTransport): - """gRPC backend transport for AdGroupAssetService. - - Service to manage ad group assets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_group_assets( - self, - ) -> Callable[ - [ad_group_asset_service.MutateAdGroupAssetsRequest], - ad_group_asset_service.MutateAdGroupAssetsResponse, - ]: - r"""Return a callable for the mutate ad group assets method over gRPC. - - Creates, updates, or removes ad group assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateAdGroupAssetsRequest], - ~.MutateAdGroupAssetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_assets" not in self._stubs: - self._stubs["mutate_ad_group_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupAssetService/MutateAdGroupAssets", - request_serializer=ad_group_asset_service.MutateAdGroupAssetsRequest.serialize, - response_deserializer=ad_group_asset_service.MutateAdGroupAssetsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_assets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdGroupAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_group_asset_service/transports/grpc_asyncio.py deleted file mode 100644 index 7e60c0e26..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_asset_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_asset_service -from .base import AdGroupAssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdGroupAssetService", - "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.ads.googleads.v19.services.AdGroupAssetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupAssetServiceGrpcAsyncIOTransport(AdGroupAssetServiceTransport): - """gRPC AsyncIO backend transport for AdGroupAssetService. - - Service to manage ad group assets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_group_assets( - self, - ) -> Callable[ - [ad_group_asset_service.MutateAdGroupAssetsRequest], - Awaitable[ad_group_asset_service.MutateAdGroupAssetsResponse], - ]: - r"""Return a callable for the mutate ad group assets method over gRPC. - - Creates, updates, or removes ad group assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateAdGroupAssetsRequest], - Awaitable[~.MutateAdGroupAssetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_assets" not in self._stubs: - self._stubs["mutate_ad_group_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupAssetService/MutateAdGroupAssets", - request_serializer=ad_group_asset_service.MutateAdGroupAssetsRequest.serialize, - response_deserializer=ad_group_asset_service.MutateAdGroupAssetsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_assets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_group_assets: self._wrap_method( - self.mutate_ad_group_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdGroupAssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/async_client.py b/google/ads/googleads/v19/services/services/ad_group_asset_set_service/async_client.py deleted file mode 100644 index a9e9fca18..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/async_client.py +++ /dev/null @@ -1,435 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_asset_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupAssetSetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import AdGroupAssetSetServiceClient - -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 AdGroupAssetSetServiceAsyncClient: - """Service to manage ad group asset set""" - - _client: AdGroupAssetSetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdGroupAssetSetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AdGroupAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AdGroupAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AdGroupAssetSetServiceClient._DEFAULT_UNIVERSE - - ad_group_path = staticmethod(AdGroupAssetSetServiceClient.ad_group_path) - parse_ad_group_path = staticmethod( - AdGroupAssetSetServiceClient.parse_ad_group_path - ) - ad_group_asset_set_path = staticmethod( - AdGroupAssetSetServiceClient.ad_group_asset_set_path - ) - parse_ad_group_asset_set_path = staticmethod( - AdGroupAssetSetServiceClient.parse_ad_group_asset_set_path - ) - asset_set_path = staticmethod(AdGroupAssetSetServiceClient.asset_set_path) - parse_asset_set_path = staticmethod( - AdGroupAssetSetServiceClient.parse_asset_set_path - ) - common_billing_account_path = staticmethod( - AdGroupAssetSetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdGroupAssetSetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AdGroupAssetSetServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AdGroupAssetSetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdGroupAssetSetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdGroupAssetSetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AdGroupAssetSetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AdGroupAssetSetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdGroupAssetSetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdGroupAssetSetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAssetSetServiceAsyncClient: The constructed client. - """ - return AdGroupAssetSetServiceClient.from_service_account_info.__func__(AdGroupAssetSetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAssetSetServiceAsyncClient: The constructed client. - """ - return AdGroupAssetSetServiceClient.from_service_account_file.__func__(AdGroupAssetSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdGroupAssetSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdGroupAssetSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupAssetSetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdGroupAssetSetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupAssetSetServiceTransport, - Callable[..., AdGroupAssetSetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group asset set service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupAssetSetServiceTransport,Callable[..., AdGroupAssetSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupAssetSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdGroupAssetSetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdGroupAssetSetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupAssetSetService", - "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.ads.googleads.v19.services.AdGroupAssetSetService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_group_asset_sets( - self, - request: Optional[ - Union[ - ad_group_asset_set_service.MutateAdGroupAssetSetsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_asset_set_service.AdGroupAssetSetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_asset_set_service.MutateAdGroupAssetSetsResponse: - r"""Creates, or removes ad group asset sets. Operation - statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdGroupAssetSetsRequest, dict]]): - The request object. Request message for - [AdGroupAssetSetService.MutateAdGroupAssetSets][google.ads.googleads.v19.services.AdGroupAssetSetService.MutateAdGroupAssetSets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose ad group asset sets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdGroupAssetSetOperation]`): - Required. The list of operations to - perform on individual ad group asset - sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupAssetSetsResponse: - Response message for an ad group - asset set mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_asset_set_service.MutateAdGroupAssetSetsRequest - ): - request = ad_group_asset_set_service.MutateAdGroupAssetSetsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_group_asset_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AdGroupAssetSetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdGroupAssetSetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/client.py b/google/ads/googleads/v19/services/services/ad_group_asset_set_service/client.py deleted file mode 100644 index 166761741..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/client.py +++ /dev/null @@ -1,925 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ad_group_asset_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupAssetSetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import AdGroupAssetSetServiceGrpcTransport -from .transports.grpc_asyncio import AdGroupAssetSetServiceGrpcAsyncIOTransport - - -class AdGroupAssetSetServiceClientMeta(type): - """Metaclass for the AdGroupAssetSetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdGroupAssetSetServiceTransport]] - _transport_registry["grpc"] = AdGroupAssetSetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AdGroupAssetSetServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdGroupAssetSetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdGroupAssetSetServiceClient(metaclass=AdGroupAssetSetServiceClientMeta): - """Service to manage ad group asset set""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAssetSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupAssetSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdGroupAssetSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupAssetSetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_group_path( - customer_id: str, - ad_group_id: str, - ) -> str: - """Returns a fully-qualified ad_group string.""" - return "customers/{customer_id}/adGroups/{ad_group_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ) - - @staticmethod - def parse_ad_group_path(path: str) -> Dict[str, str]: - """Parses a ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_asset_set_path( - customer_id: str, - ad_group_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified ad_group_asset_set string.""" - return "customers/{customer_id}/adGroupAssetSets/{ad_group_id}~{asset_set_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_ad_group_asset_set_path(path: str) -> Dict[str, str]: - """Parses a ad_group_asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAssetSets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_set_path( - customer_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified asset_set string.""" - return "customers/{customer_id}/assetSets/{asset_set_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_asset_set_path(path: str) -> Dict[str, str]: - """Parses a asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AdGroupAssetSetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AdGroupAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AdGroupAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdGroupAssetSetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupAssetSetServiceTransport, - Callable[..., AdGroupAssetSetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group asset set service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupAssetSetServiceTransport,Callable[..., AdGroupAssetSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupAssetSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdGroupAssetSetServiceClient._read_environment_variables() - self._client_cert_source = ( - AdGroupAssetSetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AdGroupAssetSetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AdGroupAssetSetServiceTransport - ) - if transport_provided: - # transport is a AdGroupAssetSetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AdGroupAssetSetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdGroupAssetSetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdGroupAssetSetServiceTransport], - Callable[..., AdGroupAssetSetServiceTransport], - ] = ( - AdGroupAssetSetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AdGroupAssetSetServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdGroupAssetSetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupAssetSetService", - "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.ads.googleads.v19.services.AdGroupAssetSetService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_group_asset_sets( - self, - request: Optional[ - Union[ - ad_group_asset_set_service.MutateAdGroupAssetSetsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_asset_set_service.AdGroupAssetSetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_asset_set_service.MutateAdGroupAssetSetsResponse: - r"""Creates, or removes ad group asset sets. Operation - statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdGroupAssetSetsRequest, dict]): - The request object. Request message for - [AdGroupAssetSetService.MutateAdGroupAssetSets][google.ads.googleads.v19.services.AdGroupAssetSetService.MutateAdGroupAssetSets]. - customer_id (str): - Required. The ID of the customer - whose ad group asset sets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupAssetSetOperation]): - Required. The list of operations to - perform on individual ad group asset - sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupAssetSetsResponse: - Response message for an ad group - asset set mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_asset_set_service.MutateAdGroupAssetSetsRequest - ): - request = ad_group_asset_set_service.MutateAdGroupAssetSetsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_ad_group_asset_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdGroupAssetSetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdGroupAssetSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/base.py deleted file mode 100644 index 5389607f0..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ad_group_asset_set_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdGroupAssetSetServiceTransport(abc.ABC): - """Abstract transport class for AdGroupAssetSetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_group_asset_sets: gapic_v1.method.wrap_method( - self.mutate_ad_group_asset_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_group_asset_sets( - self, - ) -> Callable[ - [ad_group_asset_set_service.MutateAdGroupAssetSetsRequest], - Union[ - ad_group_asset_set_service.MutateAdGroupAssetSetsResponse, - Awaitable[ - ad_group_asset_set_service.MutateAdGroupAssetSetsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdGroupAssetSetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/grpc.py deleted file mode 100644 index 40773e745..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/grpc.py +++ /dev/null @@ -1,382 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ad_group_asset_set_service -from .base import AdGroupAssetSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdGroupAssetSetService", - "rpcName": str(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.ads.googleads.v19.services.AdGroupAssetSetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupAssetSetServiceGrpcTransport(AdGroupAssetSetServiceTransport): - """gRPC backend transport for AdGroupAssetSetService. - - Service to manage ad group asset set - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_group_asset_sets( - self, - ) -> Callable[ - [ad_group_asset_set_service.MutateAdGroupAssetSetsRequest], - ad_group_asset_set_service.MutateAdGroupAssetSetsResponse, - ]: - r"""Return a callable for the mutate ad group asset sets method over gRPC. - - Creates, or removes ad group asset sets. Operation - statuses are returned. - - Returns: - Callable[[~.MutateAdGroupAssetSetsRequest], - ~.MutateAdGroupAssetSetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_asset_sets" not in self._stubs: - self._stubs["mutate_ad_group_asset_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupAssetSetService/MutateAdGroupAssetSets", - request_serializer=ad_group_asset_set_service.MutateAdGroupAssetSetsRequest.serialize, - response_deserializer=ad_group_asset_set_service.MutateAdGroupAssetSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_asset_sets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdGroupAssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/grpc_asyncio.py deleted file mode 100644 index 5359f5840..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,405 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_asset_set_service -from .base import AdGroupAssetSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdGroupAssetSetService", - "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.ads.googleads.v19.services.AdGroupAssetSetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupAssetSetServiceGrpcAsyncIOTransport( - AdGroupAssetSetServiceTransport -): - """gRPC AsyncIO backend transport for AdGroupAssetSetService. - - Service to manage ad group asset set - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_group_asset_sets( - self, - ) -> Callable[ - [ad_group_asset_set_service.MutateAdGroupAssetSetsRequest], - Awaitable[ad_group_asset_set_service.MutateAdGroupAssetSetsResponse], - ]: - r"""Return a callable for the mutate ad group asset sets method over gRPC. - - Creates, or removes ad group asset sets. Operation - statuses are returned. - - Returns: - Callable[[~.MutateAdGroupAssetSetsRequest], - Awaitable[~.MutateAdGroupAssetSetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_asset_sets" not in self._stubs: - self._stubs["mutate_ad_group_asset_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupAssetSetService/MutateAdGroupAssetSets", - request_serializer=ad_group_asset_set_service.MutateAdGroupAssetSetsRequest.serialize, - response_deserializer=ad_group_asset_set_service.MutateAdGroupAssetSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_asset_sets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_group_asset_sets: self._wrap_method( - self.mutate_ad_group_asset_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdGroupAssetSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/async_client.py b/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/async_client.py deleted file mode 100644 index cfd2bcc41..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/async_client.py +++ /dev/null @@ -1,451 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - ad_group_bid_modifier_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupBidModifierServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import AdGroupBidModifierServiceClient - -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 AdGroupBidModifierServiceAsyncClient: - """Service to manage ad group bid modifiers.""" - - _client: AdGroupBidModifierServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdGroupBidModifierServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - AdGroupBidModifierServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - AdGroupBidModifierServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AdGroupBidModifierServiceClient._DEFAULT_UNIVERSE - - ad_group_path = staticmethod(AdGroupBidModifierServiceClient.ad_group_path) - parse_ad_group_path = staticmethod( - AdGroupBidModifierServiceClient.parse_ad_group_path - ) - ad_group_bid_modifier_path = staticmethod( - AdGroupBidModifierServiceClient.ad_group_bid_modifier_path - ) - parse_ad_group_bid_modifier_path = staticmethod( - AdGroupBidModifierServiceClient.parse_ad_group_bid_modifier_path - ) - common_billing_account_path = staticmethod( - AdGroupBidModifierServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdGroupBidModifierServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AdGroupBidModifierServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AdGroupBidModifierServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdGroupBidModifierServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdGroupBidModifierServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AdGroupBidModifierServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AdGroupBidModifierServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdGroupBidModifierServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdGroupBidModifierServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupBidModifierServiceAsyncClient: The constructed client. - """ - return AdGroupBidModifierServiceClient.from_service_account_info.__func__(AdGroupBidModifierServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupBidModifierServiceAsyncClient: The constructed client. - """ - return AdGroupBidModifierServiceClient.from_service_account_file.__func__(AdGroupBidModifierServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdGroupBidModifierServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdGroupBidModifierServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupBidModifierServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdGroupBidModifierServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupBidModifierServiceTransport, - Callable[..., AdGroupBidModifierServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group bid modifier service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupBidModifierServiceTransport,Callable[..., AdGroupBidModifierServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupBidModifierServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdGroupBidModifierServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdGroupBidModifierServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupBidModifierService", - "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.ads.googleads.v19.services.AdGroupBidModifierService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_group_bid_modifiers( - self, - request: Optional[ - Union[ - ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - ad_group_bid_modifier_service.AdGroupBidModifierOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse: - r"""Creates, updates, or removes ad group bid modifiers. Operation - statuses are returned. - - List of thrown errors: `AdGroupBidModifierError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdGroupBidModifiersRequest, dict]]): - The request object. Request message for - [AdGroupBidModifierService.MutateAdGroupBidModifiers][google.ads.googleads.v19.services.AdGroupBidModifierService.MutateAdGroupBidModifiers]. - customer_id (:class:`str`): - Required. ID of the customer whose ad - group bid modifiers are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdGroupBidModifierOperation]`): - Required. The list of operations to - perform on individual ad group bid - modifiers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupBidModifiersResponse: - Response message for ad group bid - modifiers mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest, - ): - request = ( - ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_group_bid_modifiers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AdGroupBidModifierServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdGroupBidModifierServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/client.py b/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/client.py deleted file mode 100644 index b6061ec56..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/client.py +++ /dev/null @@ -1,929 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - ad_group_bid_modifier_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupBidModifierServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import AdGroupBidModifierServiceGrpcTransport -from .transports.grpc_asyncio import ( - AdGroupBidModifierServiceGrpcAsyncIOTransport, -) - - -class AdGroupBidModifierServiceClientMeta(type): - """Metaclass for the AdGroupBidModifierService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdGroupBidModifierServiceTransport]] - _transport_registry["grpc"] = AdGroupBidModifierServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AdGroupBidModifierServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdGroupBidModifierServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdGroupBidModifierServiceClient( - metaclass=AdGroupBidModifierServiceClientMeta -): - """Service to manage ad group bid modifiers.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupBidModifierServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupBidModifierServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdGroupBidModifierServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupBidModifierServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_group_path( - customer_id: str, - ad_group_id: str, - ) -> str: - """Returns a fully-qualified ad_group string.""" - return "customers/{customer_id}/adGroups/{ad_group_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ) - - @staticmethod - def parse_ad_group_path(path: str) -> Dict[str, str]: - """Parses a ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_bid_modifier_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified ad_group_bid_modifier string.""" - return "customers/{customer_id}/adGroupBidModifiers/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_ad_group_bid_modifier_path(path: str) -> Dict[str, str]: - """Parses a ad_group_bid_modifier path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupBidModifiers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - AdGroupBidModifierServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AdGroupBidModifierServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = AdGroupBidModifierServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdGroupBidModifierServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupBidModifierServiceTransport, - Callable[..., AdGroupBidModifierServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group bid modifier service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupBidModifierServiceTransport,Callable[..., AdGroupBidModifierServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupBidModifierServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdGroupBidModifierServiceClient._read_environment_variables() - self._client_cert_source = ( - AdGroupBidModifierServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AdGroupBidModifierServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AdGroupBidModifierServiceTransport - ) - if transport_provided: - # transport is a AdGroupBidModifierServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - AdGroupBidModifierServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdGroupBidModifierServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdGroupBidModifierServiceTransport], - Callable[..., AdGroupBidModifierServiceTransport], - ] = ( - AdGroupBidModifierServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AdGroupBidModifierServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdGroupBidModifierServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupBidModifierService", - "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.ads.googleads.v19.services.AdGroupBidModifierService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_group_bid_modifiers( - self, - request: Optional[ - Union[ - ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - ad_group_bid_modifier_service.AdGroupBidModifierOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse: - r"""Creates, updates, or removes ad group bid modifiers. Operation - statuses are returned. - - List of thrown errors: `AdGroupBidModifierError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdGroupBidModifiersRequest, dict]): - The request object. Request message for - [AdGroupBidModifierService.MutateAdGroupBidModifiers][google.ads.googleads.v19.services.AdGroupBidModifierService.MutateAdGroupBidModifiers]. - customer_id (str): - Required. ID of the customer whose ad - group bid modifiers are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupBidModifierOperation]): - Required. The list of operations to - perform on individual ad group bid - modifiers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupBidModifiersResponse: - Response message for ad group bid - modifiers mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest, - ): - request = ( - ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_ad_group_bid_modifiers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdGroupBidModifierServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdGroupBidModifierServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/base.py deleted file mode 100644 index 4e513e444..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - ad_group_bid_modifier_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdGroupBidModifierServiceTransport(abc.ABC): - """Abstract transport class for AdGroupBidModifierService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_group_bid_modifiers: gapic_v1.method.wrap_method( - self.mutate_ad_group_bid_modifiers, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_group_bid_modifiers( - self, - ) -> Callable[ - [ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest], - Union[ - ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse, - Awaitable[ - ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdGroupBidModifierServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/grpc.py deleted file mode 100644 index f1ff03778..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/grpc.py +++ /dev/null @@ -1,397 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - ad_group_bid_modifier_service, -) -from .base import AdGroupBidModifierServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdGroupBidModifierService", - "rpcName": str(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.ads.googleads.v19.services.AdGroupBidModifierService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupBidModifierServiceGrpcTransport( - AdGroupBidModifierServiceTransport -): - """gRPC backend transport for AdGroupBidModifierService. - - Service to manage ad group bid modifiers. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_group_bid_modifiers( - self, - ) -> Callable[ - [ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest], - ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse, - ]: - r"""Return a callable for the mutate ad group bid modifiers method over gRPC. - - Creates, updates, or removes ad group bid modifiers. Operation - statuses are returned. - - List of thrown errors: `AdGroupBidModifierError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateAdGroupBidModifiersRequest], - ~.MutateAdGroupBidModifiersResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_bid_modifiers" not in self._stubs: - self._stubs["mutate_ad_group_bid_modifiers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupBidModifierService/MutateAdGroupBidModifiers", - request_serializer=ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest.serialize, - response_deserializer=ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_bid_modifiers"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdGroupBidModifierServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/grpc_asyncio.py deleted file mode 100644 index df4abea71..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,420 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - ad_group_bid_modifier_service, -) -from .base import AdGroupBidModifierServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdGroupBidModifierService", - "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.ads.googleads.v19.services.AdGroupBidModifierService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupBidModifierServiceGrpcAsyncIOTransport( - AdGroupBidModifierServiceTransport -): - """gRPC AsyncIO backend transport for AdGroupBidModifierService. - - Service to manage ad group bid modifiers. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_group_bid_modifiers( - self, - ) -> Callable[ - [ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest], - Awaitable[ - ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse - ], - ]: - r"""Return a callable for the mutate ad group bid modifiers method over gRPC. - - Creates, updates, or removes ad group bid modifiers. Operation - statuses are returned. - - List of thrown errors: `AdGroupBidModifierError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateAdGroupBidModifiersRequest], - Awaitable[~.MutateAdGroupBidModifiersResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_bid_modifiers" not in self._stubs: - self._stubs["mutate_ad_group_bid_modifiers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupBidModifierService/MutateAdGroupBidModifiers", - request_serializer=ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest.serialize, - response_deserializer=ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_bid_modifiers"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_group_bid_modifiers: self._wrap_method( - self.mutate_ad_group_bid_modifiers, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdGroupBidModifierServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/async_client.py b/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/async_client.py deleted file mode 100644 index 03e19efe1..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/async_client.py +++ /dev/null @@ -1,455 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - ad_group_criterion_customizer_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupCriterionCustomizerServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import AdGroupCriterionCustomizerServiceClient - -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 AdGroupCriterionCustomizerServiceAsyncClient: - """Service to manage ad group criterion customizer""" - - _client: AdGroupCriterionCustomizerServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdGroupCriterionCustomizerServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - AdGroupCriterionCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - AdGroupCriterionCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ( - AdGroupCriterionCustomizerServiceClient._DEFAULT_UNIVERSE - ) - - ad_group_criterion_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.ad_group_criterion_path - ) - parse_ad_group_criterion_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.parse_ad_group_criterion_path - ) - ad_group_criterion_customizer_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.ad_group_criterion_customizer_path - ) - parse_ad_group_criterion_customizer_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.parse_ad_group_criterion_customizer_path - ) - customizer_attribute_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.customizer_attribute_path - ) - parse_customizer_attribute_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.parse_customizer_attribute_path - ) - common_billing_account_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdGroupCriterionCustomizerServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionCustomizerServiceAsyncClient: The constructed client. - """ - return AdGroupCriterionCustomizerServiceClient.from_service_account_info.__func__(AdGroupCriterionCustomizerServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionCustomizerServiceAsyncClient: The constructed client. - """ - return AdGroupCriterionCustomizerServiceClient.from_service_account_file.__func__(AdGroupCriterionCustomizerServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdGroupCriterionCustomizerServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdGroupCriterionCustomizerServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupCriterionCustomizerServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - AdGroupCriterionCustomizerServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupCriterionCustomizerServiceTransport, - Callable[..., AdGroupCriterionCustomizerServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group criterion customizer service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupCriterionCustomizerServiceTransport,Callable[..., AdGroupCriterionCustomizerServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupCriterionCustomizerServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdGroupCriterionCustomizerServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdGroupCriterionCustomizerServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupCriterionCustomizerService", - "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.ads.googleads.v19.services.AdGroupCriterionCustomizerService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_group_criterion_customizers( - self, - request: Optional[ - Union[ - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - ad_group_criterion_customizer_service.AdGroupCriterionCustomizerOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse - ): - r"""Creates, updates or removes ad group criterion - customizers. Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdGroupCriterionCustomizersRequest, dict]]): - The request object. Request message for - [AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers][google.ads.googleads.v19.services.AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers]. - customer_id (:class:`str`): - Required. The ID of the customer - whose ad group criterion customizers are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdGroupCriterionCustomizerOperation]`): - Required. The list of operations to - perform on individual ad group criterion - customizers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupCriterionCustomizersResponse: - Response message for an ad group - criterion customizer mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest, - ): - request = ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_group_criterion_customizers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__( - self, - ) -> "AdGroupCriterionCustomizerServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdGroupCriterionCustomizerServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/client.py b/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/client.py deleted file mode 100644 index 067909c8b..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/client.py +++ /dev/null @@ -1,952 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - ad_group_criterion_customizer_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupCriterionCustomizerServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import AdGroupCriterionCustomizerServiceGrpcTransport -from .transports.grpc_asyncio import ( - AdGroupCriterionCustomizerServiceGrpcAsyncIOTransport, -) - - -class AdGroupCriterionCustomizerServiceClientMeta(type): - """Metaclass for the AdGroupCriterionCustomizerService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdGroupCriterionCustomizerServiceTransport]] - _transport_registry["grpc"] = AdGroupCriterionCustomizerServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AdGroupCriterionCustomizerServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdGroupCriterionCustomizerServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdGroupCriterionCustomizerServiceClient( - metaclass=AdGroupCriterionCustomizerServiceClientMeta -): - """Service to manage ad group criterion customizer""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionCustomizerServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionCustomizerServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdGroupCriterionCustomizerServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupCriterionCustomizerServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_group_criterion_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion string.""" - return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_criterion_customizer_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion_customizer string.""" - return "customers/{customer_id}/adGroupCriterionCustomizers/{ad_group_id}~{criterion_id}~{customizer_attribute_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_ad_group_criterion_customizer_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriterionCustomizers/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customizer_attribute_path( - customer_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified customizer_attribute string.""" - return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( - customer_id=customer_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_customizer_attribute_path(path: str) -> Dict[str, str]: - """Parses a customizer_attribute path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - AdGroupCriterionCustomizerServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - AdGroupCriterionCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = AdGroupCriterionCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - AdGroupCriterionCustomizerServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupCriterionCustomizerServiceTransport, - Callable[..., AdGroupCriterionCustomizerServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group criterion customizer service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupCriterionCustomizerServiceTransport,Callable[..., AdGroupCriterionCustomizerServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupCriterionCustomizerServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ( - AdGroupCriterionCustomizerServiceClient._read_environment_variables() - ) - self._client_cert_source = ( - AdGroupCriterionCustomizerServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AdGroupCriterionCustomizerServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AdGroupCriterionCustomizerServiceTransport - ) - if transport_provided: - # transport is a AdGroupCriterionCustomizerServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - AdGroupCriterionCustomizerServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdGroupCriterionCustomizerServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdGroupCriterionCustomizerServiceTransport], - Callable[..., AdGroupCriterionCustomizerServiceTransport], - ] = ( - AdGroupCriterionCustomizerServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AdGroupCriterionCustomizerServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdGroupCriterionCustomizerServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupCriterionCustomizerService", - "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.ads.googleads.v19.services.AdGroupCriterionCustomizerService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_group_criterion_customizers( - self, - request: Optional[ - Union[ - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - ad_group_criterion_customizer_service.AdGroupCriterionCustomizerOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse - ): - r"""Creates, updates or removes ad group criterion - customizers. Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdGroupCriterionCustomizersRequest, dict]): - The request object. Request message for - [AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers][google.ads.googleads.v19.services.AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers]. - customer_id (str): - Required. The ID of the customer - whose ad group criterion customizers are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupCriterionCustomizerOperation]): - Required. The list of operations to - perform on individual ad group criterion - customizers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupCriterionCustomizersResponse: - Response message for an ad group - criterion customizer mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest, - ): - request = ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_ad_group_criterion_customizers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdGroupCriterionCustomizerServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdGroupCriterionCustomizerServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/base.py deleted file mode 100644 index aea17c1d6..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - ad_group_criterion_customizer_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdGroupCriterionCustomizerServiceTransport(abc.ABC): - """Abstract transport class for AdGroupCriterionCustomizerService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_group_criterion_customizers: gapic_v1.method.wrap_method( - self.mutate_ad_group_criterion_customizers, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_group_criterion_customizers( - self, - ) -> Callable[ - [ - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest - ], - Union[ - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse, - Awaitable[ - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdGroupCriterionCustomizerServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/grpc.py deleted file mode 100644 index 971f72091..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/grpc.py +++ /dev/null @@ -1,392 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - ad_group_criterion_customizer_service, -) -from .base import ( - AdGroupCriterionCustomizerServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdGroupCriterionCustomizerService", - "rpcName": str(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.ads.googleads.v19.services.AdGroupCriterionCustomizerService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupCriterionCustomizerServiceGrpcTransport( - AdGroupCriterionCustomizerServiceTransport -): - """gRPC backend transport for AdGroupCriterionCustomizerService. - - Service to manage ad group criterion customizer - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_group_criterion_customizers( - self, - ) -> Callable[ - [ - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest - ], - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse, - ]: - r"""Return a callable for the mutate ad group criterion - customizers method over gRPC. - - Creates, updates or removes ad group criterion - customizers. Operation statuses are returned. - - Returns: - Callable[[~.MutateAdGroupCriterionCustomizersRequest], - ~.MutateAdGroupCriterionCustomizersResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_criterion_customizers" not in self._stubs: - self._stubs["mutate_ad_group_criterion_customizers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupCriterionCustomizerService/MutateAdGroupCriterionCustomizers", - request_serializer=ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest.serialize, - response_deserializer=ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_criterion_customizers"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdGroupCriterionCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/grpc_asyncio.py deleted file mode 100644 index 2d013a34d..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,415 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - ad_group_criterion_customizer_service, -) -from .base import ( - AdGroupCriterionCustomizerServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdGroupCriterionCustomizerService", - "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.ads.googleads.v19.services.AdGroupCriterionCustomizerService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupCriterionCustomizerServiceGrpcAsyncIOTransport( - AdGroupCriterionCustomizerServiceTransport -): - """gRPC AsyncIO backend transport for AdGroupCriterionCustomizerService. - - Service to manage ad group criterion customizer - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_group_criterion_customizers( - self, - ) -> Callable[ - [ - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest - ], - Awaitable[ - ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse - ], - ]: - r"""Return a callable for the mutate ad group criterion - customizers method over gRPC. - - Creates, updates or removes ad group criterion - customizers. Operation statuses are returned. - - Returns: - Callable[[~.MutateAdGroupCriterionCustomizersRequest], - Awaitable[~.MutateAdGroupCriterionCustomizersResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_criterion_customizers" not in self._stubs: - self._stubs["mutate_ad_group_criterion_customizers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupCriterionCustomizerService/MutateAdGroupCriterionCustomizers", - request_serializer=ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest.serialize, - response_deserializer=ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_criterion_customizers"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_group_criterion_customizers: self._wrap_method( - self.mutate_ad_group_criterion_customizers, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdGroupCriterionCustomizerServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/async_client.py b/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/async_client.py deleted file mode 100644 index 9ab5288d3..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/async_client.py +++ /dev/null @@ -1,449 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - ad_group_criterion_label_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupCriterionLabelServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import AdGroupCriterionLabelServiceClient - -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 AdGroupCriterionLabelServiceAsyncClient: - """Service to manage labels on ad group criteria.""" - - _client: AdGroupCriterionLabelServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdGroupCriterionLabelServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - AdGroupCriterionLabelServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - AdGroupCriterionLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AdGroupCriterionLabelServiceClient._DEFAULT_UNIVERSE - - ad_group_criterion_path = staticmethod( - AdGroupCriterionLabelServiceClient.ad_group_criterion_path - ) - parse_ad_group_criterion_path = staticmethod( - AdGroupCriterionLabelServiceClient.parse_ad_group_criterion_path - ) - ad_group_criterion_label_path = staticmethod( - AdGroupCriterionLabelServiceClient.ad_group_criterion_label_path - ) - parse_ad_group_criterion_label_path = staticmethod( - AdGroupCriterionLabelServiceClient.parse_ad_group_criterion_label_path - ) - label_path = staticmethod(AdGroupCriterionLabelServiceClient.label_path) - parse_label_path = staticmethod( - AdGroupCriterionLabelServiceClient.parse_label_path - ) - common_billing_account_path = staticmethod( - AdGroupCriterionLabelServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdGroupCriterionLabelServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AdGroupCriterionLabelServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AdGroupCriterionLabelServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdGroupCriterionLabelServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdGroupCriterionLabelServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AdGroupCriterionLabelServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AdGroupCriterionLabelServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdGroupCriterionLabelServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdGroupCriterionLabelServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionLabelServiceAsyncClient: The constructed client. - """ - return AdGroupCriterionLabelServiceClient.from_service_account_info.__func__(AdGroupCriterionLabelServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionLabelServiceAsyncClient: The constructed client. - """ - return AdGroupCriterionLabelServiceClient.from_service_account_file.__func__(AdGroupCriterionLabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdGroupCriterionLabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdGroupCriterionLabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupCriterionLabelServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdGroupCriterionLabelServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupCriterionLabelServiceTransport, - Callable[..., AdGroupCriterionLabelServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group criterion label service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupCriterionLabelServiceTransport,Callable[..., AdGroupCriterionLabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupCriterionLabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdGroupCriterionLabelServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdGroupCriterionLabelServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupCriterionLabelService", - "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.ads.googleads.v19.services.AdGroupCriterionLabelService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_group_criterion_labels( - self, - request: Optional[ - Union[ - ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - ad_group_criterion_label_service.AdGroupCriterionLabelOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse: - r"""Creates and removes ad group criterion labels. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdGroupCriterionLabelsRequest, dict]]): - The request object. Request message for - [AdGroupCriterionLabelService.MutateAdGroupCriterionLabels][google.ads.googleads.v19.services.AdGroupCriterionLabelService.MutateAdGroupCriterionLabels]. - customer_id (:class:`str`): - Required. ID of the customer whose ad - group criterion labels are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdGroupCriterionLabelOperation]`): - Required. The list of operations to - perform on ad group criterion labels. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupCriterionLabelsResponse: - Response message for an ad group - criterion labels mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest, - ): - request = ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_group_criterion_labels - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AdGroupCriterionLabelServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdGroupCriterionLabelServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/client.py b/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/client.py deleted file mode 100644 index 32d45d80d..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/client.py +++ /dev/null @@ -1,949 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - ad_group_criterion_label_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupCriterionLabelServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import AdGroupCriterionLabelServiceGrpcTransport -from .transports.grpc_asyncio import ( - AdGroupCriterionLabelServiceGrpcAsyncIOTransport, -) - - -class AdGroupCriterionLabelServiceClientMeta(type): - """Metaclass for the AdGroupCriterionLabelService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdGroupCriterionLabelServiceTransport]] - _transport_registry["grpc"] = AdGroupCriterionLabelServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AdGroupCriterionLabelServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdGroupCriterionLabelServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdGroupCriterionLabelServiceClient( - metaclass=AdGroupCriterionLabelServiceClientMeta -): - """Service to manage labels on ad group criteria.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionLabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionLabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdGroupCriterionLabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupCriterionLabelServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_group_criterion_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion string.""" - return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_criterion_label_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion_label string.""" - return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def label_path( - customer_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified label string.""" - return "customers/{customer_id}/labels/{label_id}".format( - customer_id=customer_id, - label_id=label_id, - ) - - @staticmethod - def parse_label_path(path: str) -> Dict[str, str]: - """Parses a label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/labels/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - AdGroupCriterionLabelServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - AdGroupCriterionLabelServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = AdGroupCriterionLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdGroupCriterionLabelServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupCriterionLabelServiceTransport, - Callable[..., AdGroupCriterionLabelServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group criterion label service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupCriterionLabelServiceTransport,Callable[..., AdGroupCriterionLabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupCriterionLabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdGroupCriterionLabelServiceClient._read_environment_variables() - self._client_cert_source = ( - AdGroupCriterionLabelServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AdGroupCriterionLabelServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AdGroupCriterionLabelServiceTransport - ) - if transport_provided: - # transport is a AdGroupCriterionLabelServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - AdGroupCriterionLabelServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdGroupCriterionLabelServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdGroupCriterionLabelServiceTransport], - Callable[..., AdGroupCriterionLabelServiceTransport], - ] = ( - AdGroupCriterionLabelServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AdGroupCriterionLabelServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdGroupCriterionLabelServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupCriterionLabelService", - "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.ads.googleads.v19.services.AdGroupCriterionLabelService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_group_criterion_labels( - self, - request: Optional[ - Union[ - ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - ad_group_criterion_label_service.AdGroupCriterionLabelOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse: - r"""Creates and removes ad group criterion labels. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdGroupCriterionLabelsRequest, dict]): - The request object. Request message for - [AdGroupCriterionLabelService.MutateAdGroupCriterionLabels][google.ads.googleads.v19.services.AdGroupCriterionLabelService.MutateAdGroupCriterionLabels]. - customer_id (str): - Required. ID of the customer whose ad - group criterion labels are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupCriterionLabelOperation]): - Required. The list of operations to - perform on ad group criterion labels. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupCriterionLabelsResponse: - Response message for an ad group - criterion labels mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest, - ): - request = ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_ad_group_criterion_labels - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdGroupCriterionLabelServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdGroupCriterionLabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/base.py deleted file mode 100644 index 14b0c8024..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - ad_group_criterion_label_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdGroupCriterionLabelServiceTransport(abc.ABC): - """Abstract transport class for AdGroupCriterionLabelService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_group_criterion_labels: gapic_v1.method.wrap_method( - self.mutate_ad_group_criterion_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_group_criterion_labels( - self, - ) -> Callable[ - [ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest], - Union[ - ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse, - Awaitable[ - ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdGroupCriterionLabelServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/grpc.py deleted file mode 100644 index f82dde10e..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/grpc.py +++ /dev/null @@ -1,392 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - ad_group_criterion_label_service, -) -from .base import AdGroupCriterionLabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdGroupCriterionLabelService", - "rpcName": str(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.ads.googleads.v19.services.AdGroupCriterionLabelService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupCriterionLabelServiceGrpcTransport( - AdGroupCriterionLabelServiceTransport -): - """gRPC backend transport for AdGroupCriterionLabelService. - - Service to manage labels on ad group criteria. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_group_criterion_labels( - self, - ) -> Callable[ - [ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest], - ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse, - ]: - r"""Return a callable for the mutate ad group criterion - labels method over gRPC. - - Creates and removes ad group criterion labels. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateAdGroupCriterionLabelsRequest], - ~.MutateAdGroupCriterionLabelsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_criterion_labels" not in self._stubs: - self._stubs["mutate_ad_group_criterion_labels"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupCriterionLabelService/MutateAdGroupCriterionLabels", - request_serializer=ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest.serialize, - response_deserializer=ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_criterion_labels"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdGroupCriterionLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/grpc_asyncio.py deleted file mode 100644 index 1e1607ee3..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,415 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - ad_group_criterion_label_service, -) -from .base import AdGroupCriterionLabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdGroupCriterionLabelService", - "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.ads.googleads.v19.services.AdGroupCriterionLabelService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupCriterionLabelServiceGrpcAsyncIOTransport( - AdGroupCriterionLabelServiceTransport -): - """gRPC AsyncIO backend transport for AdGroupCriterionLabelService. - - Service to manage labels on ad group criteria. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_group_criterion_labels( - self, - ) -> Callable[ - [ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest], - Awaitable[ - ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse - ], - ]: - r"""Return a callable for the mutate ad group criterion - labels method over gRPC. - - Creates and removes ad group criterion labels. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateAdGroupCriterionLabelsRequest], - Awaitable[~.MutateAdGroupCriterionLabelsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_criterion_labels" not in self._stubs: - self._stubs["mutate_ad_group_criterion_labels"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupCriterionLabelService/MutateAdGroupCriterionLabels", - request_serializer=ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest.serialize, - response_deserializer=ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_criterion_labels"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_group_criterion_labels: self._wrap_method( - self.mutate_ad_group_criterion_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdGroupCriterionLabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_service/async_client.py b/google/ads/googleads/v19/services/services/ad_group_criterion_service/async_client.py deleted file mode 100644 index 53a099f1e..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_service/async_client.py +++ /dev/null @@ -1,469 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_criterion_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupCriterionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import AdGroupCriterionServiceClient - -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 AdGroupCriterionServiceAsyncClient: - """Service to manage ad group criteria.""" - - _client: AdGroupCriterionServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdGroupCriterionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AdGroupCriterionServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AdGroupCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AdGroupCriterionServiceClient._DEFAULT_UNIVERSE - - ad_group_path = staticmethod(AdGroupCriterionServiceClient.ad_group_path) - parse_ad_group_path = staticmethod( - AdGroupCriterionServiceClient.parse_ad_group_path - ) - ad_group_criterion_path = staticmethod( - AdGroupCriterionServiceClient.ad_group_criterion_path - ) - parse_ad_group_criterion_path = staticmethod( - AdGroupCriterionServiceClient.parse_ad_group_criterion_path - ) - ad_group_criterion_label_path = staticmethod( - AdGroupCriterionServiceClient.ad_group_criterion_label_path - ) - parse_ad_group_criterion_label_path = staticmethod( - AdGroupCriterionServiceClient.parse_ad_group_criterion_label_path - ) - combined_audience_path = staticmethod( - AdGroupCriterionServiceClient.combined_audience_path - ) - parse_combined_audience_path = staticmethod( - AdGroupCriterionServiceClient.parse_combined_audience_path - ) - mobile_app_category_constant_path = staticmethod( - AdGroupCriterionServiceClient.mobile_app_category_constant_path - ) - parse_mobile_app_category_constant_path = staticmethod( - AdGroupCriterionServiceClient.parse_mobile_app_category_constant_path - ) - topic_constant_path = staticmethod( - AdGroupCriterionServiceClient.topic_constant_path - ) - parse_topic_constant_path = staticmethod( - AdGroupCriterionServiceClient.parse_topic_constant_path - ) - common_billing_account_path = staticmethod( - AdGroupCriterionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdGroupCriterionServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AdGroupCriterionServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AdGroupCriterionServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdGroupCriterionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdGroupCriterionServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AdGroupCriterionServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AdGroupCriterionServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdGroupCriterionServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdGroupCriterionServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionServiceAsyncClient: The constructed client. - """ - return AdGroupCriterionServiceClient.from_service_account_info.__func__(AdGroupCriterionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionServiceAsyncClient: The constructed client. - """ - return AdGroupCriterionServiceClient.from_service_account_file.__func__(AdGroupCriterionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdGroupCriterionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdGroupCriterionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupCriterionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdGroupCriterionServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupCriterionServiceTransport, - Callable[..., AdGroupCriterionServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group criterion service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupCriterionServiceTransport,Callable[..., AdGroupCriterionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupCriterionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdGroupCriterionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdGroupCriterionServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupCriterionService", - "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.ads.googleads.v19.services.AdGroupCriterionService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_group_criteria( - self, - request: Optional[ - Union[ad_group_criterion_service.MutateAdGroupCriteriaRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - ad_group_criterion_service.AdGroupCriterionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_criterion_service.MutateAdGroupCriteriaResponse: - r"""Creates, updates, or removes criteria. Operation statuses are - returned. - - List of thrown errors: `AdGroupCriterionError <>`__ - `AdxError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `BiddingError <>`__ - `BiddingStrategyError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DateError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `MultiplierError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `PolicyViolationError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdGroupCriteriaRequest, dict]]): - The request object. Request message for - [AdGroupCriterionService.MutateAdGroupCriteria][google.ads.googleads.v19.services.AdGroupCriterionService.MutateAdGroupCriteria]. - customer_id (:class:`str`): - Required. ID of the customer whose - criteria are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdGroupCriterionOperation]`): - Required. The list of operations to - perform on individual criteria. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupCriteriaResponse: - Response message for an ad group - criterion mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_criterion_service.MutateAdGroupCriteriaRequest - ): - request = ad_group_criterion_service.MutateAdGroupCriteriaRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_group_criteria - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AdGroupCriterionServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdGroupCriterionServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_service/client.py b/google/ads/googleads/v19/services/services/ad_group_criterion_service/client.py deleted file mode 100644 index 13fd8ab2b..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_service/client.py +++ /dev/null @@ -1,998 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ad_group_criterion_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupCriterionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import AdGroupCriterionServiceGrpcTransport -from .transports.grpc_asyncio import AdGroupCriterionServiceGrpcAsyncIOTransport - - -class AdGroupCriterionServiceClientMeta(type): - """Metaclass for the AdGroupCriterionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdGroupCriterionServiceTransport]] - _transport_registry["grpc"] = AdGroupCriterionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AdGroupCriterionServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdGroupCriterionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdGroupCriterionServiceClient( - metaclass=AdGroupCriterionServiceClientMeta -): - """Service to manage ad group criteria.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCriterionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdGroupCriterionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupCriterionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_group_path( - customer_id: str, - ad_group_id: str, - ) -> str: - """Returns a fully-qualified ad_group string.""" - return "customers/{customer_id}/adGroups/{ad_group_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ) - - @staticmethod - def parse_ad_group_path(path: str) -> Dict[str, str]: - """Parses a ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_criterion_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion string.""" - return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_criterion_label_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion_label string.""" - return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def combined_audience_path( - customer_id: str, - combined_audience_id: str, - ) -> str: - """Returns a fully-qualified combined_audience string.""" - return "customers/{customer_id}/combinedAudiences/{combined_audience_id}".format( - customer_id=customer_id, - combined_audience_id=combined_audience_id, - ) - - @staticmethod - def parse_combined_audience_path(path: str) -> Dict[str, str]: - """Parses a combined_audience path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/combinedAudiences/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def mobile_app_category_constant_path( - mobile_app_category_id: str, - ) -> str: - """Returns a fully-qualified mobile_app_category_constant string.""" - return "mobileAppCategoryConstants/{mobile_app_category_id}".format( - mobile_app_category_id=mobile_app_category_id, - ) - - @staticmethod - def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: - """Parses a mobile_app_category_constant path into its component segments.""" - m = re.match( - r"^mobileAppCategoryConstants/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def topic_constant_path( - topic_id: str, - ) -> str: - """Returns a fully-qualified topic_constant string.""" - return "topicConstants/{topic_id}".format( - topic_id=topic_id, - ) - - @staticmethod - def parse_topic_constant_path(path: str) -> Dict[str, str]: - """Parses a topic_constant path into its component segments.""" - m = re.match(r"^topicConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AdGroupCriterionServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AdGroupCriterionServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AdGroupCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdGroupCriterionServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupCriterionServiceTransport, - Callable[..., AdGroupCriterionServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group criterion service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupCriterionServiceTransport,Callable[..., AdGroupCriterionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupCriterionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdGroupCriterionServiceClient._read_environment_variables() - self._client_cert_source = ( - AdGroupCriterionServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AdGroupCriterionServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AdGroupCriterionServiceTransport - ) - if transport_provided: - # transport is a AdGroupCriterionServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AdGroupCriterionServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdGroupCriterionServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdGroupCriterionServiceTransport], - Callable[..., AdGroupCriterionServiceTransport], - ] = ( - AdGroupCriterionServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AdGroupCriterionServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdGroupCriterionServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupCriterionService", - "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.ads.googleads.v19.services.AdGroupCriterionService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_group_criteria( - self, - request: Optional[ - Union[ad_group_criterion_service.MutateAdGroupCriteriaRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - ad_group_criterion_service.AdGroupCriterionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_criterion_service.MutateAdGroupCriteriaResponse: - r"""Creates, updates, or removes criteria. Operation statuses are - returned. - - List of thrown errors: `AdGroupCriterionError <>`__ - `AdxError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `BiddingError <>`__ - `BiddingStrategyError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DateError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `MultiplierError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `PolicyViolationError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdGroupCriteriaRequest, dict]): - The request object. Request message for - [AdGroupCriterionService.MutateAdGroupCriteria][google.ads.googleads.v19.services.AdGroupCriterionService.MutateAdGroupCriteria]. - customer_id (str): - Required. ID of the customer whose - criteria are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupCriterionOperation]): - Required. The list of operations to - perform on individual criteria. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupCriteriaResponse: - Response message for an ad group - criterion mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_criterion_service.MutateAdGroupCriteriaRequest - ): - request = ad_group_criterion_service.MutateAdGroupCriteriaRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_ad_group_criteria - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdGroupCriterionServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdGroupCriterionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/base.py deleted file mode 100644 index b9a669130..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ad_group_criterion_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdGroupCriterionServiceTransport(abc.ABC): - """Abstract transport class for AdGroupCriterionService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_group_criteria: gapic_v1.method.wrap_method( - self.mutate_ad_group_criteria, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_group_criteria( - self, - ) -> Callable[ - [ad_group_criterion_service.MutateAdGroupCriteriaRequest], - Union[ - ad_group_criterion_service.MutateAdGroupCriteriaResponse, - Awaitable[ad_group_criterion_service.MutateAdGroupCriteriaResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdGroupCriterionServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/grpc.py deleted file mode 100644 index f0975ac31..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/grpc.py +++ /dev/null @@ -1,398 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ad_group_criterion_service -from .base import AdGroupCriterionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdGroupCriterionService", - "rpcName": str(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.ads.googleads.v19.services.AdGroupCriterionService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupCriterionServiceGrpcTransport(AdGroupCriterionServiceTransport): - """gRPC backend transport for AdGroupCriterionService. - - Service to manage ad group criteria. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_group_criteria( - self, - ) -> Callable[ - [ad_group_criterion_service.MutateAdGroupCriteriaRequest], - ad_group_criterion_service.MutateAdGroupCriteriaResponse, - ]: - r"""Return a callable for the mutate ad group criteria method over gRPC. - - Creates, updates, or removes criteria. Operation statuses are - returned. - - List of thrown errors: `AdGroupCriterionError <>`__ - `AdxError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `BiddingError <>`__ - `BiddingStrategyError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DateError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `MultiplierError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `PolicyViolationError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateAdGroupCriteriaRequest], - ~.MutateAdGroupCriteriaResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_criteria" not in self._stubs: - self._stubs["mutate_ad_group_criteria"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupCriterionService/MutateAdGroupCriteria", - request_serializer=ad_group_criterion_service.MutateAdGroupCriteriaRequest.serialize, - response_deserializer=ad_group_criterion_service.MutateAdGroupCriteriaResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_criteria"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdGroupCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/grpc_asyncio.py deleted file mode 100644 index 3df7a6727..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,421 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_criterion_service -from .base import AdGroupCriterionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdGroupCriterionService", - "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.ads.googleads.v19.services.AdGroupCriterionService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupCriterionServiceGrpcAsyncIOTransport( - AdGroupCriterionServiceTransport -): - """gRPC AsyncIO backend transport for AdGroupCriterionService. - - Service to manage ad group criteria. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_group_criteria( - self, - ) -> Callable[ - [ad_group_criterion_service.MutateAdGroupCriteriaRequest], - Awaitable[ad_group_criterion_service.MutateAdGroupCriteriaResponse], - ]: - r"""Return a callable for the mutate ad group criteria method over gRPC. - - Creates, updates, or removes criteria. Operation statuses are - returned. - - List of thrown errors: `AdGroupCriterionError <>`__ - `AdxError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `BiddingError <>`__ - `BiddingStrategyError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DateError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `MultiplierError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `PolicyViolationError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateAdGroupCriteriaRequest], - Awaitable[~.MutateAdGroupCriteriaResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_criteria" not in self._stubs: - self._stubs["mutate_ad_group_criteria"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupCriterionService/MutateAdGroupCriteria", - request_serializer=ad_group_criterion_service.MutateAdGroupCriteriaRequest.serialize, - response_deserializer=ad_group_criterion_service.MutateAdGroupCriteriaResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_criteria"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_group_criteria: self._wrap_method( - self.mutate_ad_group_criteria, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdGroupCriterionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_customizer_service/async_client.py b/google/ads/googleads/v19/services/services/ad_group_customizer_service/async_client.py deleted file mode 100644 index 728cc0169..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_customizer_service/async_client.py +++ /dev/null @@ -1,442 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_customizer_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupCustomizerServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import AdGroupCustomizerServiceClient - -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 AdGroupCustomizerServiceAsyncClient: - """Service to manage ad group customizer""" - - _client: AdGroupCustomizerServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdGroupCustomizerServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AdGroupCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AdGroupCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AdGroupCustomizerServiceClient._DEFAULT_UNIVERSE - - ad_group_path = staticmethod(AdGroupCustomizerServiceClient.ad_group_path) - parse_ad_group_path = staticmethod( - AdGroupCustomizerServiceClient.parse_ad_group_path - ) - ad_group_customizer_path = staticmethod( - AdGroupCustomizerServiceClient.ad_group_customizer_path - ) - parse_ad_group_customizer_path = staticmethod( - AdGroupCustomizerServiceClient.parse_ad_group_customizer_path - ) - customizer_attribute_path = staticmethod( - AdGroupCustomizerServiceClient.customizer_attribute_path - ) - parse_customizer_attribute_path = staticmethod( - AdGroupCustomizerServiceClient.parse_customizer_attribute_path - ) - common_billing_account_path = staticmethod( - AdGroupCustomizerServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdGroupCustomizerServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AdGroupCustomizerServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AdGroupCustomizerServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdGroupCustomizerServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdGroupCustomizerServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AdGroupCustomizerServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AdGroupCustomizerServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdGroupCustomizerServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdGroupCustomizerServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCustomizerServiceAsyncClient: The constructed client. - """ - return AdGroupCustomizerServiceClient.from_service_account_info.__func__(AdGroupCustomizerServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCustomizerServiceAsyncClient: The constructed client. - """ - return AdGroupCustomizerServiceClient.from_service_account_file.__func__(AdGroupCustomizerServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdGroupCustomizerServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdGroupCustomizerServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupCustomizerServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdGroupCustomizerServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupCustomizerServiceTransport, - Callable[..., AdGroupCustomizerServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group customizer service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupCustomizerServiceTransport,Callable[..., AdGroupCustomizerServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupCustomizerServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdGroupCustomizerServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdGroupCustomizerServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupCustomizerService", - "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.ads.googleads.v19.services.AdGroupCustomizerService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_group_customizers( - self, - request: Optional[ - Union[ - ad_group_customizer_service.MutateAdGroupCustomizersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - ad_group_customizer_service.AdGroupCustomizerOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_customizer_service.MutateAdGroupCustomizersResponse: - r"""Creates, updates or removes ad group customizers. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdGroupCustomizersRequest, dict]]): - The request object. Request message for - [AdGroupCustomizerService.MutateAdGroupCustomizers][google.ads.googleads.v19.services.AdGroupCustomizerService.MutateAdGroupCustomizers]. - customer_id (:class:`str`): - Required. The ID of the customer - whose ad group customizers are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdGroupCustomizerOperation]`): - Required. The list of operations to - perform on individual ad group - customizers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupCustomizersResponse: - Response message for an ad group - customizer mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_customizer_service.MutateAdGroupCustomizersRequest - ): - request = ( - ad_group_customizer_service.MutateAdGroupCustomizersRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_group_customizers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AdGroupCustomizerServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdGroupCustomizerServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_customizer_service/client.py b/google/ads/googleads/v19/services/services/ad_group_customizer_service/client.py deleted file mode 100644 index ce1b6669e..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_customizer_service/client.py +++ /dev/null @@ -1,932 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ad_group_customizer_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AdGroupCustomizerServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import AdGroupCustomizerServiceGrpcTransport -from .transports.grpc_asyncio import ( - AdGroupCustomizerServiceGrpcAsyncIOTransport, -) - - -class AdGroupCustomizerServiceClientMeta(type): - """Metaclass for the AdGroupCustomizerService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdGroupCustomizerServiceTransport]] - _transport_registry["grpc"] = AdGroupCustomizerServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AdGroupCustomizerServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdGroupCustomizerServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdGroupCustomizerServiceClient( - metaclass=AdGroupCustomizerServiceClientMeta -): - """Service to manage ad group customizer""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCustomizerServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupCustomizerServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdGroupCustomizerServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupCustomizerServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_group_path( - customer_id: str, - ad_group_id: str, - ) -> str: - """Returns a fully-qualified ad_group string.""" - return "customers/{customer_id}/adGroups/{ad_group_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ) - - @staticmethod - def parse_ad_group_path(path: str) -> Dict[str, str]: - """Parses a ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_customizer_path( - customer_id: str, - ad_group_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified ad_group_customizer string.""" - return "customers/{customer_id}/adGroupCustomizers/{ad_group_id}~{customizer_attribute_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_ad_group_customizer_path(path: str) -> Dict[str, str]: - """Parses a ad_group_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCustomizers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customizer_attribute_path( - customer_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified customizer_attribute string.""" - return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( - customer_id=customer_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_customizer_attribute_path(path: str) -> Dict[str, str]: - """Parses a customizer_attribute path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AdGroupCustomizerServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AdGroupCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = AdGroupCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdGroupCustomizerServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupCustomizerServiceTransport, - Callable[..., AdGroupCustomizerServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group customizer service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupCustomizerServiceTransport,Callable[..., AdGroupCustomizerServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupCustomizerServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdGroupCustomizerServiceClient._read_environment_variables() - self._client_cert_source = ( - AdGroupCustomizerServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AdGroupCustomizerServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AdGroupCustomizerServiceTransport - ) - if transport_provided: - # transport is a AdGroupCustomizerServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AdGroupCustomizerServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdGroupCustomizerServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdGroupCustomizerServiceTransport], - Callable[..., AdGroupCustomizerServiceTransport], - ] = ( - AdGroupCustomizerServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AdGroupCustomizerServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdGroupCustomizerServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupCustomizerService", - "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.ads.googleads.v19.services.AdGroupCustomizerService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_group_customizers( - self, - request: Optional[ - Union[ - ad_group_customizer_service.MutateAdGroupCustomizersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - ad_group_customizer_service.AdGroupCustomizerOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_customizer_service.MutateAdGroupCustomizersResponse: - r"""Creates, updates or removes ad group customizers. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdGroupCustomizersRequest, dict]): - The request object. Request message for - [AdGroupCustomizerService.MutateAdGroupCustomizers][google.ads.googleads.v19.services.AdGroupCustomizerService.MutateAdGroupCustomizers]. - customer_id (str): - Required. The ID of the customer - whose ad group customizers are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupCustomizerOperation]): - Required. The list of operations to - perform on individual ad group - customizers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupCustomizersResponse: - Response message for an ad group - customizer mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_customizer_service.MutateAdGroupCustomizersRequest - ): - request = ( - ad_group_customizer_service.MutateAdGroupCustomizersRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_ad_group_customizers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdGroupCustomizerServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdGroupCustomizerServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/base.py deleted file mode 100644 index 2048b6681..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ad_group_customizer_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdGroupCustomizerServiceTransport(abc.ABC): - """Abstract transport class for AdGroupCustomizerService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_group_customizers: gapic_v1.method.wrap_method( - self.mutate_ad_group_customizers, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_group_customizers( - self, - ) -> Callable[ - [ad_group_customizer_service.MutateAdGroupCustomizersRequest], - Union[ - ad_group_customizer_service.MutateAdGroupCustomizersResponse, - Awaitable[ - ad_group_customizer_service.MutateAdGroupCustomizersResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdGroupCustomizerServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/grpc.py deleted file mode 100644 index e297aba0f..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/grpc.py +++ /dev/null @@ -1,382 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ad_group_customizer_service -from .base import AdGroupCustomizerServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdGroupCustomizerService", - "rpcName": str(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.ads.googleads.v19.services.AdGroupCustomizerService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupCustomizerServiceGrpcTransport(AdGroupCustomizerServiceTransport): - """gRPC backend transport for AdGroupCustomizerService. - - Service to manage ad group customizer - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_group_customizers( - self, - ) -> Callable[ - [ad_group_customizer_service.MutateAdGroupCustomizersRequest], - ad_group_customizer_service.MutateAdGroupCustomizersResponse, - ]: - r"""Return a callable for the mutate ad group customizers method over gRPC. - - Creates, updates or removes ad group customizers. - Operation statuses are returned. - - Returns: - Callable[[~.MutateAdGroupCustomizersRequest], - ~.MutateAdGroupCustomizersResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_customizers" not in self._stubs: - self._stubs["mutate_ad_group_customizers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupCustomizerService/MutateAdGroupCustomizers", - request_serializer=ad_group_customizer_service.MutateAdGroupCustomizersRequest.serialize, - response_deserializer=ad_group_customizer_service.MutateAdGroupCustomizersResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_customizers"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdGroupCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/grpc_asyncio.py deleted file mode 100644 index 04f7d78e8..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,405 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_customizer_service -from .base import AdGroupCustomizerServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdGroupCustomizerService", - "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.ads.googleads.v19.services.AdGroupCustomizerService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupCustomizerServiceGrpcAsyncIOTransport( - AdGroupCustomizerServiceTransport -): - """gRPC AsyncIO backend transport for AdGroupCustomizerService. - - Service to manage ad group customizer - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_group_customizers( - self, - ) -> Callable[ - [ad_group_customizer_service.MutateAdGroupCustomizersRequest], - Awaitable[ad_group_customizer_service.MutateAdGroupCustomizersResponse], - ]: - r"""Return a callable for the mutate ad group customizers method over gRPC. - - Creates, updates or removes ad group customizers. - Operation statuses are returned. - - Returns: - Callable[[~.MutateAdGroupCustomizersRequest], - Awaitable[~.MutateAdGroupCustomizersResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_customizers" not in self._stubs: - self._stubs["mutate_ad_group_customizers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupCustomizerService/MutateAdGroupCustomizers", - request_serializer=ad_group_customizer_service.MutateAdGroupCustomizersRequest.serialize, - response_deserializer=ad_group_customizer_service.MutateAdGroupCustomizersResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_customizers"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_group_customizers: self._wrap_method( - self.mutate_ad_group_customizers, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdGroupCustomizerServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_label_service/async_client.py b/google/ads/googleads/v19/services/services/ad_group_label_service/async_client.py deleted file mode 100644 index 70c003dd7..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_label_service/async_client.py +++ /dev/null @@ -1,430 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_label_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdGroupLabelServiceTransport, DEFAULT_CLIENT_INFO -from .client import AdGroupLabelServiceClient - -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 AdGroupLabelServiceAsyncClient: - """Service to manage labels on ad groups.""" - - _client: AdGroupLabelServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdGroupLabelServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AdGroupLabelServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AdGroupLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AdGroupLabelServiceClient._DEFAULT_UNIVERSE - - ad_group_path = staticmethod(AdGroupLabelServiceClient.ad_group_path) - parse_ad_group_path = staticmethod( - AdGroupLabelServiceClient.parse_ad_group_path - ) - ad_group_label_path = staticmethod( - AdGroupLabelServiceClient.ad_group_label_path - ) - parse_ad_group_label_path = staticmethod( - AdGroupLabelServiceClient.parse_ad_group_label_path - ) - label_path = staticmethod(AdGroupLabelServiceClient.label_path) - parse_label_path = staticmethod(AdGroupLabelServiceClient.parse_label_path) - common_billing_account_path = staticmethod( - AdGroupLabelServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdGroupLabelServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AdGroupLabelServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AdGroupLabelServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdGroupLabelServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdGroupLabelServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AdGroupLabelServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AdGroupLabelServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdGroupLabelServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdGroupLabelServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupLabelServiceAsyncClient: The constructed client. - """ - return AdGroupLabelServiceClient.from_service_account_info.__func__(AdGroupLabelServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupLabelServiceAsyncClient: The constructed client. - """ - return AdGroupLabelServiceClient.from_service_account_file.__func__(AdGroupLabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdGroupLabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdGroupLabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupLabelServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdGroupLabelServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupLabelServiceTransport, - Callable[..., AdGroupLabelServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group label service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupLabelServiceTransport,Callable[..., AdGroupLabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupLabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdGroupLabelServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdGroupLabelServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupLabelService", - "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.ads.googleads.v19.services.AdGroupLabelService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_group_labels( - self, - request: Optional[ - Union[ad_group_label_service.MutateAdGroupLabelsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_label_service.AdGroupLabelOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_label_service.MutateAdGroupLabelsResponse: - r"""Creates and removes ad group labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdGroupLabelsRequest, dict]]): - The request object. Request message for - [AdGroupLabelService.MutateAdGroupLabels][google.ads.googleads.v19.services.AdGroupLabelService.MutateAdGroupLabels]. - customer_id (:class:`str`): - Required. ID of the customer whose ad - group labels are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdGroupLabelOperation]`): - Required. The list of operations to - perform on ad group labels. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupLabelsResponse: - Response message for an ad group - labels mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_label_service.MutateAdGroupLabelsRequest - ): - request = ad_group_label_service.MutateAdGroupLabelsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_group_labels - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AdGroupLabelServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdGroupLabelServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_label_service/client.py b/google/ads/googleads/v19/services/services/ad_group_label_service/client.py deleted file mode 100644 index 4f0720eb4..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_label_service/client.py +++ /dev/null @@ -1,917 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ad_group_label_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdGroupLabelServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AdGroupLabelServiceGrpcTransport -from .transports.grpc_asyncio import AdGroupLabelServiceGrpcAsyncIOTransport - - -class AdGroupLabelServiceClientMeta(type): - """Metaclass for the AdGroupLabelService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdGroupLabelServiceTransport]] - _transport_registry["grpc"] = AdGroupLabelServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AdGroupLabelServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdGroupLabelServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdGroupLabelServiceClient(metaclass=AdGroupLabelServiceClientMeta): - """Service to manage labels on ad groups.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupLabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupLabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdGroupLabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupLabelServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_group_path( - customer_id: str, - ad_group_id: str, - ) -> str: - """Returns a fully-qualified ad_group string.""" - return "customers/{customer_id}/adGroups/{ad_group_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ) - - @staticmethod - def parse_ad_group_path(path: str) -> Dict[str, str]: - """Parses a ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_label_path( - customer_id: str, - ad_group_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_label string.""" - return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def label_path( - customer_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified label string.""" - return "customers/{customer_id}/labels/{label_id}".format( - customer_id=customer_id, - label_id=label_id, - ) - - @staticmethod - def parse_label_path(path: str) -> Dict[str, str]: - """Parses a label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/labels/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AdGroupLabelServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AdGroupLabelServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AdGroupLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdGroupLabelServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupLabelServiceTransport, - Callable[..., AdGroupLabelServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group label service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupLabelServiceTransport,Callable[..., AdGroupLabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupLabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdGroupLabelServiceClient._read_environment_variables() - self._client_cert_source = ( - AdGroupLabelServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = AdGroupLabelServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, AdGroupLabelServiceTransport) - if transport_provided: - # transport is a AdGroupLabelServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AdGroupLabelServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdGroupLabelServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdGroupLabelServiceTransport], - Callable[..., AdGroupLabelServiceTransport], - ] = ( - AdGroupLabelServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AdGroupLabelServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdGroupLabelServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupLabelService", - "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.ads.googleads.v19.services.AdGroupLabelService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_group_labels( - self, - request: Optional[ - Union[ad_group_label_service.MutateAdGroupLabelsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_label_service.AdGroupLabelOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_label_service.MutateAdGroupLabelsResponse: - r"""Creates and removes ad group labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdGroupLabelsRequest, dict]): - The request object. Request message for - [AdGroupLabelService.MutateAdGroupLabels][google.ads.googleads.v19.services.AdGroupLabelService.MutateAdGroupLabels]. - customer_id (str): - Required. ID of the customer whose ad - group labels are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupLabelOperation]): - Required. The list of operations to - perform on ad group labels. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupLabelsResponse: - Response message for an ad group - labels mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_group_label_service.MutateAdGroupLabelsRequest - ): - request = ad_group_label_service.MutateAdGroupLabelsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_ad_group_labels - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdGroupLabelServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdGroupLabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_label_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_group_label_service/transports/base.py deleted file mode 100644 index 1d9dc8668..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_label_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ad_group_label_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdGroupLabelServiceTransport(abc.ABC): - """Abstract transport class for AdGroupLabelService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_group_labels: gapic_v1.method.wrap_method( - self.mutate_ad_group_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_group_labels( - self, - ) -> Callable[ - [ad_group_label_service.MutateAdGroupLabelsRequest], - Union[ - ad_group_label_service.MutateAdGroupLabelsResponse, - Awaitable[ad_group_label_service.MutateAdGroupLabelsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdGroupLabelServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_label_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_group_label_service/transports/grpc.py deleted file mode 100644 index 387eedd2a..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_label_service/transports/grpc.py +++ /dev/null @@ -1,388 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ad_group_label_service -from .base import AdGroupLabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdGroupLabelService", - "rpcName": str(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.ads.googleads.v19.services.AdGroupLabelService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupLabelServiceGrpcTransport(AdGroupLabelServiceTransport): - """gRPC backend transport for AdGroupLabelService. - - Service to manage labels on ad groups. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_group_labels( - self, - ) -> Callable[ - [ad_group_label_service.MutateAdGroupLabelsRequest], - ad_group_label_service.MutateAdGroupLabelsResponse, - ]: - r"""Return a callable for the mutate ad group labels method over gRPC. - - Creates and removes ad group labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateAdGroupLabelsRequest], - ~.MutateAdGroupLabelsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_labels" not in self._stubs: - self._stubs["mutate_ad_group_labels"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupLabelService/MutateAdGroupLabels", - request_serializer=ad_group_label_service.MutateAdGroupLabelsRequest.serialize, - response_deserializer=ad_group_label_service.MutateAdGroupLabelsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_labels"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdGroupLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_label_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_group_label_service/transports/grpc_asyncio.py deleted file mode 100644 index 4d760a4f0..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_label_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_label_service -from .base import AdGroupLabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdGroupLabelService", - "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.ads.googleads.v19.services.AdGroupLabelService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupLabelServiceGrpcAsyncIOTransport(AdGroupLabelServiceTransport): - """gRPC AsyncIO backend transport for AdGroupLabelService. - - Service to manage labels on ad groups. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_group_labels( - self, - ) -> Callable[ - [ad_group_label_service.MutateAdGroupLabelsRequest], - Awaitable[ad_group_label_service.MutateAdGroupLabelsResponse], - ]: - r"""Return a callable for the mutate ad group labels method over gRPC. - - Creates and removes ad group labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateAdGroupLabelsRequest], - Awaitable[~.MutateAdGroupLabelsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_group_labels" not in self._stubs: - self._stubs["mutate_ad_group_labels"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupLabelService/MutateAdGroupLabels", - request_serializer=ad_group_label_service.MutateAdGroupLabelsRequest.serialize, - response_deserializer=ad_group_label_service.MutateAdGroupLabelsResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_group_labels"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_group_labels: self._wrap_method( - self.mutate_ad_group_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdGroupLabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_service/async_client.py b/google/ads/googleads/v19/services/services/ad_group_service/async_client.py deleted file mode 100644 index acfd3ff96..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_service/async_client.py +++ /dev/null @@ -1,427 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdGroupServiceTransport, DEFAULT_CLIENT_INFO -from .client import AdGroupServiceClient - -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 AdGroupServiceAsyncClient: - """Service to manage ad groups.""" - - _client: AdGroupServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdGroupServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AdGroupServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = AdGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = AdGroupServiceClient._DEFAULT_UNIVERSE - - ad_group_path = staticmethod(AdGroupServiceClient.ad_group_path) - parse_ad_group_path = staticmethod(AdGroupServiceClient.parse_ad_group_path) - ad_group_label_path = staticmethod(AdGroupServiceClient.ad_group_label_path) - parse_ad_group_label_path = staticmethod( - AdGroupServiceClient.parse_ad_group_label_path - ) - campaign_path = staticmethod(AdGroupServiceClient.campaign_path) - parse_campaign_path = staticmethod(AdGroupServiceClient.parse_campaign_path) - common_billing_account_path = staticmethod( - AdGroupServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdGroupServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(AdGroupServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - AdGroupServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdGroupServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdGroupServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod(AdGroupServiceClient.common_project_path) - parse_common_project_path = staticmethod( - AdGroupServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdGroupServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdGroupServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupServiceAsyncClient: The constructed client. - """ - return AdGroupServiceClient.from_service_account_info.__func__(AdGroupServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupServiceAsyncClient: The constructed client. - """ - return AdGroupServiceClient.from_service_account_file.__func__(AdGroupServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdGroupServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdGroupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdGroupServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupServiceTransport, - Callable[..., AdGroupServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupServiceTransport,Callable[..., AdGroupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdGroupServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdGroupServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupService", - "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.ads.googleads.v19.services.AdGroupService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_groups( - self, - request: Optional[ - Union[ad_group_service.MutateAdGroupsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_service.AdGroupOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_service.MutateAdGroupsResponse: - r"""Creates, updates, or removes ad groups. Operation statuses are - returned. - - List of thrown errors: `AdGroupError <>`__ `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MultiplierError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdGroupsRequest, dict]]): - The request object. Request message for - [AdGroupService.MutateAdGroups][google.ads.googleads.v19.services.AdGroupService.MutateAdGroups]. - customer_id (:class:`str`): - Required. The ID of the customer - whose ad groups are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdGroupOperation]`): - Required. The list of operations to - perform on individual ad groups. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupsResponse: - Response message for an ad group - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, ad_group_service.MutateAdGroupsRequest): - request = ad_group_service.MutateAdGroupsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_groups - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AdGroupServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdGroupServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_service/client.py b/google/ads/googleads/v19/services/services/ad_group_service/client.py deleted file mode 100644 index f1e86ceec..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_service/client.py +++ /dev/null @@ -1,917 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ad_group_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdGroupServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AdGroupServiceGrpcTransport -from .transports.grpc_asyncio import AdGroupServiceGrpcAsyncIOTransport - - -class AdGroupServiceClientMeta(type): - """Metaclass for the AdGroupService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdGroupServiceTransport]] - _transport_registry["grpc"] = AdGroupServiceGrpcTransport - _transport_registry["grpc_asyncio"] = AdGroupServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdGroupServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdGroupServiceClient(metaclass=AdGroupServiceClientMeta): - """Service to manage ad groups.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdGroupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdGroupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdGroupServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_group_path( - customer_id: str, - ad_group_id: str, - ) -> str: - """Returns a fully-qualified ad_group string.""" - return "customers/{customer_id}/adGroups/{ad_group_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ) - - @staticmethod - def parse_ad_group_path(path: str) -> Dict[str, str]: - """Parses a ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_label_path( - customer_id: str, - ad_group_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_label string.""" - return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AdGroupServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AdGroupServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AdGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdGroupServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdGroupServiceTransport, - Callable[..., AdGroupServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad group service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdGroupServiceTransport,Callable[..., AdGroupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdGroupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdGroupServiceClient._read_environment_variables() - self._client_cert_source = AdGroupServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - self._universe_domain = AdGroupServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, AdGroupServiceTransport) - if transport_provided: - # transport is a AdGroupServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AdGroupServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdGroupServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdGroupServiceTransport], - Callable[..., AdGroupServiceTransport], - ] = ( - AdGroupServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., AdGroupServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdGroupServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdGroupService", - "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.ads.googleads.v19.services.AdGroupService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_groups( - self, - request: Optional[ - Union[ad_group_service.MutateAdGroupsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_group_service.AdGroupOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_group_service.MutateAdGroupsResponse: - r"""Creates, updates, or removes ad groups. Operation statuses are - returned. - - List of thrown errors: `AdGroupError <>`__ `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MultiplierError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdGroupsRequest, dict]): - The request object. Request message for - [AdGroupService.MutateAdGroups][google.ads.googleads.v19.services.AdGroupService.MutateAdGroups]. - customer_id (str): - Required. The ID of the customer - whose ad groups are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupOperation]): - Required. The list of operations to - perform on individual ad groups. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdGroupsResponse: - Response message for an ad group - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, ad_group_service.MutateAdGroupsRequest): - request = ad_group_service.MutateAdGroupsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.mutate_ad_groups] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdGroupServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdGroupServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_group_service/transports/base.py deleted file mode 100644 index 05145b924..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ad_group_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdGroupServiceTransport(abc.ABC): - """Abstract transport class for AdGroupService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_groups: gapic_v1.method.wrap_method( - self.mutate_ad_groups, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_groups( - self, - ) -> Callable[ - [ad_group_service.MutateAdGroupsRequest], - Union[ - ad_group_service.MutateAdGroupsResponse, - Awaitable[ad_group_service.MutateAdGroupsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdGroupServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_group_service/transports/grpc.py deleted file mode 100644 index 3014c14e3..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_service/transports/grpc.py +++ /dev/null @@ -1,395 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ad_group_service -from .base import AdGroupServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdGroupService", - "rpcName": str(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.ads.googleads.v19.services.AdGroupService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupServiceGrpcTransport(AdGroupServiceTransport): - """gRPC backend transport for AdGroupService. - - Service to manage ad groups. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_groups( - self, - ) -> Callable[ - [ad_group_service.MutateAdGroupsRequest], - ad_group_service.MutateAdGroupsResponse, - ]: - r"""Return a callable for the mutate ad groups method over gRPC. - - Creates, updates, or removes ad groups. Operation statuses are - returned. - - List of thrown errors: `AdGroupError <>`__ `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MultiplierError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateAdGroupsRequest], - ~.MutateAdGroupsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_groups" not in self._stubs: - self._stubs["mutate_ad_groups"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupService/MutateAdGroups", - request_serializer=ad_group_service.MutateAdGroupsRequest.serialize, - response_deserializer=ad_group_service.MutateAdGroupsResponse.deserialize, - ) - return self._stubs["mutate_ad_groups"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_group_service/transports/grpc_asyncio.py deleted file mode 100644 index a84e95f89..000000000 --- a/google/ads/googleads/v19/services/services/ad_group_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,416 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ad_group_service -from .base import AdGroupServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdGroupService", - "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.ads.googleads.v19.services.AdGroupService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdGroupServiceGrpcAsyncIOTransport(AdGroupServiceTransport): - """gRPC AsyncIO backend transport for AdGroupService. - - Service to manage ad groups. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_groups( - self, - ) -> Callable[ - [ad_group_service.MutateAdGroupsRequest], - Awaitable[ad_group_service.MutateAdGroupsResponse], - ]: - r"""Return a callable for the mutate ad groups method over gRPC. - - Creates, updates, or removes ad groups. Operation statuses are - returned. - - List of thrown errors: `AdGroupError <>`__ `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MultiplierError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateAdGroupsRequest], - Awaitable[~.MutateAdGroupsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_groups" not in self._stubs: - self._stubs["mutate_ad_groups"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdGroupService/MutateAdGroups", - request_serializer=ad_group_service.MutateAdGroupsRequest.serialize, - response_deserializer=ad_group_service.MutateAdGroupsResponse.deserialize, - ) - return self._stubs["mutate_ad_groups"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_groups: self._wrap_method( - self.mutate_ad_groups, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdGroupServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_parameter_service/async_client.py b/google/ads/googleads/v19/services/services/ad_parameter_service/async_client.py deleted file mode 100644 index e498104eb..000000000 --- a/google/ads/googleads/v19/services/services/ad_parameter_service/async_client.py +++ /dev/null @@ -1,428 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ad_parameter_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdParameterServiceTransport, DEFAULT_CLIENT_INFO -from .client import AdParameterServiceClient - -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 AdParameterServiceAsyncClient: - """Service to manage ad parameters.""" - - _client: AdParameterServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdParameterServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AdParameterServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AdParameterServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AdParameterServiceClient._DEFAULT_UNIVERSE - - ad_group_criterion_path = staticmethod( - AdParameterServiceClient.ad_group_criterion_path - ) - parse_ad_group_criterion_path = staticmethod( - AdParameterServiceClient.parse_ad_group_criterion_path - ) - ad_parameter_path = staticmethod(AdParameterServiceClient.ad_parameter_path) - parse_ad_parameter_path = staticmethod( - AdParameterServiceClient.parse_ad_parameter_path - ) - common_billing_account_path = staticmethod( - AdParameterServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdParameterServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AdParameterServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AdParameterServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdParameterServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdParameterServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AdParameterServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AdParameterServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AdParameterServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AdParameterServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdParameterServiceAsyncClient: The constructed client. - """ - return AdParameterServiceClient.from_service_account_info.__func__(AdParameterServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdParameterServiceAsyncClient: The constructed client. - """ - return AdParameterServiceClient.from_service_account_file.__func__(AdParameterServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdParameterServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdParameterServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdParameterServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdParameterServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdParameterServiceTransport, - Callable[..., AdParameterServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad parameter service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdParameterServiceTransport,Callable[..., AdParameterServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdParameterServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdParameterServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdParameterServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdParameterService", - "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.ads.googleads.v19.services.AdParameterService", - "credentialsType": None, - } - ), - ) - - async def mutate_ad_parameters( - self, - request: Optional[ - Union[ad_parameter_service.MutateAdParametersRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_parameter_service.AdParameterOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_parameter_service.MutateAdParametersResponse: - r"""Creates, updates, or removes ad parameters. Operation statuses - are returned. - - List of thrown errors: `AdParameterError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdParametersRequest, dict]]): - The request object. Request message for - [AdParameterService.MutateAdParameters][google.ads.googleads.v19.services.AdParameterService.MutateAdParameters] - customer_id (:class:`str`): - Required. The ID of the customer - whose ad parameters are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdParameterOperation]`): - Required. The list of operations to - perform on individual ad parameters. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdParametersResponse: - Response message for an ad parameter - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_parameter_service.MutateAdParametersRequest - ): - request = ad_parameter_service.MutateAdParametersRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ad_parameters - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AdParameterServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdParameterServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_parameter_service/client.py b/google/ads/googleads/v19/services/services/ad_parameter_service/client.py deleted file mode 100644 index 72996a1e0..000000000 --- a/google/ads/googleads/v19/services/services/ad_parameter_service/client.py +++ /dev/null @@ -1,898 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ad_parameter_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdParameterServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AdParameterServiceGrpcTransport -from .transports.grpc_asyncio import AdParameterServiceGrpcAsyncIOTransport - - -class AdParameterServiceClientMeta(type): - """Metaclass for the AdParameterService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdParameterServiceTransport]] - _transport_registry["grpc"] = AdParameterServiceGrpcTransport - _transport_registry["grpc_asyncio"] = AdParameterServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdParameterServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdParameterServiceClient(metaclass=AdParameterServiceClientMeta): - """Service to manage ad parameters.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdParameterServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdParameterServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdParameterServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdParameterServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_group_criterion_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion string.""" - return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_parameter_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - parameter_index: str, - ) -> str: - """Returns a fully-qualified ad_parameter string.""" - return "customers/{customer_id}/adParameters/{ad_group_id}~{criterion_id}~{parameter_index}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - parameter_index=parameter_index, - ) - - @staticmethod - def parse_ad_parameter_path(path: str) -> Dict[str, str]: - """Parses a ad_parameter path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adParameters/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AdParameterServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AdParameterServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AdParameterServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdParameterServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AdParameterServiceTransport, - Callable[..., AdParameterServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad parameter service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdParameterServiceTransport,Callable[..., AdParameterServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdParameterServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdParameterServiceClient._read_environment_variables() - self._client_cert_source = ( - AdParameterServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = AdParameterServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, AdParameterServiceTransport) - if transport_provided: - # transport is a AdParameterServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AdParameterServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdParameterServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdParameterServiceTransport], - Callable[..., AdParameterServiceTransport], - ] = ( - AdParameterServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., AdParameterServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdParameterServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdParameterService", - "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.ads.googleads.v19.services.AdParameterService", - "credentialsType": None, - } - ), - ) - - def mutate_ad_parameters( - self, - request: Optional[ - Union[ad_parameter_service.MutateAdParametersRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ad_parameter_service.AdParameterOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_parameter_service.MutateAdParametersResponse: - r"""Creates, updates, or removes ad parameters. Operation statuses - are returned. - - List of thrown errors: `AdParameterError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdParametersRequest, dict]): - The request object. Request message for - [AdParameterService.MutateAdParameters][google.ads.googleads.v19.services.AdParameterService.MutateAdParameters] - customer_id (str): - Required. The ID of the customer - whose ad parameters are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdParameterOperation]): - Required. The list of operations to - perform on individual ad parameters. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdParametersResponse: - Response message for an ad parameter - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, ad_parameter_service.MutateAdParametersRequest - ): - request = ad_parameter_service.MutateAdParametersRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_ad_parameters - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdParameterServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdParameterServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_parameter_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_parameter_service/transports/base.py deleted file mode 100644 index 90355b796..000000000 --- a/google/ads/googleads/v19/services/services/ad_parameter_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ad_parameter_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdParameterServiceTransport(abc.ABC): - """Abstract transport class for AdParameterService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ad_parameters: gapic_v1.method.wrap_method( - self.mutate_ad_parameters, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ad_parameters( - self, - ) -> Callable[ - [ad_parameter_service.MutateAdParametersRequest], - Union[ - ad_parameter_service.MutateAdParametersResponse, - Awaitable[ad_parameter_service.MutateAdParametersResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdParameterServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_parameter_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_parameter_service/transports/grpc.py deleted file mode 100644 index ab521ec28..000000000 --- a/google/ads/googleads/v19/services/services/ad_parameter_service/transports/grpc.py +++ /dev/null @@ -1,388 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ad_parameter_service -from .base import AdParameterServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdParameterService", - "rpcName": str(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.ads.googleads.v19.services.AdParameterService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdParameterServiceGrpcTransport(AdParameterServiceTransport): - """gRPC backend transport for AdParameterService. - - Service to manage ad parameters. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ad_parameters( - self, - ) -> Callable[ - [ad_parameter_service.MutateAdParametersRequest], - ad_parameter_service.MutateAdParametersResponse, - ]: - r"""Return a callable for the mutate ad parameters method over gRPC. - - Creates, updates, or removes ad parameters. Operation statuses - are returned. - - List of thrown errors: `AdParameterError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateAdParametersRequest], - ~.MutateAdParametersResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_parameters" not in self._stubs: - self._stubs["mutate_ad_parameters"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdParameterService/MutateAdParameters", - request_serializer=ad_parameter_service.MutateAdParametersRequest.serialize, - response_deserializer=ad_parameter_service.MutateAdParametersResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_parameters"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdParameterServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_parameter_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_parameter_service/transports/grpc_asyncio.py deleted file mode 100644 index 208ecde3e..000000000 --- a/google/ads/googleads/v19/services/services/ad_parameter_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ad_parameter_service -from .base import AdParameterServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdParameterService", - "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.ads.googleads.v19.services.AdParameterService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdParameterServiceGrpcAsyncIOTransport(AdParameterServiceTransport): - """gRPC AsyncIO backend transport for AdParameterService. - - Service to manage ad parameters. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ad_parameters( - self, - ) -> Callable[ - [ad_parameter_service.MutateAdParametersRequest], - Awaitable[ad_parameter_service.MutateAdParametersResponse], - ]: - r"""Return a callable for the mutate ad parameters method over gRPC. - - Creates, updates, or removes ad parameters. Operation statuses - are returned. - - List of thrown errors: `AdParameterError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateAdParametersRequest], - Awaitable[~.MutateAdParametersResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ad_parameters" not in self._stubs: - self._stubs["mutate_ad_parameters"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdParameterService/MutateAdParameters", - request_serializer=ad_parameter_service.MutateAdParametersRequest.serialize, - response_deserializer=ad_parameter_service.MutateAdParametersResponse.deserialize, - ) - ) - return self._stubs["mutate_ad_parameters"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ad_parameters: self._wrap_method( - self.mutate_ad_parameters, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdParameterServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_service/async_client.py b/google/ads/googleads/v19/services/services/ad_service/async_client.py deleted file mode 100644 index 809fe4921..000000000 --- a/google/ads/googleads/v19/services/services/ad_service/async_client.py +++ /dev/null @@ -1,412 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ad_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdServiceTransport, DEFAULT_CLIENT_INFO -from .client import AdServiceClient - -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 AdServiceAsyncClient: - """Service to manage ads.""" - - _client: AdServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AdServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AdServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = AdServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = AdServiceClient._DEFAULT_UNIVERSE - - ad_path = staticmethod(AdServiceClient.ad_path) - parse_ad_path = staticmethod(AdServiceClient.parse_ad_path) - common_billing_account_path = staticmethod( - AdServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AdServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(AdServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - AdServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AdServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AdServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod(AdServiceClient.common_project_path) - parse_common_project_path = staticmethod( - AdServiceClient.parse_common_project_path - ) - common_location_path = staticmethod(AdServiceClient.common_location_path) - parse_common_location_path = staticmethod( - AdServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdServiceAsyncClient: The constructed client. - """ - return AdServiceClient.from_service_account_info.__func__(AdServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdServiceAsyncClient: The constructed client. - """ - return AdServiceClient.from_service_account_file.__func__(AdServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AdServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AdServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AdServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[str, AdServiceTransport, Callable[..., AdServiceTransport]] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdServiceTransport,Callable[..., AdServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AdServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AdServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdService", - "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.ads.googleads.v19.services.AdService", - "credentialsType": None, - } - ), - ) - - async def mutate_ads( - self, - request: Optional[Union[ad_service.MutateAdsRequest, dict]] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[MutableSequence[ad_service.AdOperation]] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_service.MutateAdsResponse: - r"""Updates ads. Operation statuses are returned. Updating ads is - not supported for TextAd, ExpandedDynamicSearchAd, GmailAd and - ImageAd. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdSharingError <>`__ `AdxError <>`__ `AssetError <>`__ - `AssetLinkError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FeedAttributeReferenceError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `FunctionError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ - `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `PolicyFindingError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAdsRequest, dict]]): - The request object. Request message for - [AdService.MutateAds][google.ads.googleads.v19.services.AdService.MutateAds]. - customer_id (:class:`str`): - Required. The ID of the customer - whose ads are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AdOperation]`): - Required. The list of operations to - perform on individual ads. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdsResponse: - Response message for an ad mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, ad_service.MutateAdsRequest): - request = ad_service.MutateAdsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_ads - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AdServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AdServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/ad_service/client.py b/google/ads/googleads/v19/services/services/ad_service/client.py deleted file mode 100644 index 5c29388e8..000000000 --- a/google/ads/googleads/v19/services/services/ad_service/client.py +++ /dev/null @@ -1,864 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ad_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AdServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AdServiceGrpcTransport -from .transports.grpc_asyncio import AdServiceGrpcAsyncIOTransport - - -class AdServiceClientMeta(type): - """Metaclass for the AdService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AdServiceTransport]] - _transport_registry["grpc"] = AdServiceGrpcTransport - _transport_registry["grpc_asyncio"] = AdServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AdServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AdServiceClient(metaclass=AdServiceClientMeta): - """Service to manage ads.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AdServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AdServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AdServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_path( - customer_id: str, - ad_id: str, - ) -> str: - """Returns a fully-qualified ad string.""" - return "customers/{customer_id}/ads/{ad_id}".format( - customer_id=customer_id, - ad_id=ad_id, - ) - - @staticmethod - def parse_ad_path(path: str) -> Dict[str, str]: - """Parses a ad path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/ads/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AdServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AdServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = AdServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AdServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[str, AdServiceTransport, Callable[..., AdServiceTransport]] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the ad service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AdServiceTransport,Callable[..., AdServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AdServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AdServiceClient._read_environment_variables() - self._client_cert_source = AdServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - self._universe_domain = AdServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, AdServiceTransport) - if transport_provided: - # transport is a AdServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AdServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AdServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AdServiceTransport], Callable[..., AdServiceTransport] - ] = ( - AdServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., AdServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AdServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AdService", - "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.ads.googleads.v19.services.AdService", - "credentialsType": None, - } - ), - ) - - def mutate_ads( - self, - request: Optional[Union[ad_service.MutateAdsRequest, dict]] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[MutableSequence[ad_service.AdOperation]] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ad_service.MutateAdsResponse: - r"""Updates ads. Operation statuses are returned. Updating ads is - not supported for TextAd, ExpandedDynamicSearchAd, GmailAd and - ImageAd. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdSharingError <>`__ `AdxError <>`__ `AssetError <>`__ - `AssetLinkError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FeedAttributeReferenceError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `FunctionError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ - `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `PolicyFindingError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAdsRequest, dict]): - The request object. Request message for - [AdService.MutateAds][google.ads.googleads.v19.services.AdService.MutateAds]. - customer_id (str): - Required. The ID of the customer - whose ads are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdOperation]): - Required. The list of operations to - perform on individual ads. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAdsResponse: - Response message for an ad mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, ad_service.MutateAdsRequest): - request = ad_service.MutateAdsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.mutate_ads] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AdServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AdServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_service/transports/base.py b/google/ads/googleads/v19/services/services/ad_service/transports/base.py deleted file mode 100644 index a48cec6e6..000000000 --- a/google/ads/googleads/v19/services/services/ad_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ad_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AdServiceTransport(abc.ABC): - """Abstract transport class for AdService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_ads: gapic_v1.method.wrap_method( - self.mutate_ads, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_ads( - self, - ) -> Callable[ - [ad_service.MutateAdsRequest], - Union[ - ad_service.MutateAdsResponse, - Awaitable[ad_service.MutateAdsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AdServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_service/transports/grpc.py b/google/ads/googleads/v19/services/services/ad_service/transports/grpc.py deleted file mode 100644 index 5fe34110e..000000000 --- a/google/ads/googleads/v19/services/services/ad_service/transports/grpc.py +++ /dev/null @@ -1,395 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ad_service -from .base import AdServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AdService", - "rpcName": str(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.ads.googleads.v19.services.AdService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdServiceGrpcTransport(AdServiceTransport): - """gRPC backend transport for AdService. - - Service to manage ads. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_ads( - self, - ) -> Callable[[ad_service.MutateAdsRequest], ad_service.MutateAdsResponse]: - r"""Return a callable for the mutate ads method over gRPC. - - Updates ads. Operation statuses are returned. Updating ads is - not supported for TextAd, ExpandedDynamicSearchAd, GmailAd and - ImageAd. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdSharingError <>`__ `AdxError <>`__ `AssetError <>`__ - `AssetLinkError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FeedAttributeReferenceError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `FunctionError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ - `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `PolicyFindingError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateAdsRequest], - ~.MutateAdsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ads" not in self._stubs: - self._stubs["mutate_ads"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdService/MutateAds", - request_serializer=ad_service.MutateAdsRequest.serialize, - response_deserializer=ad_service.MutateAdsResponse.deserialize, - ) - return self._stubs["mutate_ads"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AdServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/ad_service/transports/grpc_asyncio.py deleted file mode 100644 index 2a4a6c847..000000000 --- a/google/ads/googleads/v19/services/services/ad_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,418 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ad_service -from .base import AdServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AdService", - "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.ads.googleads.v19.services.AdService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AdServiceGrpcAsyncIOTransport(AdServiceTransport): - """gRPC AsyncIO backend transport for AdService. - - Service to manage ads. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_ads( - self, - ) -> Callable[ - [ad_service.MutateAdsRequest], Awaitable[ad_service.MutateAdsResponse] - ]: - r"""Return a callable for the mutate ads method over gRPC. - - Updates ads. Operation statuses are returned. Updating ads is - not supported for TextAd, ExpandedDynamicSearchAd, GmailAd and - ImageAd. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdSharingError <>`__ `AdxError <>`__ `AssetError <>`__ - `AssetLinkError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FeedAttributeReferenceError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `FunctionError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ - `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `PolicyFindingError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateAdsRequest], - Awaitable[~.MutateAdsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_ads" not in self._stubs: - self._stubs["mutate_ads"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AdService/MutateAds", - request_serializer=ad_service.MutateAdsRequest.serialize, - response_deserializer=ad_service.MutateAdsResponse.deserialize, - ) - return self._stubs["mutate_ads"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_ads: self._wrap_method( - self.mutate_ads, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AdServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_asset_service/async_client.py b/google/ads/googleads/v19/services/services/asset_group_asset_service/async_client.py deleted file mode 100644 index ab6772321..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_asset_service/async_client.py +++ /dev/null @@ -1,435 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import asset_group_asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AssetGroupAssetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import AssetGroupAssetServiceClient - -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 AssetGroupAssetServiceAsyncClient: - """Service to manage asset group asset.""" - - _client: AssetGroupAssetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AssetGroupAssetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AssetGroupAssetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AssetGroupAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AssetGroupAssetServiceClient._DEFAULT_UNIVERSE - - asset_path = staticmethod(AssetGroupAssetServiceClient.asset_path) - parse_asset_path = staticmethod( - AssetGroupAssetServiceClient.parse_asset_path - ) - asset_group_path = staticmethod( - AssetGroupAssetServiceClient.asset_group_path - ) - parse_asset_group_path = staticmethod( - AssetGroupAssetServiceClient.parse_asset_group_path - ) - asset_group_asset_path = staticmethod( - AssetGroupAssetServiceClient.asset_group_asset_path - ) - parse_asset_group_asset_path = staticmethod( - AssetGroupAssetServiceClient.parse_asset_group_asset_path - ) - common_billing_account_path = staticmethod( - AssetGroupAssetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AssetGroupAssetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AssetGroupAssetServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AssetGroupAssetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AssetGroupAssetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AssetGroupAssetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AssetGroupAssetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AssetGroupAssetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AssetGroupAssetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AssetGroupAssetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupAssetServiceAsyncClient: The constructed client. - """ - return AssetGroupAssetServiceClient.from_service_account_info.__func__(AssetGroupAssetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupAssetServiceAsyncClient: The constructed client. - """ - return AssetGroupAssetServiceClient.from_service_account_file.__func__(AssetGroupAssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AssetGroupAssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AssetGroupAssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetGroupAssetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AssetGroupAssetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetGroupAssetServiceTransport, - Callable[..., AssetGroupAssetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset group asset service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetGroupAssetServiceTransport,Callable[..., AssetGroupAssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetGroupAssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AssetGroupAssetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AssetGroupAssetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetGroupAssetService", - "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.ads.googleads.v19.services.AssetGroupAssetService", - "credentialsType": None, - } - ), - ) - - async def mutate_asset_group_assets( - self, - request: Optional[ - Union[asset_group_asset_service.MutateAssetGroupAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[asset_group_asset_service.AssetGroupAssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_group_asset_service.MutateAssetGroupAssetsResponse: - r"""Creates, updates or removes asset group assets. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAssetGroupAssetsRequest, dict]]): - The request object. Request message for - [AssetGroupAssetService.MutateAssetGroupAssets][google.ads.googleads.v19.services.AssetGroupAssetService.MutateAssetGroupAssets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose asset group assets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AssetGroupAssetOperation]`): - Required. The list of operations to - perform on individual asset group - assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetGroupAssetsResponse: - Response message for an asset group - asset mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, asset_group_asset_service.MutateAssetGroupAssetsRequest - ): - request = asset_group_asset_service.MutateAssetGroupAssetsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_asset_group_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AssetGroupAssetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AssetGroupAssetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_asset_service/client.py b/google/ads/googleads/v19/services/services/asset_group_asset_service/client.py deleted file mode 100644 index f21b87b09..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_asset_service/client.py +++ /dev/null @@ -1,924 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import asset_group_asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AssetGroupAssetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import AssetGroupAssetServiceGrpcTransport -from .transports.grpc_asyncio import AssetGroupAssetServiceGrpcAsyncIOTransport - - -class AssetGroupAssetServiceClientMeta(type): - """Metaclass for the AssetGroupAssetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AssetGroupAssetServiceTransport]] - _transport_registry["grpc"] = AssetGroupAssetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AssetGroupAssetServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AssetGroupAssetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AssetGroupAssetServiceClient(metaclass=AssetGroupAssetServiceClientMeta): - """Service to manage asset group asset.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupAssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupAssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AssetGroupAssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetGroupAssetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_path( - customer_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset string.""" - return "customers/{customer_id}/assets/{asset_id}".format( - customer_id=customer_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_path(path: str) -> Dict[str, str]: - """Parses a asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assets/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_path( - customer_id: str, - asset_group_id: str, - ) -> str: - """Returns a fully-qualified asset_group string.""" - return "customers/{customer_id}/assetGroups/{asset_group_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - ) - - @staticmethod - def parse_asset_group_path(path: str) -> Dict[str, str]: - """Parses a asset_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_asset_path( - customer_id: str, - asset_group_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified asset_group_asset string.""" - return "customers/{customer_id}/assetGroupAssets/{asset_group_id}~{asset_id}~{field_type}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_asset_group_asset_path(path: str) -> Dict[str, str]: - """Parses a asset_group_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AssetGroupAssetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AssetGroupAssetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AssetGroupAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AssetGroupAssetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetGroupAssetServiceTransport, - Callable[..., AssetGroupAssetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset group asset service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetGroupAssetServiceTransport,Callable[..., AssetGroupAssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetGroupAssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AssetGroupAssetServiceClient._read_environment_variables() - self._client_cert_source = ( - AssetGroupAssetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AssetGroupAssetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AssetGroupAssetServiceTransport - ) - if transport_provided: - # transport is a AssetGroupAssetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AssetGroupAssetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AssetGroupAssetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AssetGroupAssetServiceTransport], - Callable[..., AssetGroupAssetServiceTransport], - ] = ( - AssetGroupAssetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AssetGroupAssetServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AssetGroupAssetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetGroupAssetService", - "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.ads.googleads.v19.services.AssetGroupAssetService", - "credentialsType": None, - } - ), - ) - - def mutate_asset_group_assets( - self, - request: Optional[ - Union[asset_group_asset_service.MutateAssetGroupAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[asset_group_asset_service.AssetGroupAssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_group_asset_service.MutateAssetGroupAssetsResponse: - r"""Creates, updates or removes asset group assets. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAssetGroupAssetsRequest, dict]): - The request object. Request message for - [AssetGroupAssetService.MutateAssetGroupAssets][google.ads.googleads.v19.services.AssetGroupAssetService.MutateAssetGroupAssets]. - customer_id (str): - Required. The ID of the customer - whose asset group assets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetGroupAssetOperation]): - Required. The list of operations to - perform on individual asset group - assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetGroupAssetsResponse: - Response message for an asset group - asset mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, asset_group_asset_service.MutateAssetGroupAssetsRequest - ): - request = asset_group_asset_service.MutateAssetGroupAssetsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_asset_group_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AssetGroupAssetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AssetGroupAssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_asset_service/transports/base.py b/google/ads/googleads/v19/services/services/asset_group_asset_service/transports/base.py deleted file mode 100644 index dd2050c1a..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_asset_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import asset_group_asset_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AssetGroupAssetServiceTransport(abc.ABC): - """Abstract transport class for AssetGroupAssetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_asset_group_assets: gapic_v1.method.wrap_method( - self.mutate_asset_group_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_asset_group_assets( - self, - ) -> Callable[ - [asset_group_asset_service.MutateAssetGroupAssetsRequest], - Union[ - asset_group_asset_service.MutateAssetGroupAssetsResponse, - Awaitable[asset_group_asset_service.MutateAssetGroupAssetsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AssetGroupAssetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_asset_service/transports/grpc.py b/google/ads/googleads/v19/services/services/asset_group_asset_service/transports/grpc.py deleted file mode 100644 index e42ec03e4..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_asset_service/transports/grpc.py +++ /dev/null @@ -1,382 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import asset_group_asset_service -from .base import AssetGroupAssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AssetGroupAssetService", - "rpcName": str(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.ads.googleads.v19.services.AssetGroupAssetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetGroupAssetServiceGrpcTransport(AssetGroupAssetServiceTransport): - """gRPC backend transport for AssetGroupAssetService. - - Service to manage asset group asset. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_asset_group_assets( - self, - ) -> Callable[ - [asset_group_asset_service.MutateAssetGroupAssetsRequest], - asset_group_asset_service.MutateAssetGroupAssetsResponse, - ]: - r"""Return a callable for the mutate asset group assets method over gRPC. - - Creates, updates or removes asset group assets. - Operation statuses are returned. - - Returns: - Callable[[~.MutateAssetGroupAssetsRequest], - ~.MutateAssetGroupAssetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_group_assets" not in self._stubs: - self._stubs["mutate_asset_group_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetGroupAssetService/MutateAssetGroupAssets", - request_serializer=asset_group_asset_service.MutateAssetGroupAssetsRequest.serialize, - response_deserializer=asset_group_asset_service.MutateAssetGroupAssetsResponse.deserialize, - ) - ) - return self._stubs["mutate_asset_group_assets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AssetGroupAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/asset_group_asset_service/transports/grpc_asyncio.py deleted file mode 100644 index c1ebbe48e..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_asset_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,405 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import asset_group_asset_service -from .base import AssetGroupAssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AssetGroupAssetService", - "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.ads.googleads.v19.services.AssetGroupAssetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetGroupAssetServiceGrpcAsyncIOTransport( - AssetGroupAssetServiceTransport -): - """gRPC AsyncIO backend transport for AssetGroupAssetService. - - Service to manage asset group asset. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_asset_group_assets( - self, - ) -> Callable[ - [asset_group_asset_service.MutateAssetGroupAssetsRequest], - Awaitable[asset_group_asset_service.MutateAssetGroupAssetsResponse], - ]: - r"""Return a callable for the mutate asset group assets method over gRPC. - - Creates, updates or removes asset group assets. - Operation statuses are returned. - - Returns: - Callable[[~.MutateAssetGroupAssetsRequest], - Awaitable[~.MutateAssetGroupAssetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_group_assets" not in self._stubs: - self._stubs["mutate_asset_group_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetGroupAssetService/MutateAssetGroupAssets", - request_serializer=asset_group_asset_service.MutateAssetGroupAssetsRequest.serialize, - response_deserializer=asset_group_asset_service.MutateAssetGroupAssetsResponse.deserialize, - ) - ) - return self._stubs["mutate_asset_group_assets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_asset_group_assets: self._wrap_method( - self.mutate_asset_group_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AssetGroupAssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/async_client.py b/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/async_client.py deleted file mode 100644 index c6419ae0b..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/async_client.py +++ /dev/null @@ -1,452 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - asset_group_listing_group_filter_service, -) -from .transports.base import ( - AssetGroupListingGroupFilterServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import AssetGroupListingGroupFilterServiceClient - -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 AssetGroupListingGroupFilterServiceAsyncClient: - """Service to manage asset group listing group filter.""" - - _client: AssetGroupListingGroupFilterServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ( - AssetGroupListingGroupFilterServiceClient.DEFAULT_ENDPOINT - ) - DEFAULT_MTLS_ENDPOINT = ( - AssetGroupListingGroupFilterServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - AssetGroupListingGroupFilterServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ( - AssetGroupListingGroupFilterServiceClient._DEFAULT_UNIVERSE - ) - - asset_group_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.asset_group_path - ) - parse_asset_group_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.parse_asset_group_path - ) - asset_group_listing_group_filter_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.asset_group_listing_group_filter_path - ) - parse_asset_group_listing_group_filter_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.parse_asset_group_listing_group_filter_path - ) - common_billing_account_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AssetGroupListingGroupFilterServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupListingGroupFilterServiceAsyncClient: The constructed client. - """ - return AssetGroupListingGroupFilterServiceClient.from_service_account_info.__func__(AssetGroupListingGroupFilterServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupListingGroupFilterServiceAsyncClient: The constructed client. - """ - return AssetGroupListingGroupFilterServiceClient.from_service_account_file.__func__(AssetGroupListingGroupFilterServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AssetGroupListingGroupFilterServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AssetGroupListingGroupFilterServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetGroupListingGroupFilterServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - AssetGroupListingGroupFilterServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetGroupListingGroupFilterServiceTransport, - Callable[..., AssetGroupListingGroupFilterServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset group listing group filter service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetGroupListingGroupFilterServiceTransport,Callable[..., AssetGroupListingGroupFilterServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetGroupListingGroupFilterServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AssetGroupListingGroupFilterServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AssetGroupListingGroupFilterServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetGroupListingGroupFilterService", - "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.ads.googleads.v19.services.AssetGroupListingGroupFilterService", - "credentialsType": None, - } - ), - ) - - async def mutate_asset_group_listing_group_filters( - self, - request: Optional[ - Union[ - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - asset_group_listing_group_filter_service.AssetGroupListingGroupFilterOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse - ): - r"""Creates, updates or removes asset group listing group - filters. Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAssetGroupListingGroupFiltersRequest, dict]]): - The request object. Request message for - [AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters][google.ads.googleads.v19.services.AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters]. - partial_failure is not supported because the tree needs - to be validated together. - customer_id (:class:`str`): - Required. The ID of the customer - whose asset group listing group filters - are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AssetGroupListingGroupFilterOperation]`): - Required. The list of operations to - perform on individual asset group - listing group filters. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetGroupListingGroupFiltersResponse: - Response message for an asset group - listing group filter mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest, - ): - request = asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_asset_group_listing_group_filters - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__( - self, - ) -> "AssetGroupListingGroupFilterServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AssetGroupListingGroupFilterServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/client.py b/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/client.py deleted file mode 100644 index 5d97e852a..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/client.py +++ /dev/null @@ -1,933 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - asset_group_listing_group_filter_service, -) -from .transports.base import ( - AssetGroupListingGroupFilterServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import AssetGroupListingGroupFilterServiceGrpcTransport -from .transports.grpc_asyncio import ( - AssetGroupListingGroupFilterServiceGrpcAsyncIOTransport, -) - - -class AssetGroupListingGroupFilterServiceClientMeta(type): - """Metaclass for the AssetGroupListingGroupFilterService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AssetGroupListingGroupFilterServiceTransport]] - _transport_registry["grpc"] = ( - AssetGroupListingGroupFilterServiceGrpcTransport - ) - _transport_registry["grpc_asyncio"] = ( - AssetGroupListingGroupFilterServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AssetGroupListingGroupFilterServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AssetGroupListingGroupFilterServiceClient( - metaclass=AssetGroupListingGroupFilterServiceClientMeta -): - """Service to manage asset group listing group filter.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupListingGroupFilterServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupListingGroupFilterServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AssetGroupListingGroupFilterServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetGroupListingGroupFilterServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_group_path( - customer_id: str, - asset_group_id: str, - ) -> str: - """Returns a fully-qualified asset_group string.""" - return "customers/{customer_id}/assetGroups/{asset_group_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - ) - - @staticmethod - def parse_asset_group_path(path: str) -> Dict[str, str]: - """Parses a asset_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_listing_group_filter_path( - customer_id: str, - asset_group_id: str, - listing_group_filter_id: str, - ) -> str: - """Returns a fully-qualified asset_group_listing_group_filter string.""" - return "customers/{customer_id}/assetGroupListingGroupFilters/{asset_group_id}~{listing_group_filter_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - listing_group_filter_id=listing_group_filter_id, - ) - - @staticmethod - def parse_asset_group_listing_group_filter_path( - path: str, - ) -> Dict[str, str]: - """Parses a asset_group_listing_group_filter path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroupListingGroupFilters/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - AssetGroupListingGroupFilterServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - AssetGroupListingGroupFilterServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = AssetGroupListingGroupFilterServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - AssetGroupListingGroupFilterServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetGroupListingGroupFilterServiceTransport, - Callable[..., AssetGroupListingGroupFilterServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset group listing group filter service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetGroupListingGroupFilterServiceTransport,Callable[..., AssetGroupListingGroupFilterServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetGroupListingGroupFilterServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ( - AssetGroupListingGroupFilterServiceClient._read_environment_variables() - ) - self._client_cert_source = ( - AssetGroupListingGroupFilterServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AssetGroupListingGroupFilterServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AssetGroupListingGroupFilterServiceTransport - ) - if transport_provided: - # transport is a AssetGroupListingGroupFilterServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - AssetGroupListingGroupFilterServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AssetGroupListingGroupFilterServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AssetGroupListingGroupFilterServiceTransport], - Callable[..., AssetGroupListingGroupFilterServiceTransport], - ] = ( - AssetGroupListingGroupFilterServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AssetGroupListingGroupFilterServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AssetGroupListingGroupFilterServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetGroupListingGroupFilterService", - "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.ads.googleads.v19.services.AssetGroupListingGroupFilterService", - "credentialsType": None, - } - ), - ) - - def mutate_asset_group_listing_group_filters( - self, - request: Optional[ - Union[ - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - asset_group_listing_group_filter_service.AssetGroupListingGroupFilterOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse - ): - r"""Creates, updates or removes asset group listing group - filters. Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAssetGroupListingGroupFiltersRequest, dict]): - The request object. Request message for - [AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters][google.ads.googleads.v19.services.AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters]. - partial_failure is not supported because the tree needs - to be validated together. - customer_id (str): - Required. The ID of the customer - whose asset group listing group filters - are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetGroupListingGroupFilterOperation]): - Required. The list of operations to - perform on individual asset group - listing group filters. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetGroupListingGroupFiltersResponse: - Response message for an asset group - listing group filter mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest, - ): - request = asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_asset_group_listing_group_filters - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AssetGroupListingGroupFilterServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AssetGroupListingGroupFilterServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/base.py b/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/base.py deleted file mode 100644 index f2d49e956..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - asset_group_listing_group_filter_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AssetGroupListingGroupFilterServiceTransport(abc.ABC): - """Abstract transport class for AssetGroupListingGroupFilterService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_asset_group_listing_group_filters: gapic_v1.method.wrap_method( - self.mutate_asset_group_listing_group_filters, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_asset_group_listing_group_filters( - self, - ) -> Callable[ - [ - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest - ], - Union[ - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse, - Awaitable[ - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AssetGroupListingGroupFilterServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/grpc.py b/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/grpc.py deleted file mode 100644 index d772f33da..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/grpc.py +++ /dev/null @@ -1,392 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - asset_group_listing_group_filter_service, -) -from .base import ( - AssetGroupListingGroupFilterServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AssetGroupListingGroupFilterService", - "rpcName": str(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.ads.googleads.v19.services.AssetGroupListingGroupFilterService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetGroupListingGroupFilterServiceGrpcTransport( - AssetGroupListingGroupFilterServiceTransport -): - """gRPC backend transport for AssetGroupListingGroupFilterService. - - Service to manage asset group listing group filter. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_asset_group_listing_group_filters( - self, - ) -> Callable[ - [ - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest - ], - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse, - ]: - r"""Return a callable for the mutate asset group listing - group filters method over gRPC. - - Creates, updates or removes asset group listing group - filters. Operation statuses are returned. - - Returns: - Callable[[~.MutateAssetGroupListingGroupFiltersRequest], - ~.MutateAssetGroupListingGroupFiltersResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_group_listing_group_filters" not in self._stubs: - self._stubs["mutate_asset_group_listing_group_filters"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetGroupListingGroupFilterService/MutateAssetGroupListingGroupFilters", - request_serializer=asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest.serialize, - response_deserializer=asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse.deserialize, - ) - ) - return self._stubs["mutate_asset_group_listing_group_filters"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AssetGroupListingGroupFilterServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/grpc_asyncio.py deleted file mode 100644 index f33e67c00..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,415 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - asset_group_listing_group_filter_service, -) -from .base import ( - AssetGroupListingGroupFilterServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AssetGroupListingGroupFilterService", - "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.ads.googleads.v19.services.AssetGroupListingGroupFilterService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetGroupListingGroupFilterServiceGrpcAsyncIOTransport( - AssetGroupListingGroupFilterServiceTransport -): - """gRPC AsyncIO backend transport for AssetGroupListingGroupFilterService. - - Service to manage asset group listing group filter. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_asset_group_listing_group_filters( - self, - ) -> Callable[ - [ - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest - ], - Awaitable[ - asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse - ], - ]: - r"""Return a callable for the mutate asset group listing - group filters method over gRPC. - - Creates, updates or removes asset group listing group - filters. Operation statuses are returned. - - Returns: - Callable[[~.MutateAssetGroupListingGroupFiltersRequest], - Awaitable[~.MutateAssetGroupListingGroupFiltersResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_group_listing_group_filters" not in self._stubs: - self._stubs["mutate_asset_group_listing_group_filters"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetGroupListingGroupFilterService/MutateAssetGroupListingGroupFilters", - request_serializer=asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest.serialize, - response_deserializer=asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse.deserialize, - ) - ) - return self._stubs["mutate_asset_group_listing_group_filters"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_asset_group_listing_group_filters: self._wrap_method( - self.mutate_asset_group_listing_group_filters, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AssetGroupListingGroupFilterServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_service/async_client.py b/google/ads/googleads/v19/services/services/asset_group_service/async_client.py deleted file mode 100644 index 42dfa252b..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_service/async_client.py +++ /dev/null @@ -1,420 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import asset_group_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AssetGroupServiceTransport, DEFAULT_CLIENT_INFO -from .client import AssetGroupServiceClient - -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 AssetGroupServiceAsyncClient: - """Service to manage asset group""" - - _client: AssetGroupServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AssetGroupServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AssetGroupServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AssetGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AssetGroupServiceClient._DEFAULT_UNIVERSE - - asset_group_path = staticmethod(AssetGroupServiceClient.asset_group_path) - parse_asset_group_path = staticmethod( - AssetGroupServiceClient.parse_asset_group_path - ) - campaign_path = staticmethod(AssetGroupServiceClient.campaign_path) - parse_campaign_path = staticmethod( - AssetGroupServiceClient.parse_campaign_path - ) - common_billing_account_path = staticmethod( - AssetGroupServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AssetGroupServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AssetGroupServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AssetGroupServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AssetGroupServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AssetGroupServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AssetGroupServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AssetGroupServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AssetGroupServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AssetGroupServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupServiceAsyncClient: The constructed client. - """ - return AssetGroupServiceClient.from_service_account_info.__func__(AssetGroupServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupServiceAsyncClient: The constructed client. - """ - return AssetGroupServiceClient.from_service_account_file.__func__(AssetGroupServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AssetGroupServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AssetGroupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetGroupServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AssetGroupServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetGroupServiceTransport, - Callable[..., AssetGroupServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset group service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetGroupServiceTransport,Callable[..., AssetGroupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetGroupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AssetGroupServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AssetGroupServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetGroupService", - "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.ads.googleads.v19.services.AssetGroupService", - "credentialsType": None, - } - ), - ) - - async def mutate_asset_groups( - self, - request: Optional[ - Union[asset_group_service.MutateAssetGroupsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[asset_group_service.AssetGroupOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_group_service.MutateAssetGroupsResponse: - r"""Creates, updates or removes asset groups. Operation - statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAssetGroupsRequest, dict]]): - The request object. Request message for - [AssetGroupService.MutateAssetGroups][google.ads.googleads.v19.services.AssetGroupService.MutateAssetGroups]. - customer_id (:class:`str`): - Required. The ID of the customer - whose asset groups are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AssetGroupOperation]`): - Required. The list of operations to - perform on individual asset groups. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetGroupsResponse: - Response message for an asset group - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, asset_group_service.MutateAssetGroupsRequest - ): - request = asset_group_service.MutateAssetGroupsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_asset_groups - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AssetGroupServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AssetGroupServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_service/client.py b/google/ads/googleads/v19/services/services/asset_group_service/client.py deleted file mode 100644 index d612aac36..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_service/client.py +++ /dev/null @@ -1,886 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import asset_group_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AssetGroupServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AssetGroupServiceGrpcTransport -from .transports.grpc_asyncio import AssetGroupServiceGrpcAsyncIOTransport - - -class AssetGroupServiceClientMeta(type): - """Metaclass for the AssetGroupService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AssetGroupServiceTransport]] - _transport_registry["grpc"] = AssetGroupServiceGrpcTransport - _transport_registry["grpc_asyncio"] = AssetGroupServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AssetGroupServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AssetGroupServiceClient(metaclass=AssetGroupServiceClientMeta): - """Service to manage asset group""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AssetGroupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetGroupServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_group_path( - customer_id: str, - asset_group_id: str, - ) -> str: - """Returns a fully-qualified asset_group string.""" - return "customers/{customer_id}/assetGroups/{asset_group_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - ) - - @staticmethod - def parse_asset_group_path(path: str) -> Dict[str, str]: - """Parses a asset_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AssetGroupServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AssetGroupServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AssetGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AssetGroupServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetGroupServiceTransport, - Callable[..., AssetGroupServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset group service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetGroupServiceTransport,Callable[..., AssetGroupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetGroupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AssetGroupServiceClient._read_environment_variables() - self._client_cert_source = ( - AssetGroupServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = AssetGroupServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, AssetGroupServiceTransport) - if transport_provided: - # transport is a AssetGroupServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AssetGroupServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AssetGroupServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AssetGroupServiceTransport], - Callable[..., AssetGroupServiceTransport], - ] = ( - AssetGroupServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., AssetGroupServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AssetGroupServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetGroupService", - "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.ads.googleads.v19.services.AssetGroupService", - "credentialsType": None, - } - ), - ) - - def mutate_asset_groups( - self, - request: Optional[ - Union[asset_group_service.MutateAssetGroupsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[asset_group_service.AssetGroupOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_group_service.MutateAssetGroupsResponse: - r"""Creates, updates or removes asset groups. Operation - statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAssetGroupsRequest, dict]): - The request object. Request message for - [AssetGroupService.MutateAssetGroups][google.ads.googleads.v19.services.AssetGroupService.MutateAssetGroups]. - customer_id (str): - Required. The ID of the customer - whose asset groups are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetGroupOperation]): - Required. The list of operations to - perform on individual asset groups. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetGroupsResponse: - Response message for an asset group - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, asset_group_service.MutateAssetGroupsRequest - ): - request = asset_group_service.MutateAssetGroupsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_asset_groups - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AssetGroupServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AssetGroupServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_service/transports/base.py b/google/ads/googleads/v19/services/services/asset_group_service/transports/base.py deleted file mode 100644 index 4561f26d1..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import asset_group_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AssetGroupServiceTransport(abc.ABC): - """Abstract transport class for AssetGroupService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_asset_groups: gapic_v1.method.wrap_method( - self.mutate_asset_groups, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_asset_groups( - self, - ) -> Callable[ - [asset_group_service.MutateAssetGroupsRequest], - Union[ - asset_group_service.MutateAssetGroupsResponse, - Awaitable[asset_group_service.MutateAssetGroupsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AssetGroupServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_service/transports/grpc.py b/google/ads/googleads/v19/services/services/asset_group_service/transports/grpc.py deleted file mode 100644 index a2eac6c39..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_service/transports/grpc.py +++ /dev/null @@ -1,382 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import asset_group_service -from .base import AssetGroupServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AssetGroupService", - "rpcName": str(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.ads.googleads.v19.services.AssetGroupService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetGroupServiceGrpcTransport(AssetGroupServiceTransport): - """gRPC backend transport for AssetGroupService. - - Service to manage asset group - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_asset_groups( - self, - ) -> Callable[ - [asset_group_service.MutateAssetGroupsRequest], - asset_group_service.MutateAssetGroupsResponse, - ]: - r"""Return a callable for the mutate asset groups method over gRPC. - - Creates, updates or removes asset groups. Operation - statuses are returned. - - Returns: - Callable[[~.MutateAssetGroupsRequest], - ~.MutateAssetGroupsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_groups" not in self._stubs: - self._stubs["mutate_asset_groups"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetGroupService/MutateAssetGroups", - request_serializer=asset_group_service.MutateAssetGroupsRequest.serialize, - response_deserializer=asset_group_service.MutateAssetGroupsResponse.deserialize, - ) - ) - return self._stubs["mutate_asset_groups"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AssetGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/asset_group_service/transports/grpc_asyncio.py deleted file mode 100644 index 920664c2c..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,403 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import asset_group_service -from .base import AssetGroupServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AssetGroupService", - "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.ads.googleads.v19.services.AssetGroupService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetGroupServiceGrpcAsyncIOTransport(AssetGroupServiceTransport): - """gRPC AsyncIO backend transport for AssetGroupService. - - Service to manage asset group - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_asset_groups( - self, - ) -> Callable[ - [asset_group_service.MutateAssetGroupsRequest], - Awaitable[asset_group_service.MutateAssetGroupsResponse], - ]: - r"""Return a callable for the mutate asset groups method over gRPC. - - Creates, updates or removes asset groups. Operation - statuses are returned. - - Returns: - Callable[[~.MutateAssetGroupsRequest], - Awaitable[~.MutateAssetGroupsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_groups" not in self._stubs: - self._stubs["mutate_asset_groups"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetGroupService/MutateAssetGroups", - request_serializer=asset_group_service.MutateAssetGroupsRequest.serialize, - response_deserializer=asset_group_service.MutateAssetGroupsResponse.deserialize, - ) - ) - return self._stubs["mutate_asset_groups"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_asset_groups: self._wrap_method( - self.mutate_asset_groups, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AssetGroupServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_signal_service/async_client.py b/google/ads/googleads/v19/services/services/asset_group_signal_service/async_client.py deleted file mode 100644 index 9caaa27dd..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_signal_service/async_client.py +++ /dev/null @@ -1,435 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import asset_group_signal_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AssetGroupSignalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import AssetGroupSignalServiceClient - -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 AssetGroupSignalServiceAsyncClient: - """Service to manage asset group signal.""" - - _client: AssetGroupSignalServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AssetGroupSignalServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AssetGroupSignalServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AssetGroupSignalServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AssetGroupSignalServiceClient._DEFAULT_UNIVERSE - - asset_group_path = staticmethod( - AssetGroupSignalServiceClient.asset_group_path - ) - parse_asset_group_path = staticmethod( - AssetGroupSignalServiceClient.parse_asset_group_path - ) - asset_group_signal_path = staticmethod( - AssetGroupSignalServiceClient.asset_group_signal_path - ) - parse_asset_group_signal_path = staticmethod( - AssetGroupSignalServiceClient.parse_asset_group_signal_path - ) - common_billing_account_path = staticmethod( - AssetGroupSignalServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AssetGroupSignalServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AssetGroupSignalServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AssetGroupSignalServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AssetGroupSignalServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AssetGroupSignalServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AssetGroupSignalServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AssetGroupSignalServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AssetGroupSignalServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AssetGroupSignalServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupSignalServiceAsyncClient: The constructed client. - """ - return AssetGroupSignalServiceClient.from_service_account_info.__func__(AssetGroupSignalServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupSignalServiceAsyncClient: The constructed client. - """ - return AssetGroupSignalServiceClient.from_service_account_file.__func__(AssetGroupSignalServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AssetGroupSignalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AssetGroupSignalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetGroupSignalServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AssetGroupSignalServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetGroupSignalServiceTransport, - Callable[..., AssetGroupSignalServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset group signal service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetGroupSignalServiceTransport,Callable[..., AssetGroupSignalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetGroupSignalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AssetGroupSignalServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AssetGroupSignalServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetGroupSignalService", - "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.ads.googleads.v19.services.AssetGroupSignalService", - "credentialsType": None, - } - ), - ) - - async def mutate_asset_group_signals( - self, - request: Optional[ - Union[ - asset_group_signal_service.MutateAssetGroupSignalsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - asset_group_signal_service.AssetGroupSignalOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_group_signal_service.MutateAssetGroupSignalsResponse: - r"""Creates or removes asset group signals. Operation - statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAssetGroupSignalsRequest, dict]]): - The request object. Request message for - [AssetGroupSignalService.MutateAssetGroupSignals][google.ads.googleads.v19.services.AssetGroupSignalService.MutateAssetGroupSignals]. - customer_id (:class:`str`): - Required. The ID of the customer - whose asset group signals are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AssetGroupSignalOperation]`): - Required. The list of operations to - perform on individual asset group - signals. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetGroupSignalsResponse: - Response message for an asset group - signal mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, asset_group_signal_service.MutateAssetGroupSignalsRequest - ): - request = asset_group_signal_service.MutateAssetGroupSignalsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_asset_group_signals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AssetGroupSignalServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AssetGroupSignalServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_signal_service/client.py b/google/ads/googleads/v19/services/services/asset_group_signal_service/client.py deleted file mode 100644 index 561ccddfe..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_signal_service/client.py +++ /dev/null @@ -1,909 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import asset_group_signal_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - AssetGroupSignalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import AssetGroupSignalServiceGrpcTransport -from .transports.grpc_asyncio import AssetGroupSignalServiceGrpcAsyncIOTransport - - -class AssetGroupSignalServiceClientMeta(type): - """Metaclass for the AssetGroupSignalService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AssetGroupSignalServiceTransport]] - _transport_registry["grpc"] = AssetGroupSignalServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AssetGroupSignalServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AssetGroupSignalServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AssetGroupSignalServiceClient( - metaclass=AssetGroupSignalServiceClientMeta -): - """Service to manage asset group signal.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupSignalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetGroupSignalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AssetGroupSignalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetGroupSignalServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_group_path( - customer_id: str, - asset_group_id: str, - ) -> str: - """Returns a fully-qualified asset_group string.""" - return "customers/{customer_id}/assetGroups/{asset_group_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - ) - - @staticmethod - def parse_asset_group_path(path: str) -> Dict[str, str]: - """Parses a asset_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_signal_path( - customer_id: str, - asset_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified asset_group_signal string.""" - return "customers/{customer_id}/assetGroupSignals/{asset_group_id}~{criterion_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_asset_group_signal_path(path: str) -> Dict[str, str]: - """Parses a asset_group_signal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroupSignals/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AssetGroupSignalServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AssetGroupSignalServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AssetGroupSignalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AssetGroupSignalServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetGroupSignalServiceTransport, - Callable[..., AssetGroupSignalServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset group signal service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetGroupSignalServiceTransport,Callable[..., AssetGroupSignalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetGroupSignalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AssetGroupSignalServiceClient._read_environment_variables() - self._client_cert_source = ( - AssetGroupSignalServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AssetGroupSignalServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AssetGroupSignalServiceTransport - ) - if transport_provided: - # transport is a AssetGroupSignalServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AssetGroupSignalServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AssetGroupSignalServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AssetGroupSignalServiceTransport], - Callable[..., AssetGroupSignalServiceTransport], - ] = ( - AssetGroupSignalServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AssetGroupSignalServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AssetGroupSignalServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetGroupSignalService", - "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.ads.googleads.v19.services.AssetGroupSignalService", - "credentialsType": None, - } - ), - ) - - def mutate_asset_group_signals( - self, - request: Optional[ - Union[ - asset_group_signal_service.MutateAssetGroupSignalsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - asset_group_signal_service.AssetGroupSignalOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_group_signal_service.MutateAssetGroupSignalsResponse: - r"""Creates or removes asset group signals. Operation - statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAssetGroupSignalsRequest, dict]): - The request object. Request message for - [AssetGroupSignalService.MutateAssetGroupSignals][google.ads.googleads.v19.services.AssetGroupSignalService.MutateAssetGroupSignals]. - customer_id (str): - Required. The ID of the customer - whose asset group signals are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetGroupSignalOperation]): - Required. The list of operations to - perform on individual asset group - signals. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetGroupSignalsResponse: - Response message for an asset group - signal mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, asset_group_signal_service.MutateAssetGroupSignalsRequest - ): - request = asset_group_signal_service.MutateAssetGroupSignalsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_asset_group_signals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AssetGroupSignalServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AssetGroupSignalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_signal_service/transports/base.py b/google/ads/googleads/v19/services/services/asset_group_signal_service/transports/base.py deleted file mode 100644 index 433f32885..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_signal_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import asset_group_signal_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AssetGroupSignalServiceTransport(abc.ABC): - """Abstract transport class for AssetGroupSignalService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_asset_group_signals: gapic_v1.method.wrap_method( - self.mutate_asset_group_signals, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_asset_group_signals( - self, - ) -> Callable[ - [asset_group_signal_service.MutateAssetGroupSignalsRequest], - Union[ - asset_group_signal_service.MutateAssetGroupSignalsResponse, - Awaitable[ - asset_group_signal_service.MutateAssetGroupSignalsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AssetGroupSignalServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_signal_service/transports/grpc.py b/google/ads/googleads/v19/services/services/asset_group_signal_service/transports/grpc.py deleted file mode 100644 index f05fea2c8..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_signal_service/transports/grpc.py +++ /dev/null @@ -1,382 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import asset_group_signal_service -from .base import AssetGroupSignalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AssetGroupSignalService", - "rpcName": str(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.ads.googleads.v19.services.AssetGroupSignalService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetGroupSignalServiceGrpcTransport(AssetGroupSignalServiceTransport): - """gRPC backend transport for AssetGroupSignalService. - - Service to manage asset group signal. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_asset_group_signals( - self, - ) -> Callable[ - [asset_group_signal_service.MutateAssetGroupSignalsRequest], - asset_group_signal_service.MutateAssetGroupSignalsResponse, - ]: - r"""Return a callable for the mutate asset group signals method over gRPC. - - Creates or removes asset group signals. Operation - statuses are returned. - - Returns: - Callable[[~.MutateAssetGroupSignalsRequest], - ~.MutateAssetGroupSignalsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_group_signals" not in self._stubs: - self._stubs["mutate_asset_group_signals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetGroupSignalService/MutateAssetGroupSignals", - request_serializer=asset_group_signal_service.MutateAssetGroupSignalsRequest.serialize, - response_deserializer=asset_group_signal_service.MutateAssetGroupSignalsResponse.deserialize, - ) - ) - return self._stubs["mutate_asset_group_signals"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AssetGroupSignalServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_signal_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/asset_group_signal_service/transports/grpc_asyncio.py deleted file mode 100644 index d776d2af4..000000000 --- a/google/ads/googleads/v19/services/services/asset_group_signal_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,405 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import asset_group_signal_service -from .base import AssetGroupSignalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AssetGroupSignalService", - "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.ads.googleads.v19.services.AssetGroupSignalService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetGroupSignalServiceGrpcAsyncIOTransport( - AssetGroupSignalServiceTransport -): - """gRPC AsyncIO backend transport for AssetGroupSignalService. - - Service to manage asset group signal. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_asset_group_signals( - self, - ) -> Callable[ - [asset_group_signal_service.MutateAssetGroupSignalsRequest], - Awaitable[asset_group_signal_service.MutateAssetGroupSignalsResponse], - ]: - r"""Return a callable for the mutate asset group signals method over gRPC. - - Creates or removes asset group signals. Operation - statuses are returned. - - Returns: - Callable[[~.MutateAssetGroupSignalsRequest], - Awaitable[~.MutateAssetGroupSignalsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_group_signals" not in self._stubs: - self._stubs["mutate_asset_group_signals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetGroupSignalService/MutateAssetGroupSignals", - request_serializer=asset_group_signal_service.MutateAssetGroupSignalsRequest.serialize, - response_deserializer=asset_group_signal_service.MutateAssetGroupSignalsResponse.deserialize, - ) - ) - return self._stubs["mutate_asset_group_signals"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_asset_group_signals: self._wrap_method( - self.mutate_asset_group_signals, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AssetGroupSignalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_service/async_client.py b/google/ads/googleads/v19/services/services/asset_service/async_client.py deleted file mode 100644 index 15a671173..000000000 --- a/google/ads/googleads/v19/services/services/asset_service/async_client.py +++ /dev/null @@ -1,421 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AssetServiceTransport, DEFAULT_CLIENT_INFO -from .client import AssetServiceClient - -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 AssetServiceAsyncClient: - """Service to manage assets. Asset types can be created with - AssetService are YoutubeVideoAsset, MediaBundleAsset and - ImageAsset. TextAsset should be created with Ad inline. - """ - - _client: AssetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AssetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AssetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = AssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = AssetServiceClient._DEFAULT_UNIVERSE - - asset_path = staticmethod(AssetServiceClient.asset_path) - parse_asset_path = staticmethod(AssetServiceClient.parse_asset_path) - conversion_action_path = staticmethod( - AssetServiceClient.conversion_action_path - ) - parse_conversion_action_path = staticmethod( - AssetServiceClient.parse_conversion_action_path - ) - common_billing_account_path = staticmethod( - AssetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AssetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(AssetServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - AssetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AssetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AssetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod(AssetServiceClient.common_project_path) - parse_common_project_path = staticmethod( - AssetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod(AssetServiceClient.common_location_path) - parse_common_location_path = staticmethod( - AssetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetServiceAsyncClient: The constructed client. - """ - return AssetServiceClient.from_service_account_info.__func__(AssetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetServiceAsyncClient: The constructed client. - """ - return AssetServiceClient.from_service_account_file.__func__(AssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AssetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, AssetServiceTransport, Callable[..., AssetServiceTransport] - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetServiceTransport,Callable[..., AssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AssetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AssetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetService", - "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.ads.googleads.v19.services.AssetService", - "credentialsType": None, - } - ), - ) - - async def mutate_assets( - self, - request: Optional[ - Union[asset_service.MutateAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[asset_service.AssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_service.MutateAssetsResponse: - r"""Creates assets. Operation statuses are returned. - - List of thrown errors: `AssetError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CollectionSizeError <>`__ `CurrencyCodeError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaUploadError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ `YoutubeVideoRegistrationError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAssetsRequest, dict]]): - The request object. Request message for - [AssetService.MutateAssets][google.ads.googleads.v19.services.AssetService.MutateAssets] - customer_id (:class:`str`): - Required. The ID of the customer - whose assets are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AssetOperation]`): - Required. The list of operations to - perform on individual assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetsResponse: - Response message for an asset mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, asset_service.MutateAssetsRequest): - request = asset_service.MutateAssetsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AssetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AssetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/asset_service/client.py b/google/ads/googleads/v19/services/services/asset_service/client.py deleted file mode 100644 index 0adcddcc1..000000000 --- a/google/ads/googleads/v19/services/services/asset_service/client.py +++ /dev/null @@ -1,888 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AssetServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AssetServiceGrpcTransport -from .transports.grpc_asyncio import AssetServiceGrpcAsyncIOTransport - - -class AssetServiceClientMeta(type): - """Metaclass for the AssetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AssetServiceTransport]] - _transport_registry["grpc"] = AssetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = AssetServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AssetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AssetServiceClient(metaclass=AssetServiceClientMeta): - """Service to manage assets. Asset types can be created with - AssetService are YoutubeVideoAsset, MediaBundleAsset and - ImageAsset. TextAsset should be created with Ad inline. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_path( - customer_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset string.""" - return "customers/{customer_id}/assets/{asset_id}".format( - customer_id=customer_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_path(path: str) -> Dict[str, str]: - """Parses a asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assets/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_action_path( - customer_id: str, - conversion_action_id: str, - ) -> str: - """Returns a fully-qualified conversion_action string.""" - return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( - customer_id=customer_id, - conversion_action_id=conversion_action_id, - ) - - @staticmethod - def parse_conversion_action_path(path: str) -> Dict[str, str]: - """Parses a conversion_action path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionActions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AssetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AssetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = AssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AssetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, AssetServiceTransport, Callable[..., AssetServiceTransport] - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetServiceTransport,Callable[..., AssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AssetServiceClient._read_environment_variables() - self._client_cert_source = AssetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - self._universe_domain = AssetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, AssetServiceTransport) - if transport_provided: - # transport is a AssetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AssetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AssetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AssetServiceTransport], - Callable[..., AssetServiceTransport], - ] = ( - AssetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., AssetServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AssetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetService", - "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.ads.googleads.v19.services.AssetService", - "credentialsType": None, - } - ), - ) - - def mutate_assets( - self, - request: Optional[ - Union[asset_service.MutateAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[asset_service.AssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_service.MutateAssetsResponse: - r"""Creates assets. Operation statuses are returned. - - List of thrown errors: `AssetError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CollectionSizeError <>`__ `CurrencyCodeError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaUploadError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ `YoutubeVideoRegistrationError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAssetsRequest, dict]): - The request object. Request message for - [AssetService.MutateAssets][google.ads.googleads.v19.services.AssetService.MutateAssets] - customer_id (str): - Required. The ID of the customer - whose assets are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetOperation]): - Required. The list of operations to - perform on individual assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetsResponse: - Response message for an asset mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, asset_service.MutateAssetsRequest): - request = asset_service.MutateAssetsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.mutate_assets] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AssetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_service/transports/base.py b/google/ads/googleads/v19/services/services/asset_service/transports/base.py deleted file mode 100644 index 67856f313..000000000 --- a/google/ads/googleads/v19/services/services/asset_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import asset_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AssetServiceTransport(abc.ABC): - """Abstract transport class for AssetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_assets: gapic_v1.method.wrap_method( - self.mutate_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_assets( - self, - ) -> Callable[ - [asset_service.MutateAssetsRequest], - Union[ - asset_service.MutateAssetsResponse, - Awaitable[asset_service.MutateAssetsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AssetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_service/transports/grpc.py b/google/ads/googleads/v19/services/services/asset_service/transports/grpc.py deleted file mode 100644 index 402d16877..000000000 --- a/google/ads/googleads/v19/services/services/asset_service/transports/grpc.py +++ /dev/null @@ -1,393 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import asset_service -from .base import AssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AssetService", - "rpcName": str(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.ads.googleads.v19.services.AssetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetServiceGrpcTransport(AssetServiceTransport): - """gRPC backend transport for AssetService. - - Service to manage assets. Asset types can be created with - AssetService are YoutubeVideoAsset, MediaBundleAsset and - ImageAsset. TextAsset should be created with Ad inline. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_assets( - self, - ) -> Callable[ - [asset_service.MutateAssetsRequest], asset_service.MutateAssetsResponse - ]: - r"""Return a callable for the mutate assets method over gRPC. - - Creates assets. Operation statuses are returned. - - List of thrown errors: `AssetError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CollectionSizeError <>`__ `CurrencyCodeError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaUploadError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ `YoutubeVideoRegistrationError <>`__ - - Returns: - Callable[[~.MutateAssetsRequest], - ~.MutateAssetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_assets" not in self._stubs: - self._stubs["mutate_assets"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetService/MutateAssets", - request_serializer=asset_service.MutateAssetsRequest.serialize, - response_deserializer=asset_service.MutateAssetsResponse.deserialize, - ) - return self._stubs["mutate_assets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/asset_service/transports/grpc_asyncio.py deleted file mode 100644 index 66bd00d4e..000000000 --- a/google/ads/googleads/v19/services/services/asset_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,415 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import asset_service -from .base import AssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AssetService", - "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.ads.googleads.v19.services.AssetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetServiceGrpcAsyncIOTransport(AssetServiceTransport): - """gRPC AsyncIO backend transport for AssetService. - - Service to manage assets. Asset types can be created with - AssetService are YoutubeVideoAsset, MediaBundleAsset and - ImageAsset. TextAsset should be created with Ad inline. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_assets( - self, - ) -> Callable[ - [asset_service.MutateAssetsRequest], - Awaitable[asset_service.MutateAssetsResponse], - ]: - r"""Return a callable for the mutate assets method over gRPC. - - Creates assets. Operation statuses are returned. - - List of thrown errors: `AssetError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CollectionSizeError <>`__ `CurrencyCodeError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ - `MediaUploadError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ `YoutubeVideoRegistrationError <>`__ - - Returns: - Callable[[~.MutateAssetsRequest], - Awaitable[~.MutateAssetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_assets" not in self._stubs: - self._stubs["mutate_assets"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetService/MutateAssets", - request_serializer=asset_service.MutateAssetsRequest.serialize, - response_deserializer=asset_service.MutateAssetsResponse.deserialize, - ) - return self._stubs["mutate_assets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_assets: self._wrap_method( - self.mutate_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_set_asset_service/async_client.py b/google/ads/googleads/v19/services/services/asset_set_asset_service/async_client.py deleted file mode 100644 index 2e06a7f66..000000000 --- a/google/ads/googleads/v19/services/services/asset_set_asset_service/async_client.py +++ /dev/null @@ -1,427 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import asset_set_asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AssetSetAssetServiceTransport, DEFAULT_CLIENT_INFO -from .client import AssetSetAssetServiceClient - -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 AssetSetAssetServiceAsyncClient: - """Service to manage asset set asset.""" - - _client: AssetSetAssetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AssetSetAssetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AssetSetAssetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AssetSetAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AssetSetAssetServiceClient._DEFAULT_UNIVERSE - - asset_path = staticmethod(AssetSetAssetServiceClient.asset_path) - parse_asset_path = staticmethod(AssetSetAssetServiceClient.parse_asset_path) - asset_set_path = staticmethod(AssetSetAssetServiceClient.asset_set_path) - parse_asset_set_path = staticmethod( - AssetSetAssetServiceClient.parse_asset_set_path - ) - asset_set_asset_path = staticmethod( - AssetSetAssetServiceClient.asset_set_asset_path - ) - parse_asset_set_asset_path = staticmethod( - AssetSetAssetServiceClient.parse_asset_set_asset_path - ) - common_billing_account_path = staticmethod( - AssetSetAssetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AssetSetAssetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AssetSetAssetServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AssetSetAssetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AssetSetAssetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AssetSetAssetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AssetSetAssetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AssetSetAssetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AssetSetAssetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AssetSetAssetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetSetAssetServiceAsyncClient: The constructed client. - """ - return AssetSetAssetServiceClient.from_service_account_info.__func__(AssetSetAssetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetSetAssetServiceAsyncClient: The constructed client. - """ - return AssetSetAssetServiceClient.from_service_account_file.__func__(AssetSetAssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AssetSetAssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AssetSetAssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetSetAssetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AssetSetAssetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetSetAssetServiceTransport, - Callable[..., AssetSetAssetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset set asset service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetSetAssetServiceTransport,Callable[..., AssetSetAssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetSetAssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AssetSetAssetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AssetSetAssetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetSetAssetService", - "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.ads.googleads.v19.services.AssetSetAssetService", - "credentialsType": None, - } - ), - ) - - async def mutate_asset_set_assets( - self, - request: Optional[ - Union[asset_set_asset_service.MutateAssetSetAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[asset_set_asset_service.AssetSetAssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_set_asset_service.MutateAssetSetAssetsResponse: - r"""Creates, updates or removes asset set assets. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAssetSetAssetsRequest, dict]]): - The request object. Request message for - [AssetSetAssetService.MutateAssetSetAssets][google.ads.googleads.v19.services.AssetSetAssetService.MutateAssetSetAssets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose asset set assets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AssetSetAssetOperation]`): - Required. The list of operations to - perform on individual asset set assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetSetAssetsResponse: - Response message for an asset set - asset mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, asset_set_asset_service.MutateAssetSetAssetsRequest - ): - request = asset_set_asset_service.MutateAssetSetAssetsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_asset_set_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AssetSetAssetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AssetSetAssetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/asset_set_asset_service/client.py b/google/ads/googleads/v19/services/services/asset_set_asset_service/client.py deleted file mode 100644 index 7cade8fbc..000000000 --- a/google/ads/googleads/v19/services/services/asset_set_asset_service/client.py +++ /dev/null @@ -1,916 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import asset_set_asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AssetSetAssetServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AssetSetAssetServiceGrpcTransport -from .transports.grpc_asyncio import AssetSetAssetServiceGrpcAsyncIOTransport - - -class AssetSetAssetServiceClientMeta(type): - """Metaclass for the AssetSetAssetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AssetSetAssetServiceTransport]] - _transport_registry["grpc"] = AssetSetAssetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AssetSetAssetServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AssetSetAssetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AssetSetAssetServiceClient(metaclass=AssetSetAssetServiceClientMeta): - """Service to manage asset set asset.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetSetAssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetSetAssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AssetSetAssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetSetAssetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_path( - customer_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset string.""" - return "customers/{customer_id}/assets/{asset_id}".format( - customer_id=customer_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_path(path: str) -> Dict[str, str]: - """Parses a asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assets/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_set_path( - customer_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified asset_set string.""" - return "customers/{customer_id}/assetSets/{asset_set_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_asset_set_path(path: str) -> Dict[str, str]: - """Parses a asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_set_asset_path( - customer_id: str, - asset_set_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset_set_asset string.""" - return "customers/{customer_id}/assetSetAssets/{asset_set_id}~{asset_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_set_asset_path(path: str) -> Dict[str, str]: - """Parses a asset_set_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSetAssets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AssetSetAssetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AssetSetAssetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AssetSetAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AssetSetAssetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetSetAssetServiceTransport, - Callable[..., AssetSetAssetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset set asset service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetSetAssetServiceTransport,Callable[..., AssetSetAssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetSetAssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AssetSetAssetServiceClient._read_environment_variables() - self._client_cert_source = ( - AssetSetAssetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = AssetSetAssetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AssetSetAssetServiceTransport - ) - if transport_provided: - # transport is a AssetSetAssetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AssetSetAssetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AssetSetAssetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AssetSetAssetServiceTransport], - Callable[..., AssetSetAssetServiceTransport], - ] = ( - AssetSetAssetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AssetSetAssetServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AssetSetAssetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetSetAssetService", - "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.ads.googleads.v19.services.AssetSetAssetService", - "credentialsType": None, - } - ), - ) - - def mutate_asset_set_assets( - self, - request: Optional[ - Union[asset_set_asset_service.MutateAssetSetAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[asset_set_asset_service.AssetSetAssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_set_asset_service.MutateAssetSetAssetsResponse: - r"""Creates, updates or removes asset set assets. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAssetSetAssetsRequest, dict]): - The request object. Request message for - [AssetSetAssetService.MutateAssetSetAssets][google.ads.googleads.v19.services.AssetSetAssetService.MutateAssetSetAssets]. - customer_id (str): - Required. The ID of the customer - whose asset set assets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetSetAssetOperation]): - Required. The list of operations to - perform on individual asset set assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetSetAssetsResponse: - Response message for an asset set - asset mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, asset_set_asset_service.MutateAssetSetAssetsRequest - ): - request = asset_set_asset_service.MutateAssetSetAssetsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_asset_set_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AssetSetAssetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AssetSetAssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_set_asset_service/transports/base.py b/google/ads/googleads/v19/services/services/asset_set_asset_service/transports/base.py deleted file mode 100644 index e95214c08..000000000 --- a/google/ads/googleads/v19/services/services/asset_set_asset_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import asset_set_asset_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AssetSetAssetServiceTransport(abc.ABC): - """Abstract transport class for AssetSetAssetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_asset_set_assets: gapic_v1.method.wrap_method( - self.mutate_asset_set_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_asset_set_assets( - self, - ) -> Callable[ - [asset_set_asset_service.MutateAssetSetAssetsRequest], - Union[ - asset_set_asset_service.MutateAssetSetAssetsResponse, - Awaitable[asset_set_asset_service.MutateAssetSetAssetsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AssetSetAssetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_set_asset_service/transports/grpc.py b/google/ads/googleads/v19/services/services/asset_set_asset_service/transports/grpc.py deleted file mode 100644 index 4addd333d..000000000 --- a/google/ads/googleads/v19/services/services/asset_set_asset_service/transports/grpc.py +++ /dev/null @@ -1,382 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import asset_set_asset_service -from .base import AssetSetAssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AssetSetAssetService", - "rpcName": str(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.ads.googleads.v19.services.AssetSetAssetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetSetAssetServiceGrpcTransport(AssetSetAssetServiceTransport): - """gRPC backend transport for AssetSetAssetService. - - Service to manage asset set asset. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_asset_set_assets( - self, - ) -> Callable[ - [asset_set_asset_service.MutateAssetSetAssetsRequest], - asset_set_asset_service.MutateAssetSetAssetsResponse, - ]: - r"""Return a callable for the mutate asset set assets method over gRPC. - - Creates, updates or removes asset set assets. - Operation statuses are returned. - - Returns: - Callable[[~.MutateAssetSetAssetsRequest], - ~.MutateAssetSetAssetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_set_assets" not in self._stubs: - self._stubs["mutate_asset_set_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetSetAssetService/MutateAssetSetAssets", - request_serializer=asset_set_asset_service.MutateAssetSetAssetsRequest.serialize, - response_deserializer=asset_set_asset_service.MutateAssetSetAssetsResponse.deserialize, - ) - ) - return self._stubs["mutate_asset_set_assets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AssetSetAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_set_asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/asset_set_asset_service/transports/grpc_asyncio.py deleted file mode 100644 index 928efae6f..000000000 --- a/google/ads/googleads/v19/services/services/asset_set_asset_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,403 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import asset_set_asset_service -from .base import AssetSetAssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AssetSetAssetService", - "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.ads.googleads.v19.services.AssetSetAssetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetSetAssetServiceGrpcAsyncIOTransport(AssetSetAssetServiceTransport): - """gRPC AsyncIO backend transport for AssetSetAssetService. - - Service to manage asset set asset. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_asset_set_assets( - self, - ) -> Callable[ - [asset_set_asset_service.MutateAssetSetAssetsRequest], - Awaitable[asset_set_asset_service.MutateAssetSetAssetsResponse], - ]: - r"""Return a callable for the mutate asset set assets method over gRPC. - - Creates, updates or removes asset set assets. - Operation statuses are returned. - - Returns: - Callable[[~.MutateAssetSetAssetsRequest], - Awaitable[~.MutateAssetSetAssetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_set_assets" not in self._stubs: - self._stubs["mutate_asset_set_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetSetAssetService/MutateAssetSetAssets", - request_serializer=asset_set_asset_service.MutateAssetSetAssetsRequest.serialize, - response_deserializer=asset_set_asset_service.MutateAssetSetAssetsResponse.deserialize, - ) - ) - return self._stubs["mutate_asset_set_assets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_asset_set_assets: self._wrap_method( - self.mutate_asset_set_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AssetSetAssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_set_service/async_client.py b/google/ads/googleads/v19/services/services/asset_set_service/async_client.py deleted file mode 100644 index e5b678d58..000000000 --- a/google/ads/googleads/v19/services/services/asset_set_service/async_client.py +++ /dev/null @@ -1,412 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import asset_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AssetSetServiceTransport, DEFAULT_CLIENT_INFO -from .client import AssetSetServiceClient - -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 AssetSetServiceAsyncClient: - """Service to manage asset set""" - - _client: AssetSetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AssetSetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AssetSetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AssetSetServiceClient._DEFAULT_UNIVERSE - - asset_set_path = staticmethod(AssetSetServiceClient.asset_set_path) - parse_asset_set_path = staticmethod( - AssetSetServiceClient.parse_asset_set_path - ) - common_billing_account_path = staticmethod( - AssetSetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AssetSetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(AssetSetServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - AssetSetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AssetSetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AssetSetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AssetSetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AssetSetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AssetSetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AssetSetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetSetServiceAsyncClient: The constructed client. - """ - return AssetSetServiceClient.from_service_account_info.__func__(AssetSetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetSetServiceAsyncClient: The constructed client. - """ - return AssetSetServiceClient.from_service_account_file.__func__(AssetSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AssetSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AssetSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetSetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AssetSetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetSetServiceTransport, - Callable[..., AssetSetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset set service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetSetServiceTransport,Callable[..., AssetSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AssetSetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AssetSetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetSetService", - "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.ads.googleads.v19.services.AssetSetService", - "credentialsType": None, - } - ), - ) - - async def mutate_asset_sets( - self, - request: Optional[ - Union[asset_set_service.MutateAssetSetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[asset_set_service.AssetSetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_set_service.MutateAssetSetsResponse: - r"""Creates, updates or removes asset sets. Operation - statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAssetSetsRequest, dict]]): - The request object. Request message for - [AssetSetService.MutateAssetSets][google.ads.googleads.v19.services.AssetSetService.MutateAssetSets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose asset sets are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AssetSetOperation]`): - Required. The list of operations to - perform on individual asset sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetSetsResponse: - Response message for an asset set - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, asset_set_service.MutateAssetSetsRequest): - request = asset_set_service.MutateAssetSetsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_asset_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AssetSetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AssetSetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/asset_set_service/client.py b/google/ads/googleads/v19/services/services/asset_set_service/client.py deleted file mode 100644 index afd321c5f..000000000 --- a/google/ads/googleads/v19/services/services/asset_set_service/client.py +++ /dev/null @@ -1,864 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import asset_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AssetSetServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AssetSetServiceGrpcTransport -from .transports.grpc_asyncio import AssetSetServiceGrpcAsyncIOTransport - - -class AssetSetServiceClientMeta(type): - """Metaclass for the AssetSetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AssetSetServiceTransport]] - _transport_registry["grpc"] = AssetSetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = AssetSetServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AssetSetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AssetSetServiceClient(metaclass=AssetSetServiceClientMeta): - """Service to manage asset set""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AssetSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AssetSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AssetSetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_set_path( - customer_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified asset_set string.""" - return "customers/{customer_id}/assetSets/{asset_set_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_asset_set_path(path: str) -> Dict[str, str]: - """Parses a asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AssetSetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AssetSetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AssetSetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AssetSetServiceTransport, - Callable[..., AssetSetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the asset set service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AssetSetServiceTransport,Callable[..., AssetSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AssetSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AssetSetServiceClient._read_environment_variables() - self._client_cert_source = ( - AssetSetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = AssetSetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, AssetSetServiceTransport) - if transport_provided: - # transport is a AssetSetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AssetSetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AssetSetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AssetSetServiceTransport], - Callable[..., AssetSetServiceTransport], - ] = ( - AssetSetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., AssetSetServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AssetSetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AssetSetService", - "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.ads.googleads.v19.services.AssetSetService", - "credentialsType": None, - } - ), - ) - - def mutate_asset_sets( - self, - request: Optional[ - Union[asset_set_service.MutateAssetSetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[asset_set_service.AssetSetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> asset_set_service.MutateAssetSetsResponse: - r"""Creates, updates or removes asset sets. Operation - statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAssetSetsRequest, dict]): - The request object. Request message for - [AssetSetService.MutateAssetSets][google.ads.googleads.v19.services.AssetSetService.MutateAssetSets]. - customer_id (str): - Required. The ID of the customer - whose asset sets are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetSetOperation]): - Required. The list of operations to - perform on individual asset sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAssetSetsResponse: - Response message for an asset set - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, asset_set_service.MutateAssetSetsRequest): - request = asset_set_service.MutateAssetSetsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_asset_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AssetSetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AssetSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_set_service/transports/base.py b/google/ads/googleads/v19/services/services/asset_set_service/transports/base.py deleted file mode 100644 index 0f1164f02..000000000 --- a/google/ads/googleads/v19/services/services/asset_set_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import asset_set_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AssetSetServiceTransport(abc.ABC): - """Abstract transport class for AssetSetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_asset_sets: gapic_v1.method.wrap_method( - self.mutate_asset_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_asset_sets( - self, - ) -> Callable[ - [asset_set_service.MutateAssetSetsRequest], - Union[ - asset_set_service.MutateAssetSetsResponse, - Awaitable[asset_set_service.MutateAssetSetsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AssetSetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_set_service/transports/grpc.py b/google/ads/googleads/v19/services/services/asset_set_service/transports/grpc.py deleted file mode 100644 index 6fe111188..000000000 --- a/google/ads/googleads/v19/services/services/asset_set_service/transports/grpc.py +++ /dev/null @@ -1,380 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import asset_set_service -from .base import AssetSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AssetSetService", - "rpcName": str(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.ads.googleads.v19.services.AssetSetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetSetServiceGrpcTransport(AssetSetServiceTransport): - """gRPC backend transport for AssetSetService. - - Service to manage asset set - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_asset_sets( - self, - ) -> Callable[ - [asset_set_service.MutateAssetSetsRequest], - asset_set_service.MutateAssetSetsResponse, - ]: - r"""Return a callable for the mutate asset sets method over gRPC. - - Creates, updates or removes asset sets. Operation - statuses are returned. - - Returns: - Callable[[~.MutateAssetSetsRequest], - ~.MutateAssetSetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_sets" not in self._stubs: - self._stubs["mutate_asset_sets"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetSetService/MutateAssetSets", - request_serializer=asset_set_service.MutateAssetSetsRequest.serialize, - response_deserializer=asset_set_service.MutateAssetSetsResponse.deserialize, - ) - return self._stubs["mutate_asset_sets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/asset_set_service/transports/grpc_asyncio.py deleted file mode 100644 index b49e0c59a..000000000 --- a/google/ads/googleads/v19/services/services/asset_set_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,401 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import asset_set_service -from .base import AssetSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AssetSetService", - "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.ads.googleads.v19.services.AssetSetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AssetSetServiceGrpcAsyncIOTransport(AssetSetServiceTransport): - """gRPC AsyncIO backend transport for AssetSetService. - - Service to manage asset set - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_asset_sets( - self, - ) -> Callable[ - [asset_set_service.MutateAssetSetsRequest], - Awaitable[asset_set_service.MutateAssetSetsResponse], - ]: - r"""Return a callable for the mutate asset sets method over gRPC. - - Creates, updates or removes asset sets. Operation - statuses are returned. - - Returns: - Callable[[~.MutateAssetSetsRequest], - Awaitable[~.MutateAssetSetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_asset_sets" not in self._stubs: - self._stubs["mutate_asset_sets"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AssetSetService/MutateAssetSets", - request_serializer=asset_set_service.MutateAssetSetsRequest.serialize, - response_deserializer=asset_set_service.MutateAssetSetsResponse.deserialize, - ) - return self._stubs["mutate_asset_sets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_asset_sets: self._wrap_method( - self.mutate_asset_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AssetSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/audience_insights_service/async_client.py b/google/ads/googleads/v19/services/services/audience_insights_service/async_client.py deleted file mode 100644 index c81eaaf58..000000000 --- a/google/ads/googleads/v19/services/services/audience_insights_service/async_client.py +++ /dev/null @@ -1,1127 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.common.types import audience_insights_attribute -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.enums.types import audience_insights_dimension -from google.ads.googleads.v19.services.types import audience_insights_service -from .transports.base import ( - AudienceInsightsServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import AudienceInsightsServiceClient - -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 AudienceInsightsServiceAsyncClient: - """Audience Insights Service helps users find information about - groups of people and how they can be reached with Google Ads. - Accessible to allowlisted customers only. - """ - - _client: AudienceInsightsServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AudienceInsightsServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AudienceInsightsServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AudienceInsightsServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AudienceInsightsServiceClient._DEFAULT_UNIVERSE - - common_billing_account_path = staticmethod( - AudienceInsightsServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AudienceInsightsServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - AudienceInsightsServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - AudienceInsightsServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AudienceInsightsServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AudienceInsightsServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AudienceInsightsServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AudienceInsightsServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AudienceInsightsServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AudienceInsightsServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AudienceInsightsServiceAsyncClient: The constructed client. - """ - return AudienceInsightsServiceClient.from_service_account_info.__func__(AudienceInsightsServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AudienceInsightsServiceAsyncClient: The constructed client. - """ - return AudienceInsightsServiceClient.from_service_account_file.__func__(AudienceInsightsServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AudienceInsightsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AudienceInsightsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AudienceInsightsServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AudienceInsightsServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AudienceInsightsServiceTransport, - Callable[..., AudienceInsightsServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the audience insights service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AudienceInsightsServiceTransport,Callable[..., AudienceInsightsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AudienceInsightsServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AudienceInsightsServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AudienceInsightsServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AudienceInsightsService", - "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.ads.googleads.v19.services.AudienceInsightsService", - "credentialsType": None, - } - ), - ) - - async def generate_insights_finder_report( - self, - request: Optional[ - Union[ - audience_insights_service.GenerateInsightsFinderReportRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - baseline_audience: Optional[ - audience_insights_service.BasicInsightsAudience - ] = None, - specific_audience: Optional[ - audience_insights_service.BasicInsightsAudience - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.GenerateInsightsFinderReportResponse: - r"""Creates a saved report that can be viewed in the Insights Finder - tool. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateInsightsFinderReportRequest, dict]]): - The request object. Request message for - [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v19.services.AudienceInsightsService.GenerateInsightsFinderReport]. - customer_id (:class:`str`): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - baseline_audience (:class:`google.ads.googleads.v19.services.types.BasicInsightsAudience`): - Required. A baseline audience for - this report, typically all people in a - region. - - This corresponds to the ``baseline_audience`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - specific_audience (:class:`google.ads.googleads.v19.services.types.BasicInsightsAudience`): - Required. The specific audience of - interest for this report. The insights - in the report will be based on - attributes more prevalent in this - audience than in the report's baseline - audience. - - This corresponds to the ``specific_audience`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateInsightsFinderReportResponse: - The response message for - [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v19.services.AudienceInsightsService.GenerateInsightsFinderReport], - containing the shareable URL for the report. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, baseline_audience, specific_audience] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.GenerateInsightsFinderReportRequest, - ): - request = ( - audience_insights_service.GenerateInsightsFinderReportRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if baseline_audience is not None: - request.baseline_audience = baseline_audience - if specific_audience is not None: - request.specific_audience = specific_audience - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_insights_finder_report - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_audience_insights_attributes( - self, - request: Optional[ - Union[ - audience_insights_service.ListAudienceInsightsAttributesRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - dimensions: Optional[ - MutableSequence[ - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ] - ] = None, - query_text: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.ListAudienceInsightsAttributesResponse: - r"""Searches for audience attributes that can be used to generate - insights. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ListAudienceInsightsAttributesRequest, dict]]): - The request object. Request message for - [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v19.services.AudienceInsightsService.ListAudienceInsightsAttributes]. - customer_id (:class:`str`): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - dimensions (:class:`MutableSequence[google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]`): - Required. The types of attributes to be returned. - Supported dimensions are CATEGORY, KNOWLEDGE_GRAPH, - GEO_TARGET_COUNTRY, SUB_COUNTRY_LOCATION, - YOUTUBE_DYNAMIC_LINEUP, AFFINITY_USER_INTEREST, - IN_MARKET_USER_INTEREST, PARENTAL_STATUS, INCOME_RANGE, - AGE_RANGE, and GENDER. - - This corresponds to the ``dimensions`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - query_text (:class:`str`): - Required. A free text query. If the requested dimensions - include Attributes CATEGORY or KNOWLEDGE_GRAPH, then the - attributes returned for those dimensions will match or - be related to this string. For other dimensions, this - field is ignored and all available attributes are - returned. - - This corresponds to the ``query_text`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListAudienceInsightsAttributesResponse: - Response message for - [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v19.services.AudienceInsightsService.ListAudienceInsightsAttributes]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, dimensions, query_text] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.ListAudienceInsightsAttributesRequest, - ): - request = ( - audience_insights_service.ListAudienceInsightsAttributesRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if query_text is not None: - request.query_text = query_text - if dimensions: - request.dimensions.extend(dimensions) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_audience_insights_attributes - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_insights_eligible_dates( - self, - request: Optional[ - Union[ - audience_insights_service.ListInsightsEligibleDatesRequest, dict - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.ListInsightsEligibleDatesResponse: - r"""Lists date ranges for which audience insights data can be - requested. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ListInsightsEligibleDatesRequest, dict]]): - The request object. Request message for - [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v19.services.AudienceInsightsService.ListInsightsEligibleDates]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListInsightsEligibleDatesResponse: - Response message for - [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v19.services.AudienceInsightsService.ListInsightsEligibleDates]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, audience_insights_service.ListInsightsEligibleDatesRequest - ): - request = ( - audience_insights_service.ListInsightsEligibleDatesRequest( - request - ) - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_insights_eligible_dates - ] - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def generate_audience_composition_insights( - self, - request: Optional[ - Union[ - audience_insights_service.GenerateAudienceCompositionInsightsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - audience: Optional[audience_insights_service.InsightsAudience] = None, - dimensions: Optional[ - MutableSequence[ - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.GenerateAudienceCompositionInsightsResponse: - r"""Returns a collection of attributes that are represented in an - audience of interest, with metrics that compare each attribute's - share of the audience with its share of a baseline audience. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateAudienceCompositionInsightsRequest, dict]]): - The request object. Request message for - [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. - customer_id (:class:`str`): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - audience (:class:`google.ads.googleads.v19.services.types.InsightsAudience`): - Required. The audience of interest - for which insights are being requested. - - This corresponds to the ``audience`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - dimensions (:class:`MutableSequence[google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]`): - Required. The audience dimensions for which composition - insights should be returned. Supported dimensions are - KNOWLEDGE_GRAPH, GEO_TARGET_COUNTRY, - SUB_COUNTRY_LOCATION, YOUTUBE_CHANNEL, - YOUTUBE_DYNAMIC_LINEUP, AFFINITY_USER_INTEREST, - IN_MARKET_USER_INTEREST, PARENTAL_STATUS, INCOME_RANGE, - AGE_RANGE, and GENDER. - - This corresponds to the ``dimensions`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateAudienceCompositionInsightsResponse: - Response message for - [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, audience, dimensions] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.GenerateAudienceCompositionInsightsRequest, - ): - request = audience_insights_service.GenerateAudienceCompositionInsightsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if audience is not None: - request.audience = audience - if dimensions: - request.dimensions.extend(dimensions) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_audience_composition_insights - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def generate_suggested_targeting_insights( - self, - request: Optional[ - Union[ - audience_insights_service.GenerateSuggestedTargetingInsightsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.GenerateSuggestedTargetingInsightsResponse: - r"""Returns a collection of targeting insights (e.g. targetable - audiences) that are relevant to the requested audience. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateSuggestedTargetingInsightsRequest, dict]]): - The request object. Request message for - [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateSuggestedTargetingInsightsResponse: - Response message for - [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.GenerateSuggestedTargetingInsightsRequest, - ): - request = audience_insights_service.GenerateSuggestedTargetingInsightsRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_suggested_targeting_insights - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def generate_audience_overlap_insights( - self, - request: Optional[ - Union[ - audience_insights_service.GenerateAudienceOverlapInsightsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - country_location: Optional[criteria.LocationInfo] = None, - primary_attribute: Optional[ - audience_insights_attribute.AudienceInsightsAttribute - ] = None, - dimensions: Optional[ - MutableSequence[ - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.GenerateAudienceOverlapInsightsResponse: - r"""Returns a collection of audience attributes along with estimates - of the overlap between their potential YouTube reach and that of - a given input attribute. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateAudienceOverlapInsightsRequest, dict]]): - The request object. Request message for - [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. - customer_id (:class:`str`): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - country_location (:class:`google.ads.googleads.v19.common.types.LocationInfo`): - Required. The country in which to - calculate the sizes and overlaps of - audiences. - - This corresponds to the ``country_location`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - primary_attribute (:class:`google.ads.googleads.v19.common.types.AudienceInsightsAttribute`): - Required. The audience attribute that - should be intersected with all other - eligible audiences. This must be an - Affinity or In-Market UserInterest, an - AgeRange or a Gender. - - This corresponds to the ``primary_attribute`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - dimensions (:class:`MutableSequence[google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]`): - Required. The types of attributes of which to calculate - the overlap with the primary_attribute. The values must - be a subset of AFFINITY_USER_INTEREST, - IN_MARKET_USER_INTEREST, AGE_RANGE and GENDER. - - This corresponds to the ``dimensions`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateAudienceOverlapInsightsResponse: - Response message for - [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [ - customer_id, - country_location, - primary_attribute, - dimensions, - ] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.GenerateAudienceOverlapInsightsRequest, - ): - request = audience_insights_service.GenerateAudienceOverlapInsightsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if country_location is not None: - request.country_location = country_location - if primary_attribute is not None: - request.primary_attribute = primary_attribute - if dimensions: - request.dimensions.extend(dimensions) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_audience_overlap_insights - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def generate_targeting_suggestion_metrics( - self, - request: Optional[ - Union[ - audience_insights_service.GenerateTargetingSuggestionMetricsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - audiences: Optional[ - MutableSequence[audience_insights_service.BasicInsightsAudience] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.GenerateTargetingSuggestionMetricsResponse: - r"""Returns potential reach metrics for targetable audiences. - - This method helps answer questions like "How many Men aged 18+ - interested in Camping can be reached on YouTube?" - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateTargetingSuggestionMetricsRequest, dict]]): - The request object. Request message for - [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v19.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. - customer_id (:class:`str`): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - audiences (:class:`MutableSequence[google.ads.googleads.v19.services.types.BasicInsightsAudience]`): - Required. Audiences to request - metrics for. - - This corresponds to the ``audiences`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateTargetingSuggestionMetricsResponse: - Response message for - [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v19.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, audiences] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.GenerateTargetingSuggestionMetricsRequest, - ): - request = audience_insights_service.GenerateTargetingSuggestionMetricsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if audiences: - request.audiences.extend(audiences) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_targeting_suggestion_metrics - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AudienceInsightsServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AudienceInsightsServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/audience_insights_service/client.py b/google/ads/googleads/v19/services/services/audience_insights_service/client.py deleted file mode 100644 index 4163e0fc2..000000000 --- a/google/ads/googleads/v19/services/services/audience_insights_service/client.py +++ /dev/null @@ -1,1567 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.common.types import audience_insights_attribute -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.enums.types import audience_insights_dimension -from google.ads.googleads.v19.services.types import audience_insights_service -from .transports.base import ( - AudienceInsightsServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import AudienceInsightsServiceGrpcTransport -from .transports.grpc_asyncio import AudienceInsightsServiceGrpcAsyncIOTransport - - -class AudienceInsightsServiceClientMeta(type): - """Metaclass for the AudienceInsightsService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AudienceInsightsServiceTransport]] - _transport_registry["grpc"] = AudienceInsightsServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - AudienceInsightsServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AudienceInsightsServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AudienceInsightsServiceClient( - metaclass=AudienceInsightsServiceClientMeta -): - """Audience Insights Service helps users find information about - groups of people and how they can be reached with Google Ads. - Accessible to allowlisted customers only. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AudienceInsightsServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AudienceInsightsServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AudienceInsightsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AudienceInsightsServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AudienceInsightsServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AudienceInsightsServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AudienceInsightsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AudienceInsightsServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AudienceInsightsServiceTransport, - Callable[..., AudienceInsightsServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the audience insights service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AudienceInsightsServiceTransport,Callable[..., AudienceInsightsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AudienceInsightsServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AudienceInsightsServiceClient._read_environment_variables() - self._client_cert_source = ( - AudienceInsightsServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - AudienceInsightsServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, AudienceInsightsServiceTransport - ) - if transport_provided: - # transport is a AudienceInsightsServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AudienceInsightsServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AudienceInsightsServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AudienceInsightsServiceTransport], - Callable[..., AudienceInsightsServiceTransport], - ] = ( - AudienceInsightsServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., AudienceInsightsServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AudienceInsightsServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AudienceInsightsService", - "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.ads.googleads.v19.services.AudienceInsightsService", - "credentialsType": None, - } - ), - ) - - def generate_insights_finder_report( - self, - request: Optional[ - Union[ - audience_insights_service.GenerateInsightsFinderReportRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - baseline_audience: Optional[ - audience_insights_service.BasicInsightsAudience - ] = None, - specific_audience: Optional[ - audience_insights_service.BasicInsightsAudience - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.GenerateInsightsFinderReportResponse: - r"""Creates a saved report that can be viewed in the Insights Finder - tool. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateInsightsFinderReportRequest, dict]): - The request object. Request message for - [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v19.services.AudienceInsightsService.GenerateInsightsFinderReport]. - customer_id (str): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - baseline_audience (google.ads.googleads.v19.services.types.BasicInsightsAudience): - Required. A baseline audience for - this report, typically all people in a - region. - - This corresponds to the ``baseline_audience`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - specific_audience (google.ads.googleads.v19.services.types.BasicInsightsAudience): - Required. The specific audience of - interest for this report. The insights - in the report will be based on - attributes more prevalent in this - audience than in the report's baseline - audience. - - This corresponds to the ``specific_audience`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateInsightsFinderReportResponse: - The response message for - [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v19.services.AudienceInsightsService.GenerateInsightsFinderReport], - containing the shareable URL for the report. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, baseline_audience, specific_audience] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.GenerateInsightsFinderReportRequest, - ): - request = ( - audience_insights_service.GenerateInsightsFinderReportRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if baseline_audience is not None: - request.baseline_audience = baseline_audience - if specific_audience is not None: - request.specific_audience = specific_audience - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_insights_finder_report - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_audience_insights_attributes( - self, - request: Optional[ - Union[ - audience_insights_service.ListAudienceInsightsAttributesRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - dimensions: Optional[ - MutableSequence[ - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ] - ] = None, - query_text: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.ListAudienceInsightsAttributesResponse: - r"""Searches for audience attributes that can be used to generate - insights. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ListAudienceInsightsAttributesRequest, dict]): - The request object. Request message for - [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v19.services.AudienceInsightsService.ListAudienceInsightsAttributes]. - customer_id (str): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - dimensions (MutableSequence[google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): - Required. The types of attributes to be returned. - Supported dimensions are CATEGORY, KNOWLEDGE_GRAPH, - GEO_TARGET_COUNTRY, SUB_COUNTRY_LOCATION, - YOUTUBE_DYNAMIC_LINEUP, AFFINITY_USER_INTEREST, - IN_MARKET_USER_INTEREST, PARENTAL_STATUS, INCOME_RANGE, - AGE_RANGE, and GENDER. - - This corresponds to the ``dimensions`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - query_text (str): - Required. A free text query. If the requested dimensions - include Attributes CATEGORY or KNOWLEDGE_GRAPH, then the - attributes returned for those dimensions will match or - be related to this string. For other dimensions, this - field is ignored and all available attributes are - returned. - - This corresponds to the ``query_text`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListAudienceInsightsAttributesResponse: - Response message for - [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v19.services.AudienceInsightsService.ListAudienceInsightsAttributes]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, dimensions, query_text] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.ListAudienceInsightsAttributesRequest, - ): - request = ( - audience_insights_service.ListAudienceInsightsAttributesRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if dimensions is not None: - request.dimensions = dimensions - if query_text is not None: - request.query_text = query_text - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.list_audience_insights_attributes - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_insights_eligible_dates( - self, - request: Optional[ - Union[ - audience_insights_service.ListInsightsEligibleDatesRequest, dict - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.ListInsightsEligibleDatesResponse: - r"""Lists date ranges for which audience insights data can be - requested. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ListInsightsEligibleDatesRequest, dict]): - The request object. Request message for - [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v19.services.AudienceInsightsService.ListInsightsEligibleDates]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListInsightsEligibleDatesResponse: - Response message for - [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v19.services.AudienceInsightsService.ListInsightsEligibleDates]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, audience_insights_service.ListInsightsEligibleDatesRequest - ): - request = ( - audience_insights_service.ListInsightsEligibleDatesRequest( - request - ) - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.list_insights_eligible_dates - ] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def generate_audience_composition_insights( - self, - request: Optional[ - Union[ - audience_insights_service.GenerateAudienceCompositionInsightsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - audience: Optional[audience_insights_service.InsightsAudience] = None, - dimensions: Optional[ - MutableSequence[ - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.GenerateAudienceCompositionInsightsResponse: - r"""Returns a collection of attributes that are represented in an - audience of interest, with metrics that compare each attribute's - share of the audience with its share of a baseline audience. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateAudienceCompositionInsightsRequest, dict]): - The request object. Request message for - [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. - customer_id (str): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - audience (google.ads.googleads.v19.services.types.InsightsAudience): - Required. The audience of interest - for which insights are being requested. - - This corresponds to the ``audience`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - dimensions (MutableSequence[google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): - Required. The audience dimensions for which composition - insights should be returned. Supported dimensions are - KNOWLEDGE_GRAPH, GEO_TARGET_COUNTRY, - SUB_COUNTRY_LOCATION, YOUTUBE_CHANNEL, - YOUTUBE_DYNAMIC_LINEUP, AFFINITY_USER_INTEREST, - IN_MARKET_USER_INTEREST, PARENTAL_STATUS, INCOME_RANGE, - AGE_RANGE, and GENDER. - - This corresponds to the ``dimensions`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateAudienceCompositionInsightsResponse: - Response message for - [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, audience, dimensions] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.GenerateAudienceCompositionInsightsRequest, - ): - request = audience_insights_service.GenerateAudienceCompositionInsightsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if audience is not None: - request.audience = audience - if dimensions is not None: - request.dimensions = dimensions - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_audience_composition_insights - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def generate_suggested_targeting_insights( - self, - request: Optional[ - Union[ - audience_insights_service.GenerateSuggestedTargetingInsightsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.GenerateSuggestedTargetingInsightsResponse: - r"""Returns a collection of targeting insights (e.g. targetable - audiences) that are relevant to the requested audience. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateSuggestedTargetingInsightsRequest, dict]): - The request object. Request message for - [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateSuggestedTargetingInsightsResponse: - Response message for - [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.GenerateSuggestedTargetingInsightsRequest, - ): - request = audience_insights_service.GenerateSuggestedTargetingInsightsRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_suggested_targeting_insights - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def generate_audience_overlap_insights( - self, - request: Optional[ - Union[ - audience_insights_service.GenerateAudienceOverlapInsightsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - country_location: Optional[criteria.LocationInfo] = None, - primary_attribute: Optional[ - audience_insights_attribute.AudienceInsightsAttribute - ] = None, - dimensions: Optional[ - MutableSequence[ - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.GenerateAudienceOverlapInsightsResponse: - r"""Returns a collection of audience attributes along with estimates - of the overlap between their potential YouTube reach and that of - a given input attribute. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateAudienceOverlapInsightsRequest, dict]): - The request object. Request message for - [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. - customer_id (str): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - country_location (google.ads.googleads.v19.common.types.LocationInfo): - Required. The country in which to - calculate the sizes and overlaps of - audiences. - - This corresponds to the ``country_location`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - primary_attribute (google.ads.googleads.v19.common.types.AudienceInsightsAttribute): - Required. The audience attribute that - should be intersected with all other - eligible audiences. This must be an - Affinity or In-Market UserInterest, an - AgeRange or a Gender. - - This corresponds to the ``primary_attribute`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - dimensions (MutableSequence[google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): - Required. The types of attributes of which to calculate - the overlap with the primary_attribute. The values must - be a subset of AFFINITY_USER_INTEREST, - IN_MARKET_USER_INTEREST, AGE_RANGE and GENDER. - - This corresponds to the ``dimensions`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateAudienceOverlapInsightsResponse: - Response message for - [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [ - customer_id, - country_location, - primary_attribute, - dimensions, - ] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.GenerateAudienceOverlapInsightsRequest, - ): - request = audience_insights_service.GenerateAudienceOverlapInsightsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if country_location is not None: - request.country_location = country_location - if primary_attribute is not None: - request.primary_attribute = primary_attribute - if dimensions is not None: - request.dimensions = dimensions - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_audience_overlap_insights - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def generate_targeting_suggestion_metrics( - self, - request: Optional[ - Union[ - audience_insights_service.GenerateTargetingSuggestionMetricsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - audiences: Optional[ - MutableSequence[audience_insights_service.BasicInsightsAudience] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_insights_service.GenerateTargetingSuggestionMetricsResponse: - r"""Returns potential reach metrics for targetable audiences. - - This method helps answer questions like "How many Men aged 18+ - interested in Camping can be reached on YouTube?" - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateTargetingSuggestionMetricsRequest, dict]): - The request object. Request message for - [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v19.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. - customer_id (str): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - audiences (MutableSequence[google.ads.googleads.v19.services.types.BasicInsightsAudience]): - Required. Audiences to request - metrics for. - - This corresponds to the ``audiences`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateTargetingSuggestionMetricsResponse: - Response message for - [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v19.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, audiences] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - audience_insights_service.GenerateTargetingSuggestionMetricsRequest, - ): - request = audience_insights_service.GenerateTargetingSuggestionMetricsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if audiences is not None: - request.audiences = audiences - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_targeting_suggestion_metrics - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AudienceInsightsServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AudienceInsightsServiceClient",) diff --git a/google/ads/googleads/v19/services/services/audience_insights_service/transports/base.py b/google/ads/googleads/v19/services/services/audience_insights_service/transports/base.py deleted file mode 100644 index 6ff096c4e..000000000 --- a/google/ads/googleads/v19/services/services/audience_insights_service/transports/base.py +++ /dev/null @@ -1,288 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import audience_insights_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AudienceInsightsServiceTransport(abc.ABC): - """Abstract transport class for AudienceInsightsService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.generate_insights_finder_report: gapic_v1.method.wrap_method( - self.generate_insights_finder_report, - default_timeout=None, - client_info=client_info, - ), - self.list_audience_insights_attributes: gapic_v1.method.wrap_method( - self.list_audience_insights_attributes, - default_timeout=None, - client_info=client_info, - ), - self.list_insights_eligible_dates: gapic_v1.method.wrap_method( - self.list_insights_eligible_dates, - default_timeout=None, - client_info=client_info, - ), - self.generate_audience_composition_insights: gapic_v1.method.wrap_method( - self.generate_audience_composition_insights, - default_timeout=None, - client_info=client_info, - ), - self.generate_suggested_targeting_insights: gapic_v1.method.wrap_method( - self.generate_suggested_targeting_insights, - default_timeout=None, - client_info=client_info, - ), - self.generate_audience_overlap_insights: gapic_v1.method.wrap_method( - self.generate_audience_overlap_insights, - default_timeout=None, - client_info=client_info, - ), - self.generate_targeting_suggestion_metrics: gapic_v1.method.wrap_method( - self.generate_targeting_suggestion_metrics, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def generate_insights_finder_report( - self, - ) -> Callable[ - [audience_insights_service.GenerateInsightsFinderReportRequest], - Union[ - audience_insights_service.GenerateInsightsFinderReportResponse, - Awaitable[ - audience_insights_service.GenerateInsightsFinderReportResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def list_audience_insights_attributes( - self, - ) -> Callable[ - [audience_insights_service.ListAudienceInsightsAttributesRequest], - Union[ - audience_insights_service.ListAudienceInsightsAttributesResponse, - Awaitable[ - audience_insights_service.ListAudienceInsightsAttributesResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def list_insights_eligible_dates( - self, - ) -> Callable[ - [audience_insights_service.ListInsightsEligibleDatesRequest], - Union[ - audience_insights_service.ListInsightsEligibleDatesResponse, - Awaitable[ - audience_insights_service.ListInsightsEligibleDatesResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def generate_audience_composition_insights( - self, - ) -> Callable[ - [audience_insights_service.GenerateAudienceCompositionInsightsRequest], - Union[ - audience_insights_service.GenerateAudienceCompositionInsightsResponse, - Awaitable[ - audience_insights_service.GenerateAudienceCompositionInsightsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def generate_suggested_targeting_insights( - self, - ) -> Callable[ - [audience_insights_service.GenerateSuggestedTargetingInsightsRequest], - Union[ - audience_insights_service.GenerateSuggestedTargetingInsightsResponse, - Awaitable[ - audience_insights_service.GenerateSuggestedTargetingInsightsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def generate_audience_overlap_insights( - self, - ) -> Callable[ - [audience_insights_service.GenerateAudienceOverlapInsightsRequest], - Union[ - audience_insights_service.GenerateAudienceOverlapInsightsResponse, - Awaitable[ - audience_insights_service.GenerateAudienceOverlapInsightsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def generate_targeting_suggestion_metrics( - self, - ) -> Callable[ - [audience_insights_service.GenerateTargetingSuggestionMetricsRequest], - Union[ - audience_insights_service.GenerateTargetingSuggestionMetricsResponse, - Awaitable[ - audience_insights_service.GenerateTargetingSuggestionMetricsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AudienceInsightsServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/audience_insights_service/transports/grpc.py b/google/ads/googleads/v19/services/services/audience_insights_service/transports/grpc.py deleted file mode 100644 index dffb6f2f7..000000000 --- a/google/ads/googleads/v19/services/services/audience_insights_service/transports/grpc.py +++ /dev/null @@ -1,621 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import audience_insights_service -from .base import AudienceInsightsServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AudienceInsightsService", - "rpcName": str(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.ads.googleads.v19.services.AudienceInsightsService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AudienceInsightsServiceGrpcTransport(AudienceInsightsServiceTransport): - """gRPC backend transport for AudienceInsightsService. - - Audience Insights Service helps users find information about - groups of people and how they can be reached with Google Ads. - Accessible to allowlisted customers only. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def generate_insights_finder_report( - self, - ) -> Callable[ - [audience_insights_service.GenerateInsightsFinderReportRequest], - audience_insights_service.GenerateInsightsFinderReportResponse, - ]: - r"""Return a callable for the generate insights finder - report method over gRPC. - - Creates a saved report that can be viewed in the Insights Finder - tool. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateInsightsFinderReportRequest], - ~.GenerateInsightsFinderReportResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_insights_finder_report" not in self._stubs: - self._stubs["generate_insights_finder_report"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/GenerateInsightsFinderReport", - request_serializer=audience_insights_service.GenerateInsightsFinderReportRequest.serialize, - response_deserializer=audience_insights_service.GenerateInsightsFinderReportResponse.deserialize, - ) - ) - return self._stubs["generate_insights_finder_report"] - - @property - def list_audience_insights_attributes( - self, - ) -> Callable[ - [audience_insights_service.ListAudienceInsightsAttributesRequest], - audience_insights_service.ListAudienceInsightsAttributesResponse, - ]: - r"""Return a callable for the list audience insights - attributes method over gRPC. - - Searches for audience attributes that can be used to generate - insights. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.ListAudienceInsightsAttributesRequest], - ~.ListAudienceInsightsAttributesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_audience_insights_attributes" not in self._stubs: - self._stubs["list_audience_insights_attributes"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/ListAudienceInsightsAttributes", - request_serializer=audience_insights_service.ListAudienceInsightsAttributesRequest.serialize, - response_deserializer=audience_insights_service.ListAudienceInsightsAttributesResponse.deserialize, - ) - ) - return self._stubs["list_audience_insights_attributes"] - - @property - def list_insights_eligible_dates( - self, - ) -> Callable[ - [audience_insights_service.ListInsightsEligibleDatesRequest], - audience_insights_service.ListInsightsEligibleDatesResponse, - ]: - r"""Return a callable for the list insights eligible dates method over gRPC. - - Lists date ranges for which audience insights data can be - requested. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.ListInsightsEligibleDatesRequest], - ~.ListInsightsEligibleDatesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_insights_eligible_dates" not in self._stubs: - self._stubs["list_insights_eligible_dates"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/ListInsightsEligibleDates", - request_serializer=audience_insights_service.ListInsightsEligibleDatesRequest.serialize, - response_deserializer=audience_insights_service.ListInsightsEligibleDatesResponse.deserialize, - ) - ) - return self._stubs["list_insights_eligible_dates"] - - @property - def generate_audience_composition_insights( - self, - ) -> Callable[ - [audience_insights_service.GenerateAudienceCompositionInsightsRequest], - audience_insights_service.GenerateAudienceCompositionInsightsResponse, - ]: - r"""Return a callable for the generate audience composition - insights method over gRPC. - - Returns a collection of attributes that are represented in an - audience of interest, with metrics that compare each attribute's - share of the audience with its share of a baseline audience. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateAudienceCompositionInsightsRequest], - ~.GenerateAudienceCompositionInsightsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_audience_composition_insights" not in self._stubs: - self._stubs["generate_audience_composition_insights"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/GenerateAudienceCompositionInsights", - request_serializer=audience_insights_service.GenerateAudienceCompositionInsightsRequest.serialize, - response_deserializer=audience_insights_service.GenerateAudienceCompositionInsightsResponse.deserialize, - ) - ) - return self._stubs["generate_audience_composition_insights"] - - @property - def generate_suggested_targeting_insights( - self, - ) -> Callable[ - [audience_insights_service.GenerateSuggestedTargetingInsightsRequest], - audience_insights_service.GenerateSuggestedTargetingInsightsResponse, - ]: - r"""Return a callable for the generate suggested targeting - insights method over gRPC. - - Returns a collection of targeting insights (e.g. targetable - audiences) that are relevant to the requested audience. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateSuggestedTargetingInsightsRequest], - ~.GenerateSuggestedTargetingInsightsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_suggested_targeting_insights" not in self._stubs: - self._stubs["generate_suggested_targeting_insights"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/GenerateSuggestedTargetingInsights", - request_serializer=audience_insights_service.GenerateSuggestedTargetingInsightsRequest.serialize, - response_deserializer=audience_insights_service.GenerateSuggestedTargetingInsightsResponse.deserialize, - ) - ) - return self._stubs["generate_suggested_targeting_insights"] - - @property - def generate_audience_overlap_insights( - self, - ) -> Callable[ - [audience_insights_service.GenerateAudienceOverlapInsightsRequest], - audience_insights_service.GenerateAudienceOverlapInsightsResponse, - ]: - r"""Return a callable for the generate audience overlap - insights method over gRPC. - - Returns a collection of audience attributes along with estimates - of the overlap between their potential YouTube reach and that of - a given input attribute. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateAudienceOverlapInsightsRequest], - ~.GenerateAudienceOverlapInsightsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_audience_overlap_insights" not in self._stubs: - self._stubs["generate_audience_overlap_insights"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/GenerateAudienceOverlapInsights", - request_serializer=audience_insights_service.GenerateAudienceOverlapInsightsRequest.serialize, - response_deserializer=audience_insights_service.GenerateAudienceOverlapInsightsResponse.deserialize, - ) - ) - return self._stubs["generate_audience_overlap_insights"] - - @property - def generate_targeting_suggestion_metrics( - self, - ) -> Callable[ - [audience_insights_service.GenerateTargetingSuggestionMetricsRequest], - audience_insights_service.GenerateTargetingSuggestionMetricsResponse, - ]: - r"""Return a callable for the generate targeting suggestion - metrics method over gRPC. - - Returns potential reach metrics for targetable audiences. - - This method helps answer questions like "How many Men aged 18+ - interested in Camping can be reached on YouTube?" - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateTargetingSuggestionMetricsRequest], - ~.GenerateTargetingSuggestionMetricsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_targeting_suggestion_metrics" not in self._stubs: - self._stubs["generate_targeting_suggestion_metrics"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/GenerateTargetingSuggestionMetrics", - request_serializer=audience_insights_service.GenerateTargetingSuggestionMetricsRequest.serialize, - response_deserializer=audience_insights_service.GenerateTargetingSuggestionMetricsResponse.deserialize, - ) - ) - return self._stubs["generate_targeting_suggestion_metrics"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AudienceInsightsServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/audience_insights_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/audience_insights_service/transports/grpc_asyncio.py deleted file mode 100644 index 3f25ebc69..000000000 --- a/google/ads/googleads/v19/services/services/audience_insights_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,686 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import audience_insights_service -from .base import AudienceInsightsServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AudienceInsightsService", - "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.ads.googleads.v19.services.AudienceInsightsService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AudienceInsightsServiceGrpcAsyncIOTransport( - AudienceInsightsServiceTransport -): - """gRPC AsyncIO backend transport for AudienceInsightsService. - - Audience Insights Service helps users find information about - groups of people and how they can be reached with Google Ads. - Accessible to allowlisted customers only. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def generate_insights_finder_report( - self, - ) -> Callable[ - [audience_insights_service.GenerateInsightsFinderReportRequest], - Awaitable[ - audience_insights_service.GenerateInsightsFinderReportResponse - ], - ]: - r"""Return a callable for the generate insights finder - report method over gRPC. - - Creates a saved report that can be viewed in the Insights Finder - tool. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateInsightsFinderReportRequest], - Awaitable[~.GenerateInsightsFinderReportResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_insights_finder_report" not in self._stubs: - self._stubs["generate_insights_finder_report"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/GenerateInsightsFinderReport", - request_serializer=audience_insights_service.GenerateInsightsFinderReportRequest.serialize, - response_deserializer=audience_insights_service.GenerateInsightsFinderReportResponse.deserialize, - ) - ) - return self._stubs["generate_insights_finder_report"] - - @property - def list_audience_insights_attributes( - self, - ) -> Callable[ - [audience_insights_service.ListAudienceInsightsAttributesRequest], - Awaitable[ - audience_insights_service.ListAudienceInsightsAttributesResponse - ], - ]: - r"""Return a callable for the list audience insights - attributes method over gRPC. - - Searches for audience attributes that can be used to generate - insights. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.ListAudienceInsightsAttributesRequest], - Awaitable[~.ListAudienceInsightsAttributesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_audience_insights_attributes" not in self._stubs: - self._stubs["list_audience_insights_attributes"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/ListAudienceInsightsAttributes", - request_serializer=audience_insights_service.ListAudienceInsightsAttributesRequest.serialize, - response_deserializer=audience_insights_service.ListAudienceInsightsAttributesResponse.deserialize, - ) - ) - return self._stubs["list_audience_insights_attributes"] - - @property - def list_insights_eligible_dates( - self, - ) -> Callable[ - [audience_insights_service.ListInsightsEligibleDatesRequest], - Awaitable[audience_insights_service.ListInsightsEligibleDatesResponse], - ]: - r"""Return a callable for the list insights eligible dates method over gRPC. - - Lists date ranges for which audience insights data can be - requested. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.ListInsightsEligibleDatesRequest], - Awaitable[~.ListInsightsEligibleDatesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_insights_eligible_dates" not in self._stubs: - self._stubs["list_insights_eligible_dates"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/ListInsightsEligibleDates", - request_serializer=audience_insights_service.ListInsightsEligibleDatesRequest.serialize, - response_deserializer=audience_insights_service.ListInsightsEligibleDatesResponse.deserialize, - ) - ) - return self._stubs["list_insights_eligible_dates"] - - @property - def generate_audience_composition_insights( - self, - ) -> Callable[ - [audience_insights_service.GenerateAudienceCompositionInsightsRequest], - Awaitable[ - audience_insights_service.GenerateAudienceCompositionInsightsResponse - ], - ]: - r"""Return a callable for the generate audience composition - insights method over gRPC. - - Returns a collection of attributes that are represented in an - audience of interest, with metrics that compare each attribute's - share of the audience with its share of a baseline audience. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateAudienceCompositionInsightsRequest], - Awaitable[~.GenerateAudienceCompositionInsightsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_audience_composition_insights" not in self._stubs: - self._stubs["generate_audience_composition_insights"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/GenerateAudienceCompositionInsights", - request_serializer=audience_insights_service.GenerateAudienceCompositionInsightsRequest.serialize, - response_deserializer=audience_insights_service.GenerateAudienceCompositionInsightsResponse.deserialize, - ) - ) - return self._stubs["generate_audience_composition_insights"] - - @property - def generate_suggested_targeting_insights( - self, - ) -> Callable[ - [audience_insights_service.GenerateSuggestedTargetingInsightsRequest], - Awaitable[ - audience_insights_service.GenerateSuggestedTargetingInsightsResponse - ], - ]: - r"""Return a callable for the generate suggested targeting - insights method over gRPC. - - Returns a collection of targeting insights (e.g. targetable - audiences) that are relevant to the requested audience. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateSuggestedTargetingInsightsRequest], - Awaitable[~.GenerateSuggestedTargetingInsightsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_suggested_targeting_insights" not in self._stubs: - self._stubs["generate_suggested_targeting_insights"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/GenerateSuggestedTargetingInsights", - request_serializer=audience_insights_service.GenerateSuggestedTargetingInsightsRequest.serialize, - response_deserializer=audience_insights_service.GenerateSuggestedTargetingInsightsResponse.deserialize, - ) - ) - return self._stubs["generate_suggested_targeting_insights"] - - @property - def generate_audience_overlap_insights( - self, - ) -> Callable[ - [audience_insights_service.GenerateAudienceOverlapInsightsRequest], - Awaitable[ - audience_insights_service.GenerateAudienceOverlapInsightsResponse - ], - ]: - r"""Return a callable for the generate audience overlap - insights method over gRPC. - - Returns a collection of audience attributes along with estimates - of the overlap between their potential YouTube reach and that of - a given input attribute. - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateAudienceOverlapInsightsRequest], - Awaitable[~.GenerateAudienceOverlapInsightsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_audience_overlap_insights" not in self._stubs: - self._stubs["generate_audience_overlap_insights"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/GenerateAudienceOverlapInsights", - request_serializer=audience_insights_service.GenerateAudienceOverlapInsightsRequest.serialize, - response_deserializer=audience_insights_service.GenerateAudienceOverlapInsightsResponse.deserialize, - ) - ) - return self._stubs["generate_audience_overlap_insights"] - - @property - def generate_targeting_suggestion_metrics( - self, - ) -> Callable[ - [audience_insights_service.GenerateTargetingSuggestionMetricsRequest], - Awaitable[ - audience_insights_service.GenerateTargetingSuggestionMetricsResponse - ], - ]: - r"""Return a callable for the generate targeting suggestion - metrics method over gRPC. - - Returns potential reach metrics for targetable audiences. - - This method helps answer questions like "How many Men aged 18+ - interested in Camping can be reached on YouTube?" - - List of thrown errors: `AudienceInsightsError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateTargetingSuggestionMetricsRequest], - Awaitable[~.GenerateTargetingSuggestionMetricsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_targeting_suggestion_metrics" not in self._stubs: - self._stubs["generate_targeting_suggestion_metrics"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceInsightsService/GenerateTargetingSuggestionMetrics", - request_serializer=audience_insights_service.GenerateTargetingSuggestionMetricsRequest.serialize, - response_deserializer=audience_insights_service.GenerateTargetingSuggestionMetricsResponse.deserialize, - ) - ) - return self._stubs["generate_targeting_suggestion_metrics"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.generate_insights_finder_report: self._wrap_method( - self.generate_insights_finder_report, - default_timeout=None, - client_info=client_info, - ), - self.list_audience_insights_attributes: self._wrap_method( - self.list_audience_insights_attributes, - default_timeout=None, - client_info=client_info, - ), - self.list_insights_eligible_dates: self._wrap_method( - self.list_insights_eligible_dates, - default_timeout=None, - client_info=client_info, - ), - self.generate_audience_composition_insights: self._wrap_method( - self.generate_audience_composition_insights, - default_timeout=None, - client_info=client_info, - ), - self.generate_suggested_targeting_insights: self._wrap_method( - self.generate_suggested_targeting_insights, - default_timeout=None, - client_info=client_info, - ), - self.generate_audience_overlap_insights: self._wrap_method( - self.generate_audience_overlap_insights, - default_timeout=None, - client_info=client_info, - ), - self.generate_targeting_suggestion_metrics: self._wrap_method( - self.generate_targeting_suggestion_metrics, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AudienceInsightsServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/audience_service/async_client.py b/google/ads/googleads/v19/services/services/audience_service/async_client.py deleted file mode 100644 index 4d4593f49..000000000 --- a/google/ads/googleads/v19/services/services/audience_service/async_client.py +++ /dev/null @@ -1,427 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import audience_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AudienceServiceTransport, DEFAULT_CLIENT_INFO -from .client import AudienceServiceClient - -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 AudienceServiceAsyncClient: - """Service to manage audiences.""" - - _client: AudienceServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = AudienceServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = AudienceServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - AudienceServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = AudienceServiceClient._DEFAULT_UNIVERSE - - asset_group_path = staticmethod(AudienceServiceClient.asset_group_path) - parse_asset_group_path = staticmethod( - AudienceServiceClient.parse_asset_group_path - ) - audience_path = staticmethod(AudienceServiceClient.audience_path) - parse_audience_path = staticmethod( - AudienceServiceClient.parse_audience_path - ) - detailed_demographic_path = staticmethod( - AudienceServiceClient.detailed_demographic_path - ) - parse_detailed_demographic_path = staticmethod( - AudienceServiceClient.parse_detailed_demographic_path - ) - life_event_path = staticmethod(AudienceServiceClient.life_event_path) - parse_life_event_path = staticmethod( - AudienceServiceClient.parse_life_event_path - ) - common_billing_account_path = staticmethod( - AudienceServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - AudienceServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(AudienceServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - AudienceServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - AudienceServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - AudienceServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - AudienceServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - AudienceServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - AudienceServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - AudienceServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AudienceServiceAsyncClient: The constructed client. - """ - return AudienceServiceClient.from_service_account_info.__func__(AudienceServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AudienceServiceAsyncClient: The constructed client. - """ - return AudienceServiceClient.from_service_account_file.__func__(AudienceServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return AudienceServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> AudienceServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AudienceServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = AudienceServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AudienceServiceTransport, - Callable[..., AudienceServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the audience service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AudienceServiceTransport,Callable[..., AudienceServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AudienceServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = AudienceServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.AudienceServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AudienceService", - "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.ads.googleads.v19.services.AudienceService", - "credentialsType": None, - } - ), - ) - - async def mutate_audiences( - self, - request: Optional[ - Union[audience_service.MutateAudiencesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[audience_service.AudienceOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_service.MutateAudiencesResponse: - r"""Creates audiences. Operation statuses are returned. - - List of thrown errors: `AudienceError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateAudiencesRequest, dict]]): - The request object. Request message for - [AudienceService.MutateAudiences][google.ads.googleads.v19.services.AudienceService.MutateAudiences]. - customer_id (:class:`str`): - Required. The ID of the customer - whose audiences are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.AudienceOperation]`): - Required. The list of operations to - perform on individual audiences. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAudiencesResponse: - Response message for an audience - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, audience_service.MutateAudiencesRequest): - request = audience_service.MutateAudiencesRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_audiences - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "AudienceServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("AudienceServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/audience_service/client.py b/google/ads/googleads/v19/services/services/audience_service/client.py deleted file mode 100644 index 46f15de3f..000000000 --- a/google/ads/googleads/v19/services/services/audience_service/client.py +++ /dev/null @@ -1,923 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import audience_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import AudienceServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import AudienceServiceGrpcTransport -from .transports.grpc_asyncio import AudienceServiceGrpcAsyncIOTransport - - -class AudienceServiceClientMeta(type): - """Metaclass for the AudienceService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[AudienceServiceTransport]] - _transport_registry["grpc"] = AudienceServiceGrpcTransport - _transport_registry["grpc_asyncio"] = AudienceServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[AudienceServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class AudienceServiceClient(metaclass=AudienceServiceClientMeta): - """Service to manage audiences.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AudienceServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - AudienceServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> AudienceServiceTransport: - """Returns the transport used by the client instance. - - Returns: - AudienceServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_group_path( - customer_id: str, - asset_group_id: str, - ) -> str: - """Returns a fully-qualified asset_group string.""" - return "customers/{customer_id}/assetGroups/{asset_group_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - ) - - @staticmethod - def parse_asset_group_path(path: str) -> Dict[str, str]: - """Parses a asset_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def audience_path( - customer_id: str, - audience_id: str, - ) -> str: - """Returns a fully-qualified audience string.""" - return "customers/{customer_id}/audiences/{audience_id}".format( - customer_id=customer_id, - audience_id=audience_id, - ) - - @staticmethod - def parse_audience_path(path: str) -> Dict[str, str]: - """Parses a audience path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/audiences/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def detailed_demographic_path( - customer_id: str, - detailed_demographic_id: str, - ) -> str: - """Returns a fully-qualified detailed_demographic string.""" - return "customers/{customer_id}/detailedDemographics/{detailed_demographic_id}".format( - customer_id=customer_id, - detailed_demographic_id=detailed_demographic_id, - ) - - @staticmethod - def parse_detailed_demographic_path(path: str) -> Dict[str, str]: - """Parses a detailed_demographic path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/detailedDemographics/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def life_event_path( - customer_id: str, - life_event_id: str, - ) -> str: - """Returns a fully-qualified life_event string.""" - return "customers/{customer_id}/lifeEvents/{life_event_id}".format( - customer_id=customer_id, - life_event_id=life_event_id, - ) - - @staticmethod - def parse_life_event_path(path: str) -> Dict[str, str]: - """Parses a life_event path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/lifeEvents/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = AudienceServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = AudienceServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - AudienceServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = AudienceServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - AudienceServiceTransport, - Callable[..., AudienceServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the audience service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,AudienceServiceTransport,Callable[..., AudienceServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the AudienceServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = AudienceServiceClient._read_environment_variables() - self._client_cert_source = ( - AudienceServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = AudienceServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, AudienceServiceTransport) - if transport_provided: - # transport is a AudienceServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(AudienceServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or AudienceServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[AudienceServiceTransport], - Callable[..., AudienceServiceTransport], - ] = ( - AudienceServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., AudienceServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.AudienceServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.AudienceService", - "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.ads.googleads.v19.services.AudienceService", - "credentialsType": None, - } - ), - ) - - def mutate_audiences( - self, - request: Optional[ - Union[audience_service.MutateAudiencesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[audience_service.AudienceOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> audience_service.MutateAudiencesResponse: - r"""Creates audiences. Operation statuses are returned. - - List of thrown errors: `AudienceError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateAudiencesRequest, dict]): - The request object. Request message for - [AudienceService.MutateAudiences][google.ads.googleads.v19.services.AudienceService.MutateAudiences]. - customer_id (str): - Required. The ID of the customer - whose audiences are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.AudienceOperation]): - Required. The list of operations to - perform on individual audiences. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateAudiencesResponse: - Response message for an audience - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, audience_service.MutateAudiencesRequest): - request = audience_service.MutateAudiencesRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.mutate_audiences] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "AudienceServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("AudienceServiceClient",) diff --git a/google/ads/googleads/v19/services/services/audience_service/transports/base.py b/google/ads/googleads/v19/services/services/audience_service/transports/base.py deleted file mode 100644 index f57a14c13..000000000 --- a/google/ads/googleads/v19/services/services/audience_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import audience_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class AudienceServiceTransport(abc.ABC): - """Abstract transport class for AudienceService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_audiences: gapic_v1.method.wrap_method( - self.mutate_audiences, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_audiences( - self, - ) -> Callable[ - [audience_service.MutateAudiencesRequest], - Union[ - audience_service.MutateAudiencesResponse, - Awaitable[audience_service.MutateAudiencesResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("AudienceServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/audience_service/transports/grpc.py b/google/ads/googleads/v19/services/services/audience_service/transports/grpc.py deleted file mode 100644 index ca5b059d1..000000000 --- a/google/ads/googleads/v19/services/services/audience_service/transports/grpc.py +++ /dev/null @@ -1,381 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import audience_service -from .base import AudienceServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.AudienceService", - "rpcName": str(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.ads.googleads.v19.services.AudienceService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AudienceServiceGrpcTransport(AudienceServiceTransport): - """gRPC backend transport for AudienceService. - - Service to manage audiences. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_audiences( - self, - ) -> Callable[ - [audience_service.MutateAudiencesRequest], - audience_service.MutateAudiencesResponse, - ]: - r"""Return a callable for the mutate audiences method over gRPC. - - Creates audiences. Operation statuses are returned. - - List of thrown errors: `AudienceError <>`__ - - Returns: - Callable[[~.MutateAudiencesRequest], - ~.MutateAudiencesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_audiences" not in self._stubs: - self._stubs["mutate_audiences"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceService/MutateAudiences", - request_serializer=audience_service.MutateAudiencesRequest.serialize, - response_deserializer=audience_service.MutateAudiencesResponse.deserialize, - ) - return self._stubs["mutate_audiences"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("AudienceServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/audience_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/audience_service/transports/grpc_asyncio.py deleted file mode 100644 index 5492b53b1..000000000 --- a/google/ads/googleads/v19/services/services/audience_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,402 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import audience_service -from .base import AudienceServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.AudienceService", - "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.ads.googleads.v19.services.AudienceService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class AudienceServiceGrpcAsyncIOTransport(AudienceServiceTransport): - """gRPC AsyncIO backend transport for AudienceService. - - Service to manage audiences. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_audiences( - self, - ) -> Callable[ - [audience_service.MutateAudiencesRequest], - Awaitable[audience_service.MutateAudiencesResponse], - ]: - r"""Return a callable for the mutate audiences method over gRPC. - - Creates audiences. Operation statuses are returned. - - List of thrown errors: `AudienceError <>`__ - - Returns: - Callable[[~.MutateAudiencesRequest], - Awaitable[~.MutateAudiencesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_audiences" not in self._stubs: - self._stubs["mutate_audiences"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.AudienceService/MutateAudiences", - request_serializer=audience_service.MutateAudiencesRequest.serialize, - response_deserializer=audience_service.MutateAudiencesResponse.deserialize, - ) - return self._stubs["mutate_audiences"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_audiences: self._wrap_method( - self.mutate_audiences, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("AudienceServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/batch_job_service/async_client.py b/google/ads/googleads/v19/services/services/batch_job_service/async_client.py deleted file mode 100644 index bdf3bb17a..000000000 --- a/google/ads/googleads/v19/services/services/batch_job_service/async_client.py +++ /dev/null @@ -1,1192 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.resources.types import batch_job -from google.ads.googleads.v19.services.services.batch_job_service import pagers -from google.ads.googleads.v19.services.types import batch_job_service -from google.ads.googleads.v19.services.types import google_ads_service -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from .transports.base import BatchJobServiceTransport, DEFAULT_CLIENT_INFO -from .client import BatchJobServiceClient - -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 BatchJobServiceAsyncClient: - """Service to manage batch jobs.""" - - _client: BatchJobServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = BatchJobServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = BatchJobServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - BatchJobServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = BatchJobServiceClient._DEFAULT_UNIVERSE - - accessible_bidding_strategy_path = staticmethod( - BatchJobServiceClient.accessible_bidding_strategy_path - ) - parse_accessible_bidding_strategy_path = staticmethod( - BatchJobServiceClient.parse_accessible_bidding_strategy_path - ) - ad_path = staticmethod(BatchJobServiceClient.ad_path) - parse_ad_path = staticmethod(BatchJobServiceClient.parse_ad_path) - ad_group_path = staticmethod(BatchJobServiceClient.ad_group_path) - parse_ad_group_path = staticmethod( - BatchJobServiceClient.parse_ad_group_path - ) - ad_group_ad_path = staticmethod(BatchJobServiceClient.ad_group_ad_path) - parse_ad_group_ad_path = staticmethod( - BatchJobServiceClient.parse_ad_group_ad_path - ) - ad_group_ad_label_path = staticmethod( - BatchJobServiceClient.ad_group_ad_label_path - ) - parse_ad_group_ad_label_path = staticmethod( - BatchJobServiceClient.parse_ad_group_ad_label_path - ) - ad_group_asset_path = staticmethod( - BatchJobServiceClient.ad_group_asset_path - ) - parse_ad_group_asset_path = staticmethod( - BatchJobServiceClient.parse_ad_group_asset_path - ) - ad_group_bid_modifier_path = staticmethod( - BatchJobServiceClient.ad_group_bid_modifier_path - ) - parse_ad_group_bid_modifier_path = staticmethod( - BatchJobServiceClient.parse_ad_group_bid_modifier_path - ) - ad_group_criterion_path = staticmethod( - BatchJobServiceClient.ad_group_criterion_path - ) - parse_ad_group_criterion_path = staticmethod( - BatchJobServiceClient.parse_ad_group_criterion_path - ) - ad_group_criterion_customizer_path = staticmethod( - BatchJobServiceClient.ad_group_criterion_customizer_path - ) - parse_ad_group_criterion_customizer_path = staticmethod( - BatchJobServiceClient.parse_ad_group_criterion_customizer_path - ) - ad_group_criterion_label_path = staticmethod( - BatchJobServiceClient.ad_group_criterion_label_path - ) - parse_ad_group_criterion_label_path = staticmethod( - BatchJobServiceClient.parse_ad_group_criterion_label_path - ) - ad_group_customizer_path = staticmethod( - BatchJobServiceClient.ad_group_customizer_path - ) - parse_ad_group_customizer_path = staticmethod( - BatchJobServiceClient.parse_ad_group_customizer_path - ) - ad_group_label_path = staticmethod( - BatchJobServiceClient.ad_group_label_path - ) - parse_ad_group_label_path = staticmethod( - BatchJobServiceClient.parse_ad_group_label_path - ) - ad_parameter_path = staticmethod(BatchJobServiceClient.ad_parameter_path) - parse_ad_parameter_path = staticmethod( - BatchJobServiceClient.parse_ad_parameter_path - ) - asset_path = staticmethod(BatchJobServiceClient.asset_path) - parse_asset_path = staticmethod(BatchJobServiceClient.parse_asset_path) - asset_group_path = staticmethod(BatchJobServiceClient.asset_group_path) - parse_asset_group_path = staticmethod( - BatchJobServiceClient.parse_asset_group_path - ) - asset_group_asset_path = staticmethod( - BatchJobServiceClient.asset_group_asset_path - ) - parse_asset_group_asset_path = staticmethod( - BatchJobServiceClient.parse_asset_group_asset_path - ) - asset_group_listing_group_filter_path = staticmethod( - BatchJobServiceClient.asset_group_listing_group_filter_path - ) - parse_asset_group_listing_group_filter_path = staticmethod( - BatchJobServiceClient.parse_asset_group_listing_group_filter_path - ) - asset_group_signal_path = staticmethod( - BatchJobServiceClient.asset_group_signal_path - ) - parse_asset_group_signal_path = staticmethod( - BatchJobServiceClient.parse_asset_group_signal_path - ) - asset_set_path = staticmethod(BatchJobServiceClient.asset_set_path) - parse_asset_set_path = staticmethod( - BatchJobServiceClient.parse_asset_set_path - ) - asset_set_asset_path = staticmethod( - BatchJobServiceClient.asset_set_asset_path - ) - parse_asset_set_asset_path = staticmethod( - BatchJobServiceClient.parse_asset_set_asset_path - ) - audience_path = staticmethod(BatchJobServiceClient.audience_path) - parse_audience_path = staticmethod( - BatchJobServiceClient.parse_audience_path - ) - batch_job_path = staticmethod(BatchJobServiceClient.batch_job_path) - parse_batch_job_path = staticmethod( - BatchJobServiceClient.parse_batch_job_path - ) - bidding_data_exclusion_path = staticmethod( - BatchJobServiceClient.bidding_data_exclusion_path - ) - parse_bidding_data_exclusion_path = staticmethod( - BatchJobServiceClient.parse_bidding_data_exclusion_path - ) - bidding_seasonality_adjustment_path = staticmethod( - BatchJobServiceClient.bidding_seasonality_adjustment_path - ) - parse_bidding_seasonality_adjustment_path = staticmethod( - BatchJobServiceClient.parse_bidding_seasonality_adjustment_path - ) - bidding_strategy_path = staticmethod( - BatchJobServiceClient.bidding_strategy_path - ) - parse_bidding_strategy_path = staticmethod( - BatchJobServiceClient.parse_bidding_strategy_path - ) - campaign_path = staticmethod(BatchJobServiceClient.campaign_path) - parse_campaign_path = staticmethod( - BatchJobServiceClient.parse_campaign_path - ) - campaign_asset_path = staticmethod( - BatchJobServiceClient.campaign_asset_path - ) - parse_campaign_asset_path = staticmethod( - BatchJobServiceClient.parse_campaign_asset_path - ) - campaign_asset_set_path = staticmethod( - BatchJobServiceClient.campaign_asset_set_path - ) - parse_campaign_asset_set_path = staticmethod( - BatchJobServiceClient.parse_campaign_asset_set_path - ) - campaign_bid_modifier_path = staticmethod( - BatchJobServiceClient.campaign_bid_modifier_path - ) - parse_campaign_bid_modifier_path = staticmethod( - BatchJobServiceClient.parse_campaign_bid_modifier_path - ) - campaign_budget_path = staticmethod( - BatchJobServiceClient.campaign_budget_path - ) - parse_campaign_budget_path = staticmethod( - BatchJobServiceClient.parse_campaign_budget_path - ) - campaign_conversion_goal_path = staticmethod( - BatchJobServiceClient.campaign_conversion_goal_path - ) - parse_campaign_conversion_goal_path = staticmethod( - BatchJobServiceClient.parse_campaign_conversion_goal_path - ) - campaign_criterion_path = staticmethod( - BatchJobServiceClient.campaign_criterion_path - ) - parse_campaign_criterion_path = staticmethod( - BatchJobServiceClient.parse_campaign_criterion_path - ) - campaign_customizer_path = staticmethod( - BatchJobServiceClient.campaign_customizer_path - ) - parse_campaign_customizer_path = staticmethod( - BatchJobServiceClient.parse_campaign_customizer_path - ) - campaign_draft_path = staticmethod( - BatchJobServiceClient.campaign_draft_path - ) - parse_campaign_draft_path = staticmethod( - BatchJobServiceClient.parse_campaign_draft_path - ) - campaign_group_path = staticmethod( - BatchJobServiceClient.campaign_group_path - ) - parse_campaign_group_path = staticmethod( - BatchJobServiceClient.parse_campaign_group_path - ) - campaign_label_path = staticmethod( - BatchJobServiceClient.campaign_label_path - ) - parse_campaign_label_path = staticmethod( - BatchJobServiceClient.parse_campaign_label_path - ) - campaign_shared_set_path = staticmethod( - BatchJobServiceClient.campaign_shared_set_path - ) - parse_campaign_shared_set_path = staticmethod( - BatchJobServiceClient.parse_campaign_shared_set_path - ) - carrier_constant_path = staticmethod( - BatchJobServiceClient.carrier_constant_path - ) - parse_carrier_constant_path = staticmethod( - BatchJobServiceClient.parse_carrier_constant_path - ) - combined_audience_path = staticmethod( - BatchJobServiceClient.combined_audience_path - ) - parse_combined_audience_path = staticmethod( - BatchJobServiceClient.parse_combined_audience_path - ) - conversion_action_path = staticmethod( - BatchJobServiceClient.conversion_action_path - ) - parse_conversion_action_path = staticmethod( - BatchJobServiceClient.parse_conversion_action_path - ) - conversion_custom_variable_path = staticmethod( - BatchJobServiceClient.conversion_custom_variable_path - ) - parse_conversion_custom_variable_path = staticmethod( - BatchJobServiceClient.parse_conversion_custom_variable_path - ) - conversion_goal_campaign_config_path = staticmethod( - BatchJobServiceClient.conversion_goal_campaign_config_path - ) - parse_conversion_goal_campaign_config_path = staticmethod( - BatchJobServiceClient.parse_conversion_goal_campaign_config_path - ) - conversion_value_rule_path = staticmethod( - BatchJobServiceClient.conversion_value_rule_path - ) - parse_conversion_value_rule_path = staticmethod( - BatchJobServiceClient.parse_conversion_value_rule_path - ) - conversion_value_rule_set_path = staticmethod( - BatchJobServiceClient.conversion_value_rule_set_path - ) - parse_conversion_value_rule_set_path = staticmethod( - BatchJobServiceClient.parse_conversion_value_rule_set_path - ) - custom_conversion_goal_path = staticmethod( - BatchJobServiceClient.custom_conversion_goal_path - ) - parse_custom_conversion_goal_path = staticmethod( - BatchJobServiceClient.parse_custom_conversion_goal_path - ) - customer_path = staticmethod(BatchJobServiceClient.customer_path) - parse_customer_path = staticmethod( - BatchJobServiceClient.parse_customer_path - ) - customer_asset_path = staticmethod( - BatchJobServiceClient.customer_asset_path - ) - parse_customer_asset_path = staticmethod( - BatchJobServiceClient.parse_customer_asset_path - ) - customer_conversion_goal_path = staticmethod( - BatchJobServiceClient.customer_conversion_goal_path - ) - parse_customer_conversion_goal_path = staticmethod( - BatchJobServiceClient.parse_customer_conversion_goal_path - ) - customer_customizer_path = staticmethod( - BatchJobServiceClient.customer_customizer_path - ) - parse_customer_customizer_path = staticmethod( - BatchJobServiceClient.parse_customer_customizer_path - ) - customer_label_path = staticmethod( - BatchJobServiceClient.customer_label_path - ) - parse_customer_label_path = staticmethod( - BatchJobServiceClient.parse_customer_label_path - ) - customer_negative_criterion_path = staticmethod( - BatchJobServiceClient.customer_negative_criterion_path - ) - parse_customer_negative_criterion_path = staticmethod( - BatchJobServiceClient.parse_customer_negative_criterion_path - ) - customizer_attribute_path = staticmethod( - BatchJobServiceClient.customizer_attribute_path - ) - parse_customizer_attribute_path = staticmethod( - BatchJobServiceClient.parse_customizer_attribute_path - ) - detailed_demographic_path = staticmethod( - BatchJobServiceClient.detailed_demographic_path - ) - parse_detailed_demographic_path = staticmethod( - BatchJobServiceClient.parse_detailed_demographic_path - ) - experiment_path = staticmethod(BatchJobServiceClient.experiment_path) - parse_experiment_path = staticmethod( - BatchJobServiceClient.parse_experiment_path - ) - experiment_arm_path = staticmethod( - BatchJobServiceClient.experiment_arm_path - ) - parse_experiment_arm_path = staticmethod( - BatchJobServiceClient.parse_experiment_arm_path - ) - geo_target_constant_path = staticmethod( - BatchJobServiceClient.geo_target_constant_path - ) - parse_geo_target_constant_path = staticmethod( - BatchJobServiceClient.parse_geo_target_constant_path - ) - keyword_plan_path = staticmethod(BatchJobServiceClient.keyword_plan_path) - parse_keyword_plan_path = staticmethod( - BatchJobServiceClient.parse_keyword_plan_path - ) - keyword_plan_ad_group_path = staticmethod( - BatchJobServiceClient.keyword_plan_ad_group_path - ) - parse_keyword_plan_ad_group_path = staticmethod( - BatchJobServiceClient.parse_keyword_plan_ad_group_path - ) - keyword_plan_ad_group_keyword_path = staticmethod( - BatchJobServiceClient.keyword_plan_ad_group_keyword_path - ) - parse_keyword_plan_ad_group_keyword_path = staticmethod( - BatchJobServiceClient.parse_keyword_plan_ad_group_keyword_path - ) - keyword_plan_campaign_path = staticmethod( - BatchJobServiceClient.keyword_plan_campaign_path - ) - parse_keyword_plan_campaign_path = staticmethod( - BatchJobServiceClient.parse_keyword_plan_campaign_path - ) - keyword_plan_campaign_keyword_path = staticmethod( - BatchJobServiceClient.keyword_plan_campaign_keyword_path - ) - parse_keyword_plan_campaign_keyword_path = staticmethod( - BatchJobServiceClient.parse_keyword_plan_campaign_keyword_path - ) - keyword_theme_constant_path = staticmethod( - BatchJobServiceClient.keyword_theme_constant_path - ) - parse_keyword_theme_constant_path = staticmethod( - BatchJobServiceClient.parse_keyword_theme_constant_path - ) - label_path = staticmethod(BatchJobServiceClient.label_path) - parse_label_path = staticmethod(BatchJobServiceClient.parse_label_path) - language_constant_path = staticmethod( - BatchJobServiceClient.language_constant_path - ) - parse_language_constant_path = staticmethod( - BatchJobServiceClient.parse_language_constant_path - ) - life_event_path = staticmethod(BatchJobServiceClient.life_event_path) - parse_life_event_path = staticmethod( - BatchJobServiceClient.parse_life_event_path - ) - mobile_app_category_constant_path = staticmethod( - BatchJobServiceClient.mobile_app_category_constant_path - ) - parse_mobile_app_category_constant_path = staticmethod( - BatchJobServiceClient.parse_mobile_app_category_constant_path - ) - mobile_device_constant_path = staticmethod( - BatchJobServiceClient.mobile_device_constant_path - ) - parse_mobile_device_constant_path = staticmethod( - BatchJobServiceClient.parse_mobile_device_constant_path - ) - operating_system_version_constant_path = staticmethod( - BatchJobServiceClient.operating_system_version_constant_path - ) - parse_operating_system_version_constant_path = staticmethod( - BatchJobServiceClient.parse_operating_system_version_constant_path - ) - recommendation_subscription_path = staticmethod( - BatchJobServiceClient.recommendation_subscription_path - ) - parse_recommendation_subscription_path = staticmethod( - BatchJobServiceClient.parse_recommendation_subscription_path - ) - remarketing_action_path = staticmethod( - BatchJobServiceClient.remarketing_action_path - ) - parse_remarketing_action_path = staticmethod( - BatchJobServiceClient.parse_remarketing_action_path - ) - shared_criterion_path = staticmethod( - BatchJobServiceClient.shared_criterion_path - ) - parse_shared_criterion_path = staticmethod( - BatchJobServiceClient.parse_shared_criterion_path - ) - shared_set_path = staticmethod(BatchJobServiceClient.shared_set_path) - parse_shared_set_path = staticmethod( - BatchJobServiceClient.parse_shared_set_path - ) - smart_campaign_setting_path = staticmethod( - BatchJobServiceClient.smart_campaign_setting_path - ) - parse_smart_campaign_setting_path = staticmethod( - BatchJobServiceClient.parse_smart_campaign_setting_path - ) - topic_constant_path = staticmethod( - BatchJobServiceClient.topic_constant_path - ) - parse_topic_constant_path = staticmethod( - BatchJobServiceClient.parse_topic_constant_path - ) - user_interest_path = staticmethod(BatchJobServiceClient.user_interest_path) - parse_user_interest_path = staticmethod( - BatchJobServiceClient.parse_user_interest_path - ) - user_list_path = staticmethod(BatchJobServiceClient.user_list_path) - parse_user_list_path = staticmethod( - BatchJobServiceClient.parse_user_list_path - ) - common_billing_account_path = staticmethod( - BatchJobServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - BatchJobServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(BatchJobServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - BatchJobServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - BatchJobServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - BatchJobServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - BatchJobServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - BatchJobServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - BatchJobServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - BatchJobServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BatchJobServiceAsyncClient: The constructed client. - """ - return BatchJobServiceClient.from_service_account_info.__func__(BatchJobServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BatchJobServiceAsyncClient: The constructed client. - """ - return BatchJobServiceClient.from_service_account_file.__func__(BatchJobServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return BatchJobServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> BatchJobServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BatchJobServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = BatchJobServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BatchJobServiceTransport, - Callable[..., BatchJobServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the batch job service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BatchJobServiceTransport,Callable[..., BatchJobServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BatchJobServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = BatchJobServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.BatchJobServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BatchJobService", - "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.ads.googleads.v19.services.BatchJobService", - "credentialsType": None, - } - ), - ) - - async def mutate_batch_job( - self, - request: Optional[ - Union[batch_job_service.MutateBatchJobRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[batch_job_service.BatchJobOperation] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> batch_job_service.MutateBatchJobResponse: - r"""Mutates a batch job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateBatchJobRequest, dict]]): - The request object. Request message for - [BatchJobService.MutateBatchJob][google.ads.googleads.v19.services.BatchJobService.MutateBatchJob]. - customer_id (:class:`str`): - Required. The ID of the customer for - which to create a batch job. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (:class:`google.ads.googleads.v19.services.types.BatchJobOperation`): - Required. The operation to perform on - an individual batch job. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateBatchJobResponse: - Response message for - [BatchJobService.MutateBatchJob][google.ads.googleads.v19.services.BatchJobService.MutateBatchJob]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, batch_job_service.MutateBatchJobRequest): - request = batch_job_service.MutateBatchJobRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_batch_job - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_batch_job_results( - self, - request: Optional[ - Union[batch_job_service.ListBatchJobResultsRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListBatchJobResultsAsyncPager: - r"""Returns the results of the batch job. The job must be done. - Supports standard list paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ListBatchJobResultsRequest, dict]]): - The request object. Request message for - [BatchJobService.ListBatchJobResults][google.ads.googleads.v19.services.BatchJobService.ListBatchJobResults]. - resource_name (:class:`str`): - Required. The resource name of the - batch job whose results are being - listed. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.batch_job_service.pagers.ListBatchJobResultsAsyncPager: - Response message for - [BatchJobService.ListBatchJobResults][google.ads.googleads.v19.services.BatchJobService.ListBatchJobResults]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, batch_job_service.ListBatchJobResultsRequest - ): - request = batch_job_service.ListBatchJobResultsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_batch_job_results - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.ListBatchJobResultsAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def run_batch_job( - self, - request: Optional[ - Union[batch_job_service.RunBatchJobRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operation_async.AsyncOperation: - r"""Runs the batch job. - - The Operation.metadata field type is BatchJobMetadata. When - finished, the long running operation will not contain errors or - a response. Instead, use ListBatchJobResults to get the results - of the job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.RunBatchJobRequest, dict]]): - The request object. Request message for - [BatchJobService.RunBatchJob][google.ads.googleads.v19.services.BatchJobService.RunBatchJob]. - resource_name (:class:`str`): - Required. The resource name of the - BatchJob to run. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, batch_job_service.RunBatchJobRequest): - request = batch_job_service.RunBatchJobRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.run_batch_job - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - empty_pb2.Empty, - metadata_type=batch_job.BatchJob.BatchJobMetadata, - ) - - # Done; return the response. - return response - - async def add_batch_job_operations( - self, - request: Optional[ - Union[batch_job_service.AddBatchJobOperationsRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - sequence_token: Optional[str] = None, - mutate_operations: Optional[ - MutableSequence[google_ads_service.MutateOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> batch_job_service.AddBatchJobOperationsResponse: - r"""Add operations to the batch job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.AddBatchJobOperationsRequest, dict]]): - The request object. Request message for - [BatchJobService.AddBatchJobOperations][google.ads.googleads.v19.services.BatchJobService.AddBatchJobOperations]. - resource_name (:class:`str`): - Required. The resource name of the - batch job. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - sequence_token (:class:`str`): - A token used to enforce sequencing. - - The first AddBatchJobOperations request for a batch job - should not set sequence_token. Subsequent requests must - set sequence_token to the value of next_sequence_token - received in the previous AddBatchJobOperations response. - - This corresponds to the ``sequence_token`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - mutate_operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.MutateOperation]`): - Required. The list of mutates being - added. - Operations can use negative integers as - temp ids to signify dependencies between - entities created in this batch job. For - example, a customer with id = 1234 can - create a campaign and an ad group in - that same campaign by creating a - campaign in the first operation with the - resource name explicitly set to - "customers/1234/campaigns/-1", and - creating an ad group in the second - operation with the campaign field also - set to "customers/1234/campaigns/-1". - - This corresponds to the ``mutate_operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.AddBatchJobOperationsResponse: - Response message for - [BatchJobService.AddBatchJobOperations][google.ads.googleads.v19.services.BatchJobService.AddBatchJobOperations]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name, sequence_token, mutate_operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, batch_job_service.AddBatchJobOperationsRequest - ): - request = batch_job_service.AddBatchJobOperationsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - if sequence_token is not None: - request.sequence_token = sequence_token - if mutate_operations: - request.mutate_operations.extend(mutate_operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.add_batch_job_operations - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "BatchJobServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("BatchJobServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/batch_job_service/client.py b/google/ads/googleads/v19/services/services/batch_job_service/client.py deleted file mode 100644 index 144b12dd8..000000000 --- a/google/ads/googleads/v19/services/services/batch_job_service/client.py +++ /dev/null @@ -1,2769 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.resources.types import batch_job -from google.ads.googleads.v19.services.services.batch_job_service import pagers -from google.ads.googleads.v19.services.types import batch_job_service -from google.ads.googleads.v19.services.types import google_ads_service -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from .transports.base import BatchJobServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import BatchJobServiceGrpcTransport -from .transports.grpc_asyncio import BatchJobServiceGrpcAsyncIOTransport - - -class BatchJobServiceClientMeta(type): - """Metaclass for the BatchJobService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[BatchJobServiceTransport]] - _transport_registry["grpc"] = BatchJobServiceGrpcTransport - _transport_registry["grpc_asyncio"] = BatchJobServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[BatchJobServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class BatchJobServiceClient(metaclass=BatchJobServiceClientMeta): - """Service to manage batch jobs.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BatchJobServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BatchJobServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> BatchJobServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BatchJobServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def accessible_bidding_strategy_path( - customer_id: str, - bidding_strategy_id: str, - ) -> str: - """Returns a fully-qualified accessible_bidding_strategy string.""" - return "customers/{customer_id}/accessibleBiddingStrategies/{bidding_strategy_id}".format( - customer_id=customer_id, - bidding_strategy_id=bidding_strategy_id, - ) - - @staticmethod - def parse_accessible_bidding_strategy_path(path: str) -> Dict[str, str]: - """Parses a accessible_bidding_strategy path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/accessibleBiddingStrategies/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_path( - customer_id: str, - ad_id: str, - ) -> str: - """Returns a fully-qualified ad string.""" - return "customers/{customer_id}/ads/{ad_id}".format( - customer_id=customer_id, - ad_id=ad_id, - ) - - @staticmethod - def parse_ad_path(path: str) -> Dict[str, str]: - """Parses a ad path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/ads/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_path( - customer_id: str, - ad_group_id: str, - ) -> str: - """Returns a fully-qualified ad_group string.""" - return "customers/{customer_id}/adGroups/{ad_group_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ) - - @staticmethod - def parse_ad_group_path(path: str) -> Dict[str, str]: - """Parses a ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_ad_path( - customer_id: str, - ad_group_id: str, - ad_id: str, - ) -> str: - """Returns a fully-qualified ad_group_ad string.""" - return ( - "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ad_id=ad_id, - ) - ) - - @staticmethod - def parse_ad_group_ad_path(path: str) -> Dict[str, str]: - """Parses a ad_group_ad path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_ad_label_path( - customer_id: str, - ad_group_id: str, - ad_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_ad_label string.""" - return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ad_id=ad_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_ad_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_asset_path( - customer_id: str, - ad_group_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified ad_group_asset string.""" - return "customers/{customer_id}/adGroupAssets/{ad_group_id}~{asset_id}~{field_type}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_ad_group_asset_path(path: str) -> Dict[str, str]: - """Parses a ad_group_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_bid_modifier_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified ad_group_bid_modifier string.""" - return "customers/{customer_id}/adGroupBidModifiers/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_ad_group_bid_modifier_path(path: str) -> Dict[str, str]: - """Parses a ad_group_bid_modifier path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupBidModifiers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_criterion_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion string.""" - return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_criterion_customizer_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion_customizer string.""" - return "customers/{customer_id}/adGroupCriterionCustomizers/{ad_group_id}~{criterion_id}~{customizer_attribute_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_ad_group_criterion_customizer_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriterionCustomizers/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_criterion_label_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion_label string.""" - return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_customizer_path( - customer_id: str, - ad_group_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified ad_group_customizer string.""" - return "customers/{customer_id}/adGroupCustomizers/{ad_group_id}~{customizer_attribute_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_ad_group_customizer_path(path: str) -> Dict[str, str]: - """Parses a ad_group_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCustomizers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_label_path( - customer_id: str, - ad_group_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_label string.""" - return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_parameter_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - parameter_index: str, - ) -> str: - """Returns a fully-qualified ad_parameter string.""" - return "customers/{customer_id}/adParameters/{ad_group_id}~{criterion_id}~{parameter_index}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - parameter_index=parameter_index, - ) - - @staticmethod - def parse_ad_parameter_path(path: str) -> Dict[str, str]: - """Parses a ad_parameter path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adParameters/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_path( - customer_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset string.""" - return "customers/{customer_id}/assets/{asset_id}".format( - customer_id=customer_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_path(path: str) -> Dict[str, str]: - """Parses a asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assets/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_path( - customer_id: str, - asset_group_id: str, - ) -> str: - """Returns a fully-qualified asset_group string.""" - return "customers/{customer_id}/assetGroups/{asset_group_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - ) - - @staticmethod - def parse_asset_group_path(path: str) -> Dict[str, str]: - """Parses a asset_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_asset_path( - customer_id: str, - asset_group_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified asset_group_asset string.""" - return "customers/{customer_id}/assetGroupAssets/{asset_group_id}~{asset_id}~{field_type}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_asset_group_asset_path(path: str) -> Dict[str, str]: - """Parses a asset_group_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_listing_group_filter_path( - customer_id: str, - asset_group_id: str, - listing_group_filter_id: str, - ) -> str: - """Returns a fully-qualified asset_group_listing_group_filter string.""" - return "customers/{customer_id}/assetGroupListingGroupFilters/{asset_group_id}~{listing_group_filter_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - listing_group_filter_id=listing_group_filter_id, - ) - - @staticmethod - def parse_asset_group_listing_group_filter_path( - path: str, - ) -> Dict[str, str]: - """Parses a asset_group_listing_group_filter path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroupListingGroupFilters/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_signal_path( - customer_id: str, - asset_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified asset_group_signal string.""" - return "customers/{customer_id}/assetGroupSignals/{asset_group_id}~{criterion_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_asset_group_signal_path(path: str) -> Dict[str, str]: - """Parses a asset_group_signal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroupSignals/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_set_path( - customer_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified asset_set string.""" - return "customers/{customer_id}/assetSets/{asset_set_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_asset_set_path(path: str) -> Dict[str, str]: - """Parses a asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_set_asset_path( - customer_id: str, - asset_set_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset_set_asset string.""" - return "customers/{customer_id}/assetSetAssets/{asset_set_id}~{asset_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_set_asset_path(path: str) -> Dict[str, str]: - """Parses a asset_set_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSetAssets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def audience_path( - customer_id: str, - audience_id: str, - ) -> str: - """Returns a fully-qualified audience string.""" - return "customers/{customer_id}/audiences/{audience_id}".format( - customer_id=customer_id, - audience_id=audience_id, - ) - - @staticmethod - def parse_audience_path(path: str) -> Dict[str, str]: - """Parses a audience path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/audiences/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def batch_job_path( - customer_id: str, - batch_job_id: str, - ) -> str: - """Returns a fully-qualified batch_job string.""" - return "customers/{customer_id}/batchJobs/{batch_job_id}".format( - customer_id=customer_id, - batch_job_id=batch_job_id, - ) - - @staticmethod - def parse_batch_job_path(path: str) -> Dict[str, str]: - """Parses a batch_job path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/batchJobs/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def bidding_data_exclusion_path( - customer_id: str, - seasonality_event_id: str, - ) -> str: - """Returns a fully-qualified bidding_data_exclusion string.""" - return "customers/{customer_id}/biddingDataExclusions/{seasonality_event_id}".format( - customer_id=customer_id, - seasonality_event_id=seasonality_event_id, - ) - - @staticmethod - def parse_bidding_data_exclusion_path(path: str) -> Dict[str, str]: - """Parses a bidding_data_exclusion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/biddingDataExclusions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def bidding_seasonality_adjustment_path( - customer_id: str, - seasonality_event_id: str, - ) -> str: - """Returns a fully-qualified bidding_seasonality_adjustment string.""" - return "customers/{customer_id}/biddingSeasonalityAdjustments/{seasonality_event_id}".format( - customer_id=customer_id, - seasonality_event_id=seasonality_event_id, - ) - - @staticmethod - def parse_bidding_seasonality_adjustment_path(path: str) -> Dict[str, str]: - """Parses a bidding_seasonality_adjustment path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/biddingSeasonalityAdjustments/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def bidding_strategy_path( - customer_id: str, - bidding_strategy_id: str, - ) -> str: - """Returns a fully-qualified bidding_strategy string.""" - return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( - customer_id=customer_id, - bidding_strategy_id=bidding_strategy_id, - ) - - @staticmethod - def parse_bidding_strategy_path(path: str) -> Dict[str, str]: - """Parses a bidding_strategy path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_asset_path( - customer_id: str, - campaign_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified campaign_asset string.""" - return "customers/{customer_id}/campaignAssets/{campaign_id}~{asset_id}~{field_type}".format( - customer_id=customer_id, - campaign_id=campaign_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_campaign_asset_path(path: str) -> Dict[str, str]: - """Parses a campaign_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignAssets/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_asset_set_path( - customer_id: str, - campaign_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified campaign_asset_set string.""" - return "customers/{customer_id}/campaignAssetSets/{campaign_id}~{asset_set_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_campaign_asset_set_path(path: str) -> Dict[str, str]: - """Parses a campaign_asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignAssetSets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_bid_modifier_path( - customer_id: str, - campaign_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified campaign_bid_modifier string.""" - return "customers/{customer_id}/campaignBidModifiers/{campaign_id}~{criterion_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_campaign_bid_modifier_path(path: str) -> Dict[str, str]: - """Parses a campaign_bid_modifier path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignBidModifiers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_budget_path( - customer_id: str, - campaign_budget_id: str, - ) -> str: - """Returns a fully-qualified campaign_budget string.""" - return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( - customer_id=customer_id, - campaign_budget_id=campaign_budget_id, - ) - - @staticmethod - def parse_campaign_budget_path(path: str) -> Dict[str, str]: - """Parses a campaign_budget path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_conversion_goal_path( - customer_id: str, - campaign_id: str, - category: str, - source: str, - ) -> str: - """Returns a fully-qualified campaign_conversion_goal string.""" - return "customers/{customer_id}/campaignConversionGoals/{campaign_id}~{category}~{source}".format( - customer_id=customer_id, - campaign_id=campaign_id, - category=category, - source=source, - ) - - @staticmethod - def parse_campaign_conversion_goal_path(path: str) -> Dict[str, str]: - """Parses a campaign_conversion_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignConversionGoals/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_criterion_path( - customer_id: str, - campaign_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified campaign_criterion string.""" - return "customers/{customer_id}/campaignCriteria/{campaign_id}~{criterion_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_campaign_criterion_path(path: str) -> Dict[str, str]: - """Parses a campaign_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_customizer_path( - customer_id: str, - campaign_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified campaign_customizer string.""" - return "customers/{customer_id}/campaignCustomizers/{campaign_id}~{customizer_attribute_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_campaign_customizer_path(path: str) -> Dict[str, str]: - """Parses a campaign_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignCustomizers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_draft_path( - customer_id: str, - base_campaign_id: str, - draft_id: str, - ) -> str: - """Returns a fully-qualified campaign_draft string.""" - return "customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}".format( - customer_id=customer_id, - base_campaign_id=base_campaign_id, - draft_id=draft_id, - ) - - @staticmethod - def parse_campaign_draft_path(path: str) -> Dict[str, str]: - """Parses a campaign_draft path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignDrafts/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_group_path( - customer_id: str, - campaign_group_id: str, - ) -> str: - """Returns a fully-qualified campaign_group string.""" - return ( - "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( - customer_id=customer_id, - campaign_group_id=campaign_group_id, - ) - ) - - @staticmethod - def parse_campaign_group_path(path: str) -> Dict[str, str]: - """Parses a campaign_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_label_path( - customer_id: str, - campaign_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified campaign_label string.""" - return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - label_id=label_id, - ) - - @staticmethod - def parse_campaign_label_path(path: str) -> Dict[str, str]: - """Parses a campaign_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_shared_set_path( - customer_id: str, - campaign_id: str, - shared_set_id: str, - ) -> str: - """Returns a fully-qualified campaign_shared_set string.""" - return "customers/{customer_id}/campaignSharedSets/{campaign_id}~{shared_set_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - shared_set_id=shared_set_id, - ) - - @staticmethod - def parse_campaign_shared_set_path(path: str) -> Dict[str, str]: - """Parses a campaign_shared_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignSharedSets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def carrier_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified carrier_constant string.""" - return "carrierConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_carrier_constant_path(path: str) -> Dict[str, str]: - """Parses a carrier_constant path into its component segments.""" - m = re.match(r"^carrierConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def combined_audience_path( - customer_id: str, - combined_audience_id: str, - ) -> str: - """Returns a fully-qualified combined_audience string.""" - return "customers/{customer_id}/combinedAudiences/{combined_audience_id}".format( - customer_id=customer_id, - combined_audience_id=combined_audience_id, - ) - - @staticmethod - def parse_combined_audience_path(path: str) -> Dict[str, str]: - """Parses a combined_audience path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/combinedAudiences/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_action_path( - customer_id: str, - conversion_action_id: str, - ) -> str: - """Returns a fully-qualified conversion_action string.""" - return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( - customer_id=customer_id, - conversion_action_id=conversion_action_id, - ) - - @staticmethod - def parse_conversion_action_path(path: str) -> Dict[str, str]: - """Parses a conversion_action path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionActions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_custom_variable_path( - customer_id: str, - conversion_custom_variable_id: str, - ) -> str: - """Returns a fully-qualified conversion_custom_variable string.""" - return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( - customer_id=customer_id, - conversion_custom_variable_id=conversion_custom_variable_id, - ) - - @staticmethod - def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: - """Parses a conversion_custom_variable path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_goal_campaign_config_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified conversion_goal_campaign_config string.""" - return "customers/{customer_id}/conversionGoalCampaignConfigs/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_conversion_goal_campaign_config_path(path: str) -> Dict[str, str]: - """Parses a conversion_goal_campaign_config path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionGoalCampaignConfigs/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_value_rule_path( - customer_id: str, - conversion_value_rule_id: str, - ) -> str: - """Returns a fully-qualified conversion_value_rule string.""" - return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( - customer_id=customer_id, - conversion_value_rule_id=conversion_value_rule_id, - ) - - @staticmethod - def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: - """Parses a conversion_value_rule path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_value_rule_set_path( - customer_id: str, - conversion_value_rule_set_id: str, - ) -> str: - """Returns a fully-qualified conversion_value_rule_set string.""" - return "customers/{customer_id}/conversionValueRuleSets/{conversion_value_rule_set_id}".format( - customer_id=customer_id, - conversion_value_rule_set_id=conversion_value_rule_set_id, - ) - - @staticmethod - def parse_conversion_value_rule_set_path(path: str) -> Dict[str, str]: - """Parses a conversion_value_rule_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionValueRuleSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def custom_conversion_goal_path( - customer_id: str, - goal_id: str, - ) -> str: - """Returns a fully-qualified custom_conversion_goal string.""" - return "customers/{customer_id}/customConversionGoals/{goal_id}".format( - customer_id=customer_id, - goal_id=goal_id, - ) - - @staticmethod - def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: - """Parses a custom_conversion_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def customer_asset_path( - customer_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified customer_asset string.""" - return "customers/{customer_id}/customerAssets/{asset_id}~{field_type}".format( - customer_id=customer_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_customer_asset_path(path: str) -> Dict[str, str]: - """Parses a customer_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerAssets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_conversion_goal_path( - customer_id: str, - category: str, - source: str, - ) -> str: - """Returns a fully-qualified customer_conversion_goal string.""" - return "customers/{customer_id}/customerConversionGoals/{category}~{source}".format( - customer_id=customer_id, - category=category, - source=source, - ) - - @staticmethod - def parse_customer_conversion_goal_path(path: str) -> Dict[str, str]: - """Parses a customer_conversion_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerConversionGoals/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_customizer_path( - customer_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified customer_customizer string.""" - return "customers/{customer_id}/customerCustomizers/{customizer_attribute_id}".format( - customer_id=customer_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_customer_customizer_path(path: str) -> Dict[str, str]: - """Parses a customer_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerCustomizers/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_label_path( - customer_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified customer_label string.""" - return "customers/{customer_id}/customerLabels/{label_id}".format( - customer_id=customer_id, - label_id=label_id, - ) - - @staticmethod - def parse_customer_label_path(path: str) -> Dict[str, str]: - """Parses a customer_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerLabels/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_negative_criterion_path( - customer_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified customer_negative_criterion string.""" - return "customers/{customer_id}/customerNegativeCriteria/{criterion_id}".format( - customer_id=customer_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_customer_negative_criterion_path(path: str) -> Dict[str, str]: - """Parses a customer_negative_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerNegativeCriteria/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customizer_attribute_path( - customer_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified customizer_attribute string.""" - return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( - customer_id=customer_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_customizer_attribute_path(path: str) -> Dict[str, str]: - """Parses a customizer_attribute path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def detailed_demographic_path( - customer_id: str, - detailed_demographic_id: str, - ) -> str: - """Returns a fully-qualified detailed_demographic string.""" - return "customers/{customer_id}/detailedDemographics/{detailed_demographic_id}".format( - customer_id=customer_id, - detailed_demographic_id=detailed_demographic_id, - ) - - @staticmethod - def parse_detailed_demographic_path(path: str) -> Dict[str, str]: - """Parses a detailed_demographic path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/detailedDemographics/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def experiment_path( - customer_id: str, - trial_id: str, - ) -> str: - """Returns a fully-qualified experiment string.""" - return "customers/{customer_id}/experiments/{trial_id}".format( - customer_id=customer_id, - trial_id=trial_id, - ) - - @staticmethod - def parse_experiment_path(path: str) -> Dict[str, str]: - """Parses a experiment path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/experiments/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def experiment_arm_path( - customer_id: str, - trial_id: str, - trial_arm_id: str, - ) -> str: - """Returns a fully-qualified experiment_arm string.""" - return "customers/{customer_id}/experimentArms/{trial_id}~{trial_arm_id}".format( - customer_id=customer_id, - trial_id=trial_id, - trial_arm_id=trial_arm_id, - ) - - @staticmethod - def parse_experiment_arm_path(path: str) -> Dict[str, str]: - """Parses a experiment_arm path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/experimentArms/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def geo_target_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified geo_target_constant string.""" - return "geoTargetConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_geo_target_constant_path(path: str) -> Dict[str, str]: - """Parses a geo_target_constant path into its component segments.""" - m = re.match(r"^geoTargetConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_path( - customer_id: str, - keyword_plan_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan string.""" - return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( - customer_id=customer_id, - keyword_plan_id=keyword_plan_id, - ) - - @staticmethod - def parse_keyword_plan_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_ad_group_path( - customer_id: str, - keyword_plan_ad_group_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_ad_group string.""" - return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( - customer_id=customer_id, - keyword_plan_ad_group_id=keyword_plan_ad_group_id, - ) - - @staticmethod - def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_ad_group_keyword_path( - customer_id: str, - keyword_plan_ad_group_keyword_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_ad_group_keyword string.""" - return "customers/{customer_id}/keywordPlanAdGroupKeywords/{keyword_plan_ad_group_keyword_id}".format( - customer_id=customer_id, - keyword_plan_ad_group_keyword_id=keyword_plan_ad_group_keyword_id, - ) - - @staticmethod - def parse_keyword_plan_ad_group_keyword_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_ad_group_keyword path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanAdGroupKeywords/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_campaign_path( - customer_id: str, - keyword_plan_campaign_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_campaign string.""" - return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( - customer_id=customer_id, - keyword_plan_campaign_id=keyword_plan_campaign_id, - ) - - @staticmethod - def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_campaign_keyword_path( - customer_id: str, - keyword_plan_campaign_keyword_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_campaign_keyword string.""" - return "customers/{customer_id}/keywordPlanCampaignKeywords/{keyword_plan_campaign_keyword_id}".format( - customer_id=customer_id, - keyword_plan_campaign_keyword_id=keyword_plan_campaign_keyword_id, - ) - - @staticmethod - def parse_keyword_plan_campaign_keyword_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_campaign_keyword path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanCampaignKeywords/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_theme_constant_path( - express_category_id: str, - express_sub_category_id: str, - ) -> str: - """Returns a fully-qualified keyword_theme_constant string.""" - return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( - express_category_id=express_category_id, - express_sub_category_id=express_sub_category_id, - ) - - @staticmethod - def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: - """Parses a keyword_theme_constant path into its component segments.""" - m = re.match( - r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def label_path( - customer_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified label string.""" - return "customers/{customer_id}/labels/{label_id}".format( - customer_id=customer_id, - label_id=label_id, - ) - - @staticmethod - def parse_label_path(path: str) -> Dict[str, str]: - """Parses a label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/labels/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def language_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified language_constant string.""" - return "languageConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_language_constant_path(path: str) -> Dict[str, str]: - """Parses a language_constant path into its component segments.""" - m = re.match(r"^languageConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def life_event_path( - customer_id: str, - life_event_id: str, - ) -> str: - """Returns a fully-qualified life_event string.""" - return "customers/{customer_id}/lifeEvents/{life_event_id}".format( - customer_id=customer_id, - life_event_id=life_event_id, - ) - - @staticmethod - def parse_life_event_path(path: str) -> Dict[str, str]: - """Parses a life_event path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/lifeEvents/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def mobile_app_category_constant_path( - mobile_app_category_id: str, - ) -> str: - """Returns a fully-qualified mobile_app_category_constant string.""" - return "mobileAppCategoryConstants/{mobile_app_category_id}".format( - mobile_app_category_id=mobile_app_category_id, - ) - - @staticmethod - def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: - """Parses a mobile_app_category_constant path into its component segments.""" - m = re.match( - r"^mobileAppCategoryConstants/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def mobile_device_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified mobile_device_constant string.""" - return "mobileDeviceConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_mobile_device_constant_path(path: str) -> Dict[str, str]: - """Parses a mobile_device_constant path into its component segments.""" - m = re.match(r"^mobileDeviceConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def operating_system_version_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified operating_system_version_constant string.""" - return "operatingSystemVersionConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_operating_system_version_constant_path( - path: str, - ) -> Dict[str, str]: - """Parses a operating_system_version_constant path into its component segments.""" - m = re.match( - r"^operatingSystemVersionConstants/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def recommendation_subscription_path( - customer_id: str, - recommendation_type: str, - ) -> str: - """Returns a fully-qualified recommendation_subscription string.""" - return "customers/{customer_id}/recommendationSubscriptions/{recommendation_type}".format( - customer_id=customer_id, - recommendation_type=recommendation_type, - ) - - @staticmethod - def parse_recommendation_subscription_path(path: str) -> Dict[str, str]: - """Parses a recommendation_subscription path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/recommendationSubscriptions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def remarketing_action_path( - customer_id: str, - remarketing_action_id: str, - ) -> str: - """Returns a fully-qualified remarketing_action string.""" - return "customers/{customer_id}/remarketingActions/{remarketing_action_id}".format( - customer_id=customer_id, - remarketing_action_id=remarketing_action_id, - ) - - @staticmethod - def parse_remarketing_action_path(path: str) -> Dict[str, str]: - """Parses a remarketing_action path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/remarketingActions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def shared_criterion_path( - customer_id: str, - shared_set_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified shared_criterion string.""" - return "customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}".format( - customer_id=customer_id, - shared_set_id=shared_set_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_shared_criterion_path(path: str) -> Dict[str, str]: - """Parses a shared_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/sharedCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def shared_set_path( - customer_id: str, - shared_set_id: str, - ) -> str: - """Returns a fully-qualified shared_set string.""" - return "customers/{customer_id}/sharedSets/{shared_set_id}".format( - customer_id=customer_id, - shared_set_id=shared_set_id, - ) - - @staticmethod - def parse_shared_set_path(path: str) -> Dict[str, str]: - """Parses a shared_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/sharedSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def smart_campaign_setting_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified smart_campaign_setting string.""" - return "customers/{customer_id}/smartCampaignSettings/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_smart_campaign_setting_path(path: str) -> Dict[str, str]: - """Parses a smart_campaign_setting path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/smartCampaignSettings/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def topic_constant_path( - topic_id: str, - ) -> str: - """Returns a fully-qualified topic_constant string.""" - return "topicConstants/{topic_id}".format( - topic_id=topic_id, - ) - - @staticmethod - def parse_topic_constant_path(path: str) -> Dict[str, str]: - """Parses a topic_constant path into its component segments.""" - m = re.match(r"^topicConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def user_interest_path( - customer_id: str, - user_interest_id: str, - ) -> str: - """Returns a fully-qualified user_interest string.""" - return ( - "customers/{customer_id}/userInterests/{user_interest_id}".format( - customer_id=customer_id, - user_interest_id=user_interest_id, - ) - ) - - @staticmethod - def parse_user_interest_path(path: str) -> Dict[str, str]: - """Parses a user_interest path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/userInterests/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def user_list_path( - customer_id: str, - user_list_id: str, - ) -> str: - """Returns a fully-qualified user_list string.""" - return "customers/{customer_id}/userLists/{user_list_id}".format( - customer_id=customer_id, - user_list_id=user_list_id, - ) - - @staticmethod - def parse_user_list_path(path: str) -> Dict[str, str]: - """Parses a user_list path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/userLists/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = BatchJobServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = BatchJobServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - BatchJobServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = BatchJobServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BatchJobServiceTransport, - Callable[..., BatchJobServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the batch job service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BatchJobServiceTransport,Callable[..., BatchJobServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BatchJobServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = BatchJobServiceClient._read_environment_variables() - self._client_cert_source = ( - BatchJobServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = BatchJobServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, BatchJobServiceTransport) - if transport_provided: - # transport is a BatchJobServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(BatchJobServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or BatchJobServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[BatchJobServiceTransport], - Callable[..., BatchJobServiceTransport], - ] = ( - BatchJobServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., BatchJobServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.BatchJobServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BatchJobService", - "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.ads.googleads.v19.services.BatchJobService", - "credentialsType": None, - } - ), - ) - - def mutate_batch_job( - self, - request: Optional[ - Union[batch_job_service.MutateBatchJobRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[batch_job_service.BatchJobOperation] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> batch_job_service.MutateBatchJobResponse: - r"""Mutates a batch job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateBatchJobRequest, dict]): - The request object. Request message for - [BatchJobService.MutateBatchJob][google.ads.googleads.v19.services.BatchJobService.MutateBatchJob]. - customer_id (str): - Required. The ID of the customer for - which to create a batch job. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (google.ads.googleads.v19.services.types.BatchJobOperation): - Required. The operation to perform on - an individual batch job. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateBatchJobResponse: - Response message for - [BatchJobService.MutateBatchJob][google.ads.googleads.v19.services.BatchJobService.MutateBatchJob]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, batch_job_service.MutateBatchJobRequest): - request = batch_job_service.MutateBatchJobRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.mutate_batch_job] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_batch_job_results( - self, - request: Optional[ - Union[batch_job_service.ListBatchJobResultsRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListBatchJobResultsPager: - r"""Returns the results of the batch job. The job must be done. - Supports standard list paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ListBatchJobResultsRequest, dict]): - The request object. Request message for - [BatchJobService.ListBatchJobResults][google.ads.googleads.v19.services.BatchJobService.ListBatchJobResults]. - resource_name (str): - Required. The resource name of the - batch job whose results are being - listed. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.batch_job_service.pagers.ListBatchJobResultsPager: - Response message for - [BatchJobService.ListBatchJobResults][google.ads.googleads.v19.services.BatchJobService.ListBatchJobResults]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, batch_job_service.ListBatchJobResultsRequest - ): - request = batch_job_service.ListBatchJobResultsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.list_batch_job_results - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.ListBatchJobResultsPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def run_batch_job( - self, - request: Optional[ - Union[batch_job_service.RunBatchJobRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operation.Operation: - r"""Runs the batch job. - - The Operation.metadata field type is BatchJobMetadata. When - finished, the long running operation will not contain errors or - a response. Instead, use ListBatchJobResults to get the results - of the job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.RunBatchJobRequest, dict]): - The request object. Request message for - [BatchJobService.RunBatchJob][google.ads.googleads.v19.services.BatchJobService.RunBatchJob]. - resource_name (str): - Required. The resource name of the - BatchJob to run. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, batch_job_service.RunBatchJobRequest): - request = batch_job_service.RunBatchJobRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.run_batch_job] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - empty_pb2.Empty, - metadata_type=batch_job.BatchJob.BatchJobMetadata, - ) - - # Done; return the response. - return response - - def add_batch_job_operations( - self, - request: Optional[ - Union[batch_job_service.AddBatchJobOperationsRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - sequence_token: Optional[str] = None, - mutate_operations: Optional[ - MutableSequence[google_ads_service.MutateOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> batch_job_service.AddBatchJobOperationsResponse: - r"""Add operations to the batch job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.AddBatchJobOperationsRequest, dict]): - The request object. Request message for - [BatchJobService.AddBatchJobOperations][google.ads.googleads.v19.services.BatchJobService.AddBatchJobOperations]. - resource_name (str): - Required. The resource name of the - batch job. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - sequence_token (str): - A token used to enforce sequencing. - - The first AddBatchJobOperations request for a batch job - should not set sequence_token. Subsequent requests must - set sequence_token to the value of next_sequence_token - received in the previous AddBatchJobOperations response. - - This corresponds to the ``sequence_token`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - mutate_operations (MutableSequence[google.ads.googleads.v19.services.types.MutateOperation]): - Required. The list of mutates being - added. - Operations can use negative integers as - temp ids to signify dependencies between - entities created in this batch job. For - example, a customer with id = 1234 can - create a campaign and an ad group in - that same campaign by creating a - campaign in the first operation with the - resource name explicitly set to - "customers/1234/campaigns/-1", and - creating an ad group in the second - operation with the campaign field also - set to "customers/1234/campaigns/-1". - - This corresponds to the ``mutate_operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.AddBatchJobOperationsResponse: - Response message for - [BatchJobService.AddBatchJobOperations][google.ads.googleads.v19.services.BatchJobService.AddBatchJobOperations]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name, sequence_token, mutate_operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, batch_job_service.AddBatchJobOperationsRequest - ): - request = batch_job_service.AddBatchJobOperationsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - if sequence_token is not None: - request.sequence_token = sequence_token - if mutate_operations is not None: - request.mutate_operations = mutate_operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.add_batch_job_operations - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "BatchJobServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("BatchJobServiceClient",) diff --git a/google/ads/googleads/v19/services/services/batch_job_service/pagers.py b/google/ads/googleads/v19/services/services/batch_job_service/pagers.py deleted file mode 100644 index 38f22b3da..000000000 --- a/google/ads/googleads/v19/services/services/batch_job_service/pagers.py +++ /dev/null @@ -1,199 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import retry_async as retries_async -from typing import ( - Any, - AsyncIterator, - Awaitable, - Callable, - Sequence, - Tuple, - Iterator, - Union, -) - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] - OptionalAsyncRetry = Union[ - retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import batch_job_service - - -class ListBatchJobResultsPager: - """A pager for iterating through ``list_batch_job_results`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.ListBatchJobResultsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``results`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListBatchJobResults`` requests and continue to iterate - through the ``results`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.ListBatchJobResultsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[..., batch_job_service.ListBatchJobResultsResponse], - request: batch_job_service.ListBatchJobResultsRequest, - response: batch_job_service.ListBatchJobResultsResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.ListBatchJobResultsRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.ListBatchJobResultsResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = batch_job_service.ListBatchJobResultsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[batch_job_service.ListBatchJobResultsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __iter__(self) -> Iterator[batch_job_service.BatchJobResult]: - for page in self.pages: - yield from page.results - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) - - -class ListBatchJobResultsAsyncPager: - """A pager for iterating through ``list_batch_job_results`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.ListBatchJobResultsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``results`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListBatchJobResults`` requests and continue to iterate - through the ``results`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.ListBatchJobResultsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[ - ..., Awaitable[batch_job_service.ListBatchJobResultsResponse] - ], - request: batch_job_service.ListBatchJobResultsRequest, - response: batch_job_service.ListBatchJobResultsResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.ListBatchJobResultsRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.ListBatchJobResultsResponse): - The initial response object. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = batch_job_service.ListBatchJobResultsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages( - self, - ) -> AsyncIterator[batch_job_service.ListBatchJobResultsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __aiter__(self) -> AsyncIterator[batch_job_service.BatchJobResult]: - async def async_generator(): - async for page in self.pages: - for response in page.results: - yield response - - return async_generator() - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/batch_job_service/transports/base.py b/google/ads/googleads/v19/services/services/batch_job_service/transports/base.py deleted file mode 100644 index 4a0763416..000000000 --- a/google/ads/googleads/v19/services/services/batch_job_service/transports/base.py +++ /dev/null @@ -1,226 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import batch_job_service -from google.longrunning import operations_pb2 # type: ignore - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class BatchJobServiceTransport(abc.ABC): - """Abstract transport class for BatchJobService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_batch_job: gapic_v1.method.wrap_method( - self.mutate_batch_job, - default_timeout=None, - client_info=client_info, - ), - self.list_batch_job_results: gapic_v1.method.wrap_method( - self.list_batch_job_results, - default_timeout=None, - client_info=client_info, - ), - self.run_batch_job: gapic_v1.method.wrap_method( - self.run_batch_job, - default_timeout=None, - client_info=client_info, - ), - self.add_batch_job_operations: gapic_v1.method.wrap_method( - self.add_batch_job_operations, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def operations_client(self): - """Return the client designed to process long-running operations.""" - raise NotImplementedError() - - @property - def mutate_batch_job( - self, - ) -> Callable[ - [batch_job_service.MutateBatchJobRequest], - Union[ - batch_job_service.MutateBatchJobResponse, - Awaitable[batch_job_service.MutateBatchJobResponse], - ], - ]: - raise NotImplementedError() - - @property - def list_batch_job_results( - self, - ) -> Callable[ - [batch_job_service.ListBatchJobResultsRequest], - Union[ - batch_job_service.ListBatchJobResultsResponse, - Awaitable[batch_job_service.ListBatchJobResultsResponse], - ], - ]: - raise NotImplementedError() - - @property - def run_batch_job( - self, - ) -> Callable[ - [batch_job_service.RunBatchJobRequest], - Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], - ]: - raise NotImplementedError() - - @property - def add_batch_job_operations( - self, - ) -> Callable[ - [batch_job_service.AddBatchJobOperationsRequest], - Union[ - batch_job_service.AddBatchJobOperationsResponse, - Awaitable[batch_job_service.AddBatchJobOperationsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("BatchJobServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/batch_job_service/transports/grpc.py b/google/ads/googleads/v19/services/services/batch_job_service/transports/grpc.py deleted file mode 100644 index 8502db6d5..000000000 --- a/google/ads/googleads/v19/services/services/batch_job_service/transports/grpc.py +++ /dev/null @@ -1,514 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import operations_v1 -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import batch_job_service -from google.longrunning import operations_pb2 # type: ignore -from .base import BatchJobServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.BatchJobService", - "rpcName": str(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.ads.googleads.v19.services.BatchJobService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BatchJobServiceGrpcTransport(BatchJobServiceTransport): - """gRPC backend transport for BatchJobService. - - Service to manage batch jobs. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[operations_v1.OperationsClient] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # 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._logged_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def mutate_batch_job( - self, - ) -> Callable[ - [batch_job_service.MutateBatchJobRequest], - batch_job_service.MutateBatchJobResponse, - ]: - r"""Return a callable for the mutate batch job method over gRPC. - - Mutates a batch job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.MutateBatchJobRequest], - ~.MutateBatchJobResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_batch_job" not in self._stubs: - self._stubs["mutate_batch_job"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BatchJobService/MutateBatchJob", - request_serializer=batch_job_service.MutateBatchJobRequest.serialize, - response_deserializer=batch_job_service.MutateBatchJobResponse.deserialize, - ) - return self._stubs["mutate_batch_job"] - - @property - def list_batch_job_results( - self, - ) -> Callable[ - [batch_job_service.ListBatchJobResultsRequest], - batch_job_service.ListBatchJobResultsResponse, - ]: - r"""Return a callable for the list batch job results method over gRPC. - - Returns the results of the batch job. The job must be done. - Supports standard list paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.ListBatchJobResultsRequest], - ~.ListBatchJobResultsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_batch_job_results" not in self._stubs: - self._stubs["list_batch_job_results"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BatchJobService/ListBatchJobResults", - request_serializer=batch_job_service.ListBatchJobResultsRequest.serialize, - response_deserializer=batch_job_service.ListBatchJobResultsResponse.deserialize, - ) - ) - return self._stubs["list_batch_job_results"] - - @property - def run_batch_job( - self, - ) -> Callable[ - [batch_job_service.RunBatchJobRequest], operations_pb2.Operation - ]: - r"""Return a callable for the run batch job method over gRPC. - - Runs the batch job. - - The Operation.metadata field type is BatchJobMetadata. When - finished, the long running operation will not contain errors or - a response. Instead, use ListBatchJobResults to get the results - of the job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.RunBatchJobRequest], - ~.Operation]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "run_batch_job" not in self._stubs: - self._stubs["run_batch_job"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BatchJobService/RunBatchJob", - request_serializer=batch_job_service.RunBatchJobRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["run_batch_job"] - - @property - def add_batch_job_operations( - self, - ) -> Callable[ - [batch_job_service.AddBatchJobOperationsRequest], - batch_job_service.AddBatchJobOperationsResponse, - ]: - r"""Return a callable for the add batch job operations method over gRPC. - - Add operations to the batch job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.AddBatchJobOperationsRequest], - ~.AddBatchJobOperationsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "add_batch_job_operations" not in self._stubs: - self._stubs["add_batch_job_operations"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BatchJobService/AddBatchJobOperations", - request_serializer=batch_job_service.AddBatchJobOperationsRequest.serialize, - response_deserializer=batch_job_service.AddBatchJobOperationsResponse.deserialize, - ) - ) - return self._stubs["add_batch_job_operations"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("BatchJobServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/batch_job_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/batch_job_service/transports/grpc_asyncio.py deleted file mode 100644 index ac6940925..000000000 --- a/google/ads/googleads/v19/services/services/batch_job_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,553 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.api_core import operations_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import batch_job_service -from google.longrunning import operations_pb2 # type: ignore -from .base import BatchJobServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.BatchJobService", - "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.ads.googleads.v19.services.BatchJobService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BatchJobServiceGrpcAsyncIOTransport(BatchJobServiceTransport): - """gRPC AsyncIO backend transport for BatchJobService. - - Service to manage batch jobs. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[ - operations_v1.OperationsAsyncClient - ] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsAsyncClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # 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._logged_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def mutate_batch_job( - self, - ) -> Callable[ - [batch_job_service.MutateBatchJobRequest], - Awaitable[batch_job_service.MutateBatchJobResponse], - ]: - r"""Return a callable for the mutate batch job method over gRPC. - - Mutates a batch job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.MutateBatchJobRequest], - Awaitable[~.MutateBatchJobResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_batch_job" not in self._stubs: - self._stubs["mutate_batch_job"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BatchJobService/MutateBatchJob", - request_serializer=batch_job_service.MutateBatchJobRequest.serialize, - response_deserializer=batch_job_service.MutateBatchJobResponse.deserialize, - ) - return self._stubs["mutate_batch_job"] - - @property - def list_batch_job_results( - self, - ) -> Callable[ - [batch_job_service.ListBatchJobResultsRequest], - Awaitable[batch_job_service.ListBatchJobResultsResponse], - ]: - r"""Return a callable for the list batch job results method over gRPC. - - Returns the results of the batch job. The job must be done. - Supports standard list paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.ListBatchJobResultsRequest], - Awaitable[~.ListBatchJobResultsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_batch_job_results" not in self._stubs: - self._stubs["list_batch_job_results"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BatchJobService/ListBatchJobResults", - request_serializer=batch_job_service.ListBatchJobResultsRequest.serialize, - response_deserializer=batch_job_service.ListBatchJobResultsResponse.deserialize, - ) - ) - return self._stubs["list_batch_job_results"] - - @property - def run_batch_job( - self, - ) -> Callable[ - [batch_job_service.RunBatchJobRequest], - Awaitable[operations_pb2.Operation], - ]: - r"""Return a callable for the run batch job method over gRPC. - - Runs the batch job. - - The Operation.metadata field type is BatchJobMetadata. When - finished, the long running operation will not contain errors or - a response. Instead, use ListBatchJobResults to get the results - of the job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.RunBatchJobRequest], - Awaitable[~.Operation]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "run_batch_job" not in self._stubs: - self._stubs["run_batch_job"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BatchJobService/RunBatchJob", - request_serializer=batch_job_service.RunBatchJobRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - return self._stubs["run_batch_job"] - - @property - def add_batch_job_operations( - self, - ) -> Callable[ - [batch_job_service.AddBatchJobOperationsRequest], - Awaitable[batch_job_service.AddBatchJobOperationsResponse], - ]: - r"""Return a callable for the add batch job operations method over gRPC. - - Add operations to the batch job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BatchJobError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.AddBatchJobOperationsRequest], - Awaitable[~.AddBatchJobOperationsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "add_batch_job_operations" not in self._stubs: - self._stubs["add_batch_job_operations"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BatchJobService/AddBatchJobOperations", - request_serializer=batch_job_service.AddBatchJobOperationsRequest.serialize, - response_deserializer=batch_job_service.AddBatchJobOperationsResponse.deserialize, - ) - ) - return self._stubs["add_batch_job_operations"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_batch_job: self._wrap_method( - self.mutate_batch_job, - default_timeout=None, - client_info=client_info, - ), - self.list_batch_job_results: self._wrap_method( - self.list_batch_job_results, - default_timeout=None, - client_info=client_info, - ), - self.run_batch_job: self._wrap_method( - self.run_batch_job, - default_timeout=None, - client_info=client_info, - ), - self.add_batch_job_operations: self._wrap_method( - self.add_batch_job_operations, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("BatchJobServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/async_client.py b/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/async_client.py deleted file mode 100644 index 477eb7a82..000000000 --- a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/async_client.py +++ /dev/null @@ -1,439 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - bidding_data_exclusion_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - BiddingDataExclusionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import BiddingDataExclusionServiceClient - -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 BiddingDataExclusionServiceAsyncClient: - """Service to manage bidding data exclusions.""" - - _client: BiddingDataExclusionServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = BiddingDataExclusionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - BiddingDataExclusionServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - BiddingDataExclusionServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = BiddingDataExclusionServiceClient._DEFAULT_UNIVERSE - - bidding_data_exclusion_path = staticmethod( - BiddingDataExclusionServiceClient.bidding_data_exclusion_path - ) - parse_bidding_data_exclusion_path = staticmethod( - BiddingDataExclusionServiceClient.parse_bidding_data_exclusion_path - ) - campaign_path = staticmethod( - BiddingDataExclusionServiceClient.campaign_path - ) - parse_campaign_path = staticmethod( - BiddingDataExclusionServiceClient.parse_campaign_path - ) - common_billing_account_path = staticmethod( - BiddingDataExclusionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - BiddingDataExclusionServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - BiddingDataExclusionServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - BiddingDataExclusionServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - BiddingDataExclusionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - BiddingDataExclusionServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - BiddingDataExclusionServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - BiddingDataExclusionServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - BiddingDataExclusionServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - BiddingDataExclusionServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingDataExclusionServiceAsyncClient: The constructed client. - """ - return BiddingDataExclusionServiceClient.from_service_account_info.__func__(BiddingDataExclusionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingDataExclusionServiceAsyncClient: The constructed client. - """ - return BiddingDataExclusionServiceClient.from_service_account_file.__func__(BiddingDataExclusionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return BiddingDataExclusionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> BiddingDataExclusionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BiddingDataExclusionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = BiddingDataExclusionServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BiddingDataExclusionServiceTransport, - Callable[..., BiddingDataExclusionServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the bidding data exclusion service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BiddingDataExclusionServiceTransport,Callable[..., BiddingDataExclusionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BiddingDataExclusionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = BiddingDataExclusionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.BiddingDataExclusionServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BiddingDataExclusionService", - "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.ads.googleads.v19.services.BiddingDataExclusionService", - "credentialsType": None, - } - ), - ) - - async def mutate_bidding_data_exclusions( - self, - request: Optional[ - Union[ - bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - bidding_data_exclusion_service.BiddingDataExclusionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse: - r"""Creates, updates, or removes data exclusions. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateBiddingDataExclusionsRequest, dict]]): - The request object. Request message for - [BiddingDataExclusionService.MutateBiddingDataExclusions][google.ads.googleads.v19.services.BiddingDataExclusionService.MutateBiddingDataExclusions]. - customer_id (:class:`str`): - Required. ID of the customer whose - data exclusions are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.BiddingDataExclusionOperation]`): - Required. The list of operations to - perform on individual data exclusions. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateBiddingDataExclusionsResponse: - Response message for data exclusions - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest, - ): - request = bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_bidding_data_exclusions - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "BiddingDataExclusionServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("BiddingDataExclusionServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/client.py b/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/client.py deleted file mode 100644 index 915bb55d3..000000000 --- a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/client.py +++ /dev/null @@ -1,916 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - bidding_data_exclusion_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - BiddingDataExclusionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import BiddingDataExclusionServiceGrpcTransport -from .transports.grpc_asyncio import ( - BiddingDataExclusionServiceGrpcAsyncIOTransport, -) - - -class BiddingDataExclusionServiceClientMeta(type): - """Metaclass for the BiddingDataExclusionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[BiddingDataExclusionServiceTransport]] - _transport_registry["grpc"] = BiddingDataExclusionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - BiddingDataExclusionServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[BiddingDataExclusionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class BiddingDataExclusionServiceClient( - metaclass=BiddingDataExclusionServiceClientMeta -): - """Service to manage bidding data exclusions.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingDataExclusionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingDataExclusionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> BiddingDataExclusionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BiddingDataExclusionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def bidding_data_exclusion_path( - customer_id: str, - seasonality_event_id: str, - ) -> str: - """Returns a fully-qualified bidding_data_exclusion string.""" - return "customers/{customer_id}/biddingDataExclusions/{seasonality_event_id}".format( - customer_id=customer_id, - seasonality_event_id=seasonality_event_id, - ) - - @staticmethod - def parse_bidding_data_exclusion_path(path: str) -> Dict[str, str]: - """Parses a bidding_data_exclusion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/biddingDataExclusions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - BiddingDataExclusionServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - BiddingDataExclusionServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = BiddingDataExclusionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = BiddingDataExclusionServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BiddingDataExclusionServiceTransport, - Callable[..., BiddingDataExclusionServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the bidding data exclusion service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BiddingDataExclusionServiceTransport,Callable[..., BiddingDataExclusionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BiddingDataExclusionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = BiddingDataExclusionServiceClient._read_environment_variables() - self._client_cert_source = ( - BiddingDataExclusionServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - BiddingDataExclusionServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, BiddingDataExclusionServiceTransport - ) - if transport_provided: - # transport is a BiddingDataExclusionServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - BiddingDataExclusionServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or BiddingDataExclusionServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[BiddingDataExclusionServiceTransport], - Callable[..., BiddingDataExclusionServiceTransport], - ] = ( - BiddingDataExclusionServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., BiddingDataExclusionServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.BiddingDataExclusionServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BiddingDataExclusionService", - "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.ads.googleads.v19.services.BiddingDataExclusionService", - "credentialsType": None, - } - ), - ) - - def mutate_bidding_data_exclusions( - self, - request: Optional[ - Union[ - bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - bidding_data_exclusion_service.BiddingDataExclusionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse: - r"""Creates, updates, or removes data exclusions. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateBiddingDataExclusionsRequest, dict]): - The request object. Request message for - [BiddingDataExclusionService.MutateBiddingDataExclusions][google.ads.googleads.v19.services.BiddingDataExclusionService.MutateBiddingDataExclusions]. - customer_id (str): - Required. ID of the customer whose - data exclusions are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.BiddingDataExclusionOperation]): - Required. The list of operations to - perform on individual data exclusions. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateBiddingDataExclusionsResponse: - Response message for data exclusions - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest, - ): - request = bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_bidding_data_exclusions - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "BiddingDataExclusionServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("BiddingDataExclusionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/base.py b/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/base.py deleted file mode 100644 index 620b89860..000000000 --- a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - bidding_data_exclusion_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class BiddingDataExclusionServiceTransport(abc.ABC): - """Abstract transport class for BiddingDataExclusionService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_bidding_data_exclusions: gapic_v1.method.wrap_method( - self.mutate_bidding_data_exclusions, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_bidding_data_exclusions( - self, - ) -> Callable[ - [bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest], - Union[ - bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse, - Awaitable[ - bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("BiddingDataExclusionServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/grpc.py b/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/grpc.py deleted file mode 100644 index 6c5cf9970..000000000 --- a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/grpc.py +++ /dev/null @@ -1,386 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - bidding_data_exclusion_service, -) -from .base import BiddingDataExclusionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.BiddingDataExclusionService", - "rpcName": str(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.ads.googleads.v19.services.BiddingDataExclusionService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BiddingDataExclusionServiceGrpcTransport( - BiddingDataExclusionServiceTransport -): - """gRPC backend transport for BiddingDataExclusionService. - - Service to manage bidding data exclusions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_bidding_data_exclusions( - self, - ) -> Callable[ - [bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest], - bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse, - ]: - r"""Return a callable for the mutate bidding data exclusions method over gRPC. - - Creates, updates, or removes data exclusions. - Operation statuses are returned. - - Returns: - Callable[[~.MutateBiddingDataExclusionsRequest], - ~.MutateBiddingDataExclusionsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_bidding_data_exclusions" not in self._stubs: - self._stubs["mutate_bidding_data_exclusions"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BiddingDataExclusionService/MutateBiddingDataExclusions", - request_serializer=bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest.serialize, - response_deserializer=bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse.deserialize, - ) - ) - return self._stubs["mutate_bidding_data_exclusions"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("BiddingDataExclusionServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/grpc_asyncio.py deleted file mode 100644 index 9e9e339ee..000000000 --- a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - bidding_data_exclusion_service, -) -from .base import BiddingDataExclusionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.BiddingDataExclusionService", - "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.ads.googleads.v19.services.BiddingDataExclusionService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BiddingDataExclusionServiceGrpcAsyncIOTransport( - BiddingDataExclusionServiceTransport -): - """gRPC AsyncIO backend transport for BiddingDataExclusionService. - - Service to manage bidding data exclusions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_bidding_data_exclusions( - self, - ) -> Callable[ - [bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest], - Awaitable[ - bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse - ], - ]: - r"""Return a callable for the mutate bidding data exclusions method over gRPC. - - Creates, updates, or removes data exclusions. - Operation statuses are returned. - - Returns: - Callable[[~.MutateBiddingDataExclusionsRequest], - Awaitable[~.MutateBiddingDataExclusionsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_bidding_data_exclusions" not in self._stubs: - self._stubs["mutate_bidding_data_exclusions"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BiddingDataExclusionService/MutateBiddingDataExclusions", - request_serializer=bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest.serialize, - response_deserializer=bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse.deserialize, - ) - ) - return self._stubs["mutate_bidding_data_exclusions"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_bidding_data_exclusions: self._wrap_method( - self.mutate_bidding_data_exclusions, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("BiddingDataExclusionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/async_client.py b/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/async_client.py deleted file mode 100644 index 333305531..000000000 --- a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/async_client.py +++ /dev/null @@ -1,451 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - bidding_seasonality_adjustment_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - BiddingSeasonalityAdjustmentServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import BiddingSeasonalityAdjustmentServiceClient - -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 BiddingSeasonalityAdjustmentServiceAsyncClient: - """Service to manage bidding seasonality adjustments.""" - - _client: BiddingSeasonalityAdjustmentServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ( - BiddingSeasonalityAdjustmentServiceClient.DEFAULT_ENDPOINT - ) - DEFAULT_MTLS_ENDPOINT = ( - BiddingSeasonalityAdjustmentServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - BiddingSeasonalityAdjustmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ( - BiddingSeasonalityAdjustmentServiceClient._DEFAULT_UNIVERSE - ) - - bidding_seasonality_adjustment_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.bidding_seasonality_adjustment_path - ) - parse_bidding_seasonality_adjustment_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.parse_bidding_seasonality_adjustment_path - ) - campaign_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.campaign_path - ) - parse_campaign_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.parse_campaign_path - ) - common_billing_account_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - BiddingSeasonalityAdjustmentServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingSeasonalityAdjustmentServiceAsyncClient: The constructed client. - """ - return BiddingSeasonalityAdjustmentServiceClient.from_service_account_info.__func__(BiddingSeasonalityAdjustmentServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingSeasonalityAdjustmentServiceAsyncClient: The constructed client. - """ - return BiddingSeasonalityAdjustmentServiceClient.from_service_account_file.__func__(BiddingSeasonalityAdjustmentServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return BiddingSeasonalityAdjustmentServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> BiddingSeasonalityAdjustmentServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BiddingSeasonalityAdjustmentServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - BiddingSeasonalityAdjustmentServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BiddingSeasonalityAdjustmentServiceTransport, - Callable[..., BiddingSeasonalityAdjustmentServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the bidding seasonality adjustment service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BiddingSeasonalityAdjustmentServiceTransport,Callable[..., BiddingSeasonalityAdjustmentServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BiddingSeasonalityAdjustmentServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = BiddingSeasonalityAdjustmentServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.BiddingSeasonalityAdjustmentServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService", - "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.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService", - "credentialsType": None, - } - ), - ) - - async def mutate_bidding_seasonality_adjustments( - self, - request: Optional[ - Union[ - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - bidding_seasonality_adjustment_service.BiddingSeasonalityAdjustmentOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse - ): - r"""Creates, updates, or removes seasonality adjustments. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateBiddingSeasonalityAdjustmentsRequest, dict]]): - The request object. Request message for - [BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments][google.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments]. - customer_id (:class:`str`): - Required. ID of the customer whose - seasonality adjustments are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.BiddingSeasonalityAdjustmentOperation]`): - Required. The list of operations to - perform on individual seasonality - adjustments. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateBiddingSeasonalityAdjustmentsResponse: - Response message for seasonality - adjustments mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest, - ): - request = bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_bidding_seasonality_adjustments - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__( - self, - ) -> "BiddingSeasonalityAdjustmentServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("BiddingSeasonalityAdjustmentServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/client.py b/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/client.py deleted file mode 100644 index 391c9bab0..000000000 --- a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/client.py +++ /dev/null @@ -1,928 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - bidding_seasonality_adjustment_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - BiddingSeasonalityAdjustmentServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import BiddingSeasonalityAdjustmentServiceGrpcTransport -from .transports.grpc_asyncio import ( - BiddingSeasonalityAdjustmentServiceGrpcAsyncIOTransport, -) - - -class BiddingSeasonalityAdjustmentServiceClientMeta(type): - """Metaclass for the BiddingSeasonalityAdjustmentService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[BiddingSeasonalityAdjustmentServiceTransport]] - _transport_registry["grpc"] = ( - BiddingSeasonalityAdjustmentServiceGrpcTransport - ) - _transport_registry["grpc_asyncio"] = ( - BiddingSeasonalityAdjustmentServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[BiddingSeasonalityAdjustmentServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class BiddingSeasonalityAdjustmentServiceClient( - metaclass=BiddingSeasonalityAdjustmentServiceClientMeta -): - """Service to manage bidding seasonality adjustments.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingSeasonalityAdjustmentServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingSeasonalityAdjustmentServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> BiddingSeasonalityAdjustmentServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BiddingSeasonalityAdjustmentServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def bidding_seasonality_adjustment_path( - customer_id: str, - seasonality_event_id: str, - ) -> str: - """Returns a fully-qualified bidding_seasonality_adjustment string.""" - return "customers/{customer_id}/biddingSeasonalityAdjustments/{seasonality_event_id}".format( - customer_id=customer_id, - seasonality_event_id=seasonality_event_id, - ) - - @staticmethod - def parse_bidding_seasonality_adjustment_path(path: str) -> Dict[str, str]: - """Parses a bidding_seasonality_adjustment path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/biddingSeasonalityAdjustments/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - BiddingSeasonalityAdjustmentServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - BiddingSeasonalityAdjustmentServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = BiddingSeasonalityAdjustmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - BiddingSeasonalityAdjustmentServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BiddingSeasonalityAdjustmentServiceTransport, - Callable[..., BiddingSeasonalityAdjustmentServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the bidding seasonality adjustment service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BiddingSeasonalityAdjustmentServiceTransport,Callable[..., BiddingSeasonalityAdjustmentServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BiddingSeasonalityAdjustmentServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ( - BiddingSeasonalityAdjustmentServiceClient._read_environment_variables() - ) - self._client_cert_source = ( - BiddingSeasonalityAdjustmentServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - BiddingSeasonalityAdjustmentServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, BiddingSeasonalityAdjustmentServiceTransport - ) - if transport_provided: - # transport is a BiddingSeasonalityAdjustmentServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - BiddingSeasonalityAdjustmentServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or BiddingSeasonalityAdjustmentServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[BiddingSeasonalityAdjustmentServiceTransport], - Callable[..., BiddingSeasonalityAdjustmentServiceTransport], - ] = ( - BiddingSeasonalityAdjustmentServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., BiddingSeasonalityAdjustmentServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.BiddingSeasonalityAdjustmentServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService", - "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.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService", - "credentialsType": None, - } - ), - ) - - def mutate_bidding_seasonality_adjustments( - self, - request: Optional[ - Union[ - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - bidding_seasonality_adjustment_service.BiddingSeasonalityAdjustmentOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse - ): - r"""Creates, updates, or removes seasonality adjustments. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateBiddingSeasonalityAdjustmentsRequest, dict]): - The request object. Request message for - [BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments][google.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments]. - customer_id (str): - Required. ID of the customer whose - seasonality adjustments are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.BiddingSeasonalityAdjustmentOperation]): - Required. The list of operations to - perform on individual seasonality - adjustments. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateBiddingSeasonalityAdjustmentsResponse: - Response message for seasonality - adjustments mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest, - ): - request = bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_bidding_seasonality_adjustments - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "BiddingSeasonalityAdjustmentServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("BiddingSeasonalityAdjustmentServiceClient",) diff --git a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/base.py b/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/base.py deleted file mode 100644 index d1bb1bd8d..000000000 --- a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - bidding_seasonality_adjustment_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class BiddingSeasonalityAdjustmentServiceTransport(abc.ABC): - """Abstract transport class for BiddingSeasonalityAdjustmentService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_bidding_seasonality_adjustments: gapic_v1.method.wrap_method( - self.mutate_bidding_seasonality_adjustments, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_bidding_seasonality_adjustments( - self, - ) -> Callable[ - [ - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest - ], - Union[ - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse, - Awaitable[ - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("BiddingSeasonalityAdjustmentServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/grpc.py b/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/grpc.py deleted file mode 100644 index bac091ffa..000000000 --- a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/grpc.py +++ /dev/null @@ -1,392 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - bidding_seasonality_adjustment_service, -) -from .base import ( - BiddingSeasonalityAdjustmentServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService", - "rpcName": str(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.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BiddingSeasonalityAdjustmentServiceGrpcTransport( - BiddingSeasonalityAdjustmentServiceTransport -): - """gRPC backend transport for BiddingSeasonalityAdjustmentService. - - Service to manage bidding seasonality adjustments. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_bidding_seasonality_adjustments( - self, - ) -> Callable[ - [ - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest - ], - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse, - ]: - r"""Return a callable for the mutate bidding seasonality - adjustments method over gRPC. - - Creates, updates, or removes seasonality adjustments. - Operation statuses are returned. - - Returns: - Callable[[~.MutateBiddingSeasonalityAdjustmentsRequest], - ~.MutateBiddingSeasonalityAdjustmentsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_bidding_seasonality_adjustments" not in self._stubs: - self._stubs["mutate_bidding_seasonality_adjustments"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService/MutateBiddingSeasonalityAdjustments", - request_serializer=bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest.serialize, - response_deserializer=bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse.deserialize, - ) - ) - return self._stubs["mutate_bidding_seasonality_adjustments"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("BiddingSeasonalityAdjustmentServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/grpc_asyncio.py deleted file mode 100644 index bc4327c69..000000000 --- a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,415 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - bidding_seasonality_adjustment_service, -) -from .base import ( - BiddingSeasonalityAdjustmentServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService", - "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.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BiddingSeasonalityAdjustmentServiceGrpcAsyncIOTransport( - BiddingSeasonalityAdjustmentServiceTransport -): - """gRPC AsyncIO backend transport for BiddingSeasonalityAdjustmentService. - - Service to manage bidding seasonality adjustments. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_bidding_seasonality_adjustments( - self, - ) -> Callable[ - [ - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest - ], - Awaitable[ - bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse - ], - ]: - r"""Return a callable for the mutate bidding seasonality - adjustments method over gRPC. - - Creates, updates, or removes seasonality adjustments. - Operation statuses are returned. - - Returns: - Callable[[~.MutateBiddingSeasonalityAdjustmentsRequest], - Awaitable[~.MutateBiddingSeasonalityAdjustmentsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_bidding_seasonality_adjustments" not in self._stubs: - self._stubs["mutate_bidding_seasonality_adjustments"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService/MutateBiddingSeasonalityAdjustments", - request_serializer=bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest.serialize, - response_deserializer=bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse.deserialize, - ) - ) - return self._stubs["mutate_bidding_seasonality_adjustments"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_bidding_seasonality_adjustments: self._wrap_method( - self.mutate_bidding_seasonality_adjustments, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("BiddingSeasonalityAdjustmentServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_strategy_service/async_client.py b/google/ads/googleads/v19/services/services/bidding_strategy_service/async_client.py deleted file mode 100644 index 4a11e3aec..000000000 --- a/google/ads/googleads/v19/services/services/bidding_strategy_service/async_client.py +++ /dev/null @@ -1,438 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import bidding_strategy_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - BiddingStrategyServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import BiddingStrategyServiceClient - -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 BiddingStrategyServiceAsyncClient: - """Service to manage bidding strategies.""" - - _client: BiddingStrategyServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = BiddingStrategyServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = BiddingStrategyServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - BiddingStrategyServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = BiddingStrategyServiceClient._DEFAULT_UNIVERSE - - bidding_strategy_path = staticmethod( - BiddingStrategyServiceClient.bidding_strategy_path - ) - parse_bidding_strategy_path = staticmethod( - BiddingStrategyServiceClient.parse_bidding_strategy_path - ) - common_billing_account_path = staticmethod( - BiddingStrategyServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - BiddingStrategyServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - BiddingStrategyServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - BiddingStrategyServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - BiddingStrategyServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - BiddingStrategyServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - BiddingStrategyServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - BiddingStrategyServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - BiddingStrategyServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - BiddingStrategyServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingStrategyServiceAsyncClient: The constructed client. - """ - return BiddingStrategyServiceClient.from_service_account_info.__func__(BiddingStrategyServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingStrategyServiceAsyncClient: The constructed client. - """ - return BiddingStrategyServiceClient.from_service_account_file.__func__(BiddingStrategyServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return BiddingStrategyServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> BiddingStrategyServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BiddingStrategyServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = BiddingStrategyServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BiddingStrategyServiceTransport, - Callable[..., BiddingStrategyServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the bidding strategy service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BiddingStrategyServiceTransport,Callable[..., BiddingStrategyServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BiddingStrategyServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = BiddingStrategyServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.BiddingStrategyServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BiddingStrategyService", - "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.ads.googleads.v19.services.BiddingStrategyService", - "credentialsType": None, - } - ), - ) - - async def mutate_bidding_strategies( - self, - request: Optional[ - Union[bidding_strategy_service.MutateBiddingStrategiesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[bidding_strategy_service.BiddingStrategyOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> bidding_strategy_service.MutateBiddingStrategiesResponse: - r"""Creates, updates, or removes bidding strategies. Operation - statuses are returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateBiddingStrategiesRequest, dict]]): - The request object. Request message for - [BiddingStrategyService.MutateBiddingStrategies][google.ads.googleads.v19.services.BiddingStrategyService.MutateBiddingStrategies]. - customer_id (:class:`str`): - Required. The ID of the customer - whose bidding strategies are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.BiddingStrategyOperation]`): - Required. The list of operations to - perform on individual bidding - strategies. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateBiddingStrategiesResponse: - Response message for bidding strategy - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, bidding_strategy_service.MutateBiddingStrategiesRequest - ): - request = bidding_strategy_service.MutateBiddingStrategiesRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_bidding_strategies - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "BiddingStrategyServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("BiddingStrategyServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/bidding_strategy_service/client.py b/google/ads/googleads/v19/services/services/bidding_strategy_service/client.py deleted file mode 100644 index 4f51a8db4..000000000 --- a/google/ads/googleads/v19/services/services/bidding_strategy_service/client.py +++ /dev/null @@ -1,894 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import bidding_strategy_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - BiddingStrategyServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import BiddingStrategyServiceGrpcTransport -from .transports.grpc_asyncio import BiddingStrategyServiceGrpcAsyncIOTransport - - -class BiddingStrategyServiceClientMeta(type): - """Metaclass for the BiddingStrategyService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[BiddingStrategyServiceTransport]] - _transport_registry["grpc"] = BiddingStrategyServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - BiddingStrategyServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[BiddingStrategyServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class BiddingStrategyServiceClient(metaclass=BiddingStrategyServiceClientMeta): - """Service to manage bidding strategies.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingStrategyServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BiddingStrategyServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> BiddingStrategyServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BiddingStrategyServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def bidding_strategy_path( - customer_id: str, - bidding_strategy_id: str, - ) -> str: - """Returns a fully-qualified bidding_strategy string.""" - return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( - customer_id=customer_id, - bidding_strategy_id=bidding_strategy_id, - ) - - @staticmethod - def parse_bidding_strategy_path(path: str) -> Dict[str, str]: - """Parses a bidding_strategy path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = BiddingStrategyServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = BiddingStrategyServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - BiddingStrategyServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = BiddingStrategyServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BiddingStrategyServiceTransport, - Callable[..., BiddingStrategyServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the bidding strategy service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BiddingStrategyServiceTransport,Callable[..., BiddingStrategyServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BiddingStrategyServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = BiddingStrategyServiceClient._read_environment_variables() - self._client_cert_source = ( - BiddingStrategyServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - BiddingStrategyServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, BiddingStrategyServiceTransport - ) - if transport_provided: - # transport is a BiddingStrategyServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(BiddingStrategyServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or BiddingStrategyServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[BiddingStrategyServiceTransport], - Callable[..., BiddingStrategyServiceTransport], - ] = ( - BiddingStrategyServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., BiddingStrategyServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.BiddingStrategyServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BiddingStrategyService", - "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.ads.googleads.v19.services.BiddingStrategyService", - "credentialsType": None, - } - ), - ) - - def mutate_bidding_strategies( - self, - request: Optional[ - Union[bidding_strategy_service.MutateBiddingStrategiesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[bidding_strategy_service.BiddingStrategyOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> bidding_strategy_service.MutateBiddingStrategiesResponse: - r"""Creates, updates, or removes bidding strategies. Operation - statuses are returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateBiddingStrategiesRequest, dict]): - The request object. Request message for - [BiddingStrategyService.MutateBiddingStrategies][google.ads.googleads.v19.services.BiddingStrategyService.MutateBiddingStrategies]. - customer_id (str): - Required. The ID of the customer - whose bidding strategies are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.BiddingStrategyOperation]): - Required. The list of operations to - perform on individual bidding - strategies. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateBiddingStrategiesResponse: - Response message for bidding strategy - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, bidding_strategy_service.MutateBiddingStrategiesRequest - ): - request = bidding_strategy_service.MutateBiddingStrategiesRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_bidding_strategies - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "BiddingStrategyServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("BiddingStrategyServiceClient",) diff --git a/google/ads/googleads/v19/services/services/bidding_strategy_service/transports/base.py b/google/ads/googleads/v19/services/services/bidding_strategy_service/transports/base.py deleted file mode 100644 index e5fd2bc45..000000000 --- a/google/ads/googleads/v19/services/services/bidding_strategy_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import bidding_strategy_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class BiddingStrategyServiceTransport(abc.ABC): - """Abstract transport class for BiddingStrategyService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_bidding_strategies: gapic_v1.method.wrap_method( - self.mutate_bidding_strategies, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_bidding_strategies( - self, - ) -> Callable[ - [bidding_strategy_service.MutateBiddingStrategiesRequest], - Union[ - bidding_strategy_service.MutateBiddingStrategiesResponse, - Awaitable[bidding_strategy_service.MutateBiddingStrategiesResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("BiddingStrategyServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_strategy_service/transports/grpc.py b/google/ads/googleads/v19/services/services/bidding_strategy_service/transports/grpc.py deleted file mode 100644 index 600402ec9..000000000 --- a/google/ads/googleads/v19/services/services/bidding_strategy_service/transports/grpc.py +++ /dev/null @@ -1,395 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import bidding_strategy_service -from .base import BiddingStrategyServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.BiddingStrategyService", - "rpcName": str(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.ads.googleads.v19.services.BiddingStrategyService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BiddingStrategyServiceGrpcTransport(BiddingStrategyServiceTransport): - """gRPC backend transport for BiddingStrategyService. - - Service to manage bidding strategies. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_bidding_strategies( - self, - ) -> Callable[ - [bidding_strategy_service.MutateBiddingStrategiesRequest], - bidding_strategy_service.MutateBiddingStrategiesResponse, - ]: - r"""Return a callable for the mutate bidding strategies method over gRPC. - - Creates, updates, or removes bidding strategies. Operation - statuses are returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Returns: - Callable[[~.MutateBiddingStrategiesRequest], - ~.MutateBiddingStrategiesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_bidding_strategies" not in self._stubs: - self._stubs["mutate_bidding_strategies"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BiddingStrategyService/MutateBiddingStrategies", - request_serializer=bidding_strategy_service.MutateBiddingStrategiesRequest.serialize, - response_deserializer=bidding_strategy_service.MutateBiddingStrategiesResponse.deserialize, - ) - ) - return self._stubs["mutate_bidding_strategies"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("BiddingStrategyServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_strategy_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/bidding_strategy_service/transports/grpc_asyncio.py deleted file mode 100644 index e0f188a88..000000000 --- a/google/ads/googleads/v19/services/services/bidding_strategy_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,418 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import bidding_strategy_service -from .base import BiddingStrategyServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.BiddingStrategyService", - "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.ads.googleads.v19.services.BiddingStrategyService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BiddingStrategyServiceGrpcAsyncIOTransport( - BiddingStrategyServiceTransport -): - """gRPC AsyncIO backend transport for BiddingStrategyService. - - Service to manage bidding strategies. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_bidding_strategies( - self, - ) -> Callable[ - [bidding_strategy_service.MutateBiddingStrategiesRequest], - Awaitable[bidding_strategy_service.MutateBiddingStrategiesResponse], - ]: - r"""Return a callable for the mutate bidding strategies method over gRPC. - - Creates, updates, or removes bidding strategies. Operation - statuses are returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Returns: - Callable[[~.MutateBiddingStrategiesRequest], - Awaitable[~.MutateBiddingStrategiesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_bidding_strategies" not in self._stubs: - self._stubs["mutate_bidding_strategies"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BiddingStrategyService/MutateBiddingStrategies", - request_serializer=bidding_strategy_service.MutateBiddingStrategiesRequest.serialize, - response_deserializer=bidding_strategy_service.MutateBiddingStrategiesResponse.deserialize, - ) - ) - return self._stubs["mutate_bidding_strategies"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_bidding_strategies: self._wrap_method( - self.mutate_bidding_strategies, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("BiddingStrategyServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/billing_setup_service/async_client.py b/google/ads/googleads/v19/services/services/billing_setup_service/async_client.py deleted file mode 100644 index 644fad788..000000000 --- a/google/ads/googleads/v19/services/services/billing_setup_service/async_client.py +++ /dev/null @@ -1,435 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import billing_setup_service -from .transports.base import BillingSetupServiceTransport, DEFAULT_CLIENT_INFO -from .client import BillingSetupServiceClient - -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 BillingSetupServiceAsyncClient: - """A service for designating the business entity responsible for - accrued costs. - A billing setup is associated with a payments account. - Billing-related activity for all billing setups associated with - a particular payments account will appear on a single invoice - generated monthly. - - Mutates: - - The REMOVE operation cancels a pending billing setup. The CREATE - operation creates a new billing setup. - """ - - _client: BillingSetupServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = BillingSetupServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = BillingSetupServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - BillingSetupServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = BillingSetupServiceClient._DEFAULT_UNIVERSE - - billing_setup_path = staticmethod( - BillingSetupServiceClient.billing_setup_path - ) - parse_billing_setup_path = staticmethod( - BillingSetupServiceClient.parse_billing_setup_path - ) - payments_account_path = staticmethod( - BillingSetupServiceClient.payments_account_path - ) - parse_payments_account_path = staticmethod( - BillingSetupServiceClient.parse_payments_account_path - ) - common_billing_account_path = staticmethod( - BillingSetupServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - BillingSetupServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - BillingSetupServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - BillingSetupServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - BillingSetupServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - BillingSetupServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - BillingSetupServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - BillingSetupServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - BillingSetupServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - BillingSetupServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BillingSetupServiceAsyncClient: The constructed client. - """ - return BillingSetupServiceClient.from_service_account_info.__func__(BillingSetupServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BillingSetupServiceAsyncClient: The constructed client. - """ - return BillingSetupServiceClient.from_service_account_file.__func__(BillingSetupServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return BillingSetupServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> BillingSetupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BillingSetupServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = BillingSetupServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BillingSetupServiceTransport, - Callable[..., BillingSetupServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the billing setup service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BillingSetupServiceTransport,Callable[..., BillingSetupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BillingSetupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = BillingSetupServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.BillingSetupServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BillingSetupService", - "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.ads.googleads.v19.services.BillingSetupService", - "credentialsType": None, - } - ), - ) - - async def mutate_billing_setup( - self, - request: Optional[ - Union[billing_setup_service.MutateBillingSetupRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[billing_setup_service.BillingSetupOperation] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> billing_setup_service.MutateBillingSetupResponse: - r"""Creates a billing setup, or cancels an existing billing setup. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BillingSetupError <>`__ - `DateError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateBillingSetupRequest, dict]]): - The request object. Request message for billing setup - mutate operations. - customer_id (:class:`str`): - Required. Id of the customer to apply - the billing setup mutate operation to. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (:class:`google.ads.googleads.v19.services.types.BillingSetupOperation`): - Required. The operation to perform. - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateBillingSetupResponse: - Response message for a billing setup - operation. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, billing_setup_service.MutateBillingSetupRequest - ): - request = billing_setup_service.MutateBillingSetupRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_billing_setup - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "BillingSetupServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("BillingSetupServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/billing_setup_service/client.py b/google/ads/googleads/v19/services/services/billing_setup_service/client.py deleted file mode 100644 index 2e1a0cd02..000000000 --- a/google/ads/googleads/v19/services/services/billing_setup_service/client.py +++ /dev/null @@ -1,893 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import billing_setup_service -from .transports.base import BillingSetupServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import BillingSetupServiceGrpcTransport -from .transports.grpc_asyncio import BillingSetupServiceGrpcAsyncIOTransport - - -class BillingSetupServiceClientMeta(type): - """Metaclass for the BillingSetupService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[BillingSetupServiceTransport]] - _transport_registry["grpc"] = BillingSetupServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - BillingSetupServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[BillingSetupServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class BillingSetupServiceClient(metaclass=BillingSetupServiceClientMeta): - """A service for designating the business entity responsible for - accrued costs. - A billing setup is associated with a payments account. - Billing-related activity for all billing setups associated with - a particular payments account will appear on a single invoice - generated monthly. - - Mutates: - - The REMOVE operation cancels a pending billing setup. The CREATE - operation creates a new billing setup. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BillingSetupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BillingSetupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> BillingSetupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BillingSetupServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def billing_setup_path( - customer_id: str, - billing_setup_id: str, - ) -> str: - """Returns a fully-qualified billing_setup string.""" - return ( - "customers/{customer_id}/billingSetups/{billing_setup_id}".format( - customer_id=customer_id, - billing_setup_id=billing_setup_id, - ) - ) - - @staticmethod - def parse_billing_setup_path(path: str) -> Dict[str, str]: - """Parses a billing_setup path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/billingSetups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def payments_account_path( - customer_id: str, - payments_account_id: str, - ) -> str: - """Returns a fully-qualified payments_account string.""" - return "customers/{customer_id}/paymentsAccounts/{payments_account_id}".format( - customer_id=customer_id, - payments_account_id=payments_account_id, - ) - - @staticmethod - def parse_payments_account_path(path: str) -> Dict[str, str]: - """Parses a payments_account path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/paymentsAccounts/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = BillingSetupServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = BillingSetupServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - BillingSetupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = BillingSetupServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BillingSetupServiceTransport, - Callable[..., BillingSetupServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the billing setup service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BillingSetupServiceTransport,Callable[..., BillingSetupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BillingSetupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = BillingSetupServiceClient._read_environment_variables() - self._client_cert_source = ( - BillingSetupServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = BillingSetupServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, BillingSetupServiceTransport) - if transport_provided: - # transport is a BillingSetupServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(BillingSetupServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or BillingSetupServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[BillingSetupServiceTransport], - Callable[..., BillingSetupServiceTransport], - ] = ( - BillingSetupServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., BillingSetupServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.BillingSetupServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BillingSetupService", - "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.ads.googleads.v19.services.BillingSetupService", - "credentialsType": None, - } - ), - ) - - def mutate_billing_setup( - self, - request: Optional[ - Union[billing_setup_service.MutateBillingSetupRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[billing_setup_service.BillingSetupOperation] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> billing_setup_service.MutateBillingSetupResponse: - r"""Creates a billing setup, or cancels an existing billing setup. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BillingSetupError <>`__ - `DateError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateBillingSetupRequest, dict]): - The request object. Request message for billing setup - mutate operations. - customer_id (str): - Required. Id of the customer to apply - the billing setup mutate operation to. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (google.ads.googleads.v19.services.types.BillingSetupOperation): - Required. The operation to perform. - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateBillingSetupResponse: - Response message for a billing setup - operation. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, billing_setup_service.MutateBillingSetupRequest - ): - request = billing_setup_service.MutateBillingSetupRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_billing_setup - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "BillingSetupServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("BillingSetupServiceClient",) diff --git a/google/ads/googleads/v19/services/services/billing_setup_service/transports/base.py b/google/ads/googleads/v19/services/services/billing_setup_service/transports/base.py deleted file mode 100644 index 0a2459239..000000000 --- a/google/ads/googleads/v19/services/services/billing_setup_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import billing_setup_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class BillingSetupServiceTransport(abc.ABC): - """Abstract transport class for BillingSetupService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_billing_setup: gapic_v1.method.wrap_method( - self.mutate_billing_setup, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_billing_setup( - self, - ) -> Callable[ - [billing_setup_service.MutateBillingSetupRequest], - Union[ - billing_setup_service.MutateBillingSetupResponse, - Awaitable[billing_setup_service.MutateBillingSetupResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("BillingSetupServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/billing_setup_service/transports/grpc.py b/google/ads/googleads/v19/services/services/billing_setup_service/transports/grpc.py deleted file mode 100644 index e52407e81..000000000 --- a/google/ads/googleads/v19/services/services/billing_setup_service/transports/grpc.py +++ /dev/null @@ -1,397 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import billing_setup_service -from .base import BillingSetupServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.BillingSetupService", - "rpcName": str(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.ads.googleads.v19.services.BillingSetupService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BillingSetupServiceGrpcTransport(BillingSetupServiceTransport): - """gRPC backend transport for BillingSetupService. - - A service for designating the business entity responsible for - accrued costs. - A billing setup is associated with a payments account. - Billing-related activity for all billing setups associated with - a particular payments account will appear on a single invoice - generated monthly. - - Mutates: - - The REMOVE operation cancels a pending billing setup. The CREATE - operation creates a new billing setup. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_billing_setup( - self, - ) -> Callable[ - [billing_setup_service.MutateBillingSetupRequest], - billing_setup_service.MutateBillingSetupResponse, - ]: - r"""Return a callable for the mutate billing setup method over gRPC. - - Creates a billing setup, or cancels an existing billing setup. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BillingSetupError <>`__ - `DateError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateBillingSetupRequest], - ~.MutateBillingSetupResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_billing_setup" not in self._stubs: - self._stubs["mutate_billing_setup"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BillingSetupService/MutateBillingSetup", - request_serializer=billing_setup_service.MutateBillingSetupRequest.serialize, - response_deserializer=billing_setup_service.MutateBillingSetupResponse.deserialize, - ) - ) - return self._stubs["mutate_billing_setup"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("BillingSetupServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/billing_setup_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/billing_setup_service/transports/grpc_asyncio.py deleted file mode 100644 index 911c56971..000000000 --- a/google/ads/googleads/v19/services/services/billing_setup_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,418 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import billing_setup_service -from .base import BillingSetupServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.BillingSetupService", - "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.ads.googleads.v19.services.BillingSetupService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BillingSetupServiceGrpcAsyncIOTransport(BillingSetupServiceTransport): - """gRPC AsyncIO backend transport for BillingSetupService. - - A service for designating the business entity responsible for - accrued costs. - A billing setup is associated with a payments account. - Billing-related activity for all billing setups associated with - a particular payments account will appear on a single invoice - generated monthly. - - Mutates: - - The REMOVE operation cancels a pending billing setup. The CREATE - operation creates a new billing setup. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_billing_setup( - self, - ) -> Callable[ - [billing_setup_service.MutateBillingSetupRequest], - Awaitable[billing_setup_service.MutateBillingSetupResponse], - ]: - r"""Return a callable for the mutate billing setup method over gRPC. - - Creates a billing setup, or cancels an existing billing setup. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `BillingSetupError <>`__ - `DateError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateBillingSetupRequest], - Awaitable[~.MutateBillingSetupResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_billing_setup" not in self._stubs: - self._stubs["mutate_billing_setup"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BillingSetupService/MutateBillingSetup", - request_serializer=billing_setup_service.MutateBillingSetupRequest.serialize, - response_deserializer=billing_setup_service.MutateBillingSetupResponse.deserialize, - ) - ) - return self._stubs["mutate_billing_setup"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_billing_setup: self._wrap_method( - self.mutate_billing_setup, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("BillingSetupServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/brand_suggestion_service/async_client.py b/google/ads/googleads/v19/services/services/brand_suggestion_service/async_client.py deleted file mode 100644 index d70e4e0b9..000000000 --- a/google/ads/googleads/v19/services/services/brand_suggestion_service/async_client.py +++ /dev/null @@ -1,411 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import brand_suggestion_service -from .transports.base import ( - BrandSuggestionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import BrandSuggestionServiceClient - -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 BrandSuggestionServiceAsyncClient: - """This service will suggest brands based on a prefix.""" - - _client: BrandSuggestionServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = BrandSuggestionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = BrandSuggestionServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - BrandSuggestionServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = BrandSuggestionServiceClient._DEFAULT_UNIVERSE - - common_billing_account_path = staticmethod( - BrandSuggestionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - BrandSuggestionServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - BrandSuggestionServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - BrandSuggestionServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - BrandSuggestionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - BrandSuggestionServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - BrandSuggestionServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - BrandSuggestionServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - BrandSuggestionServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - BrandSuggestionServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BrandSuggestionServiceAsyncClient: The constructed client. - """ - return BrandSuggestionServiceClient.from_service_account_info.__func__(BrandSuggestionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BrandSuggestionServiceAsyncClient: The constructed client. - """ - return BrandSuggestionServiceClient.from_service_account_file.__func__(BrandSuggestionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return BrandSuggestionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> BrandSuggestionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BrandSuggestionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = BrandSuggestionServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BrandSuggestionServiceTransport, - Callable[..., BrandSuggestionServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the brand suggestion service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BrandSuggestionServiceTransport,Callable[..., BrandSuggestionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BrandSuggestionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = BrandSuggestionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.BrandSuggestionServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BrandSuggestionService", - "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.ads.googleads.v19.services.BrandSuggestionService", - "credentialsType": None, - } - ), - ) - - async def suggest_brands( - self, - request: Optional[ - Union[brand_suggestion_service.SuggestBrandsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - brand_prefix: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> brand_suggestion_service.SuggestBrandsResponse: - r"""Rpc to return a list of matching brands based on a - prefix for this customer. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.SuggestBrandsRequest, dict]]): - The request object. Request message for - [BrandSuggestionService.SuggestBrands][google.ads.googleads.v19.services.BrandSuggestionService.SuggestBrands]. - customer_id (:class:`str`): - Required. The ID of the customer onto - which to apply the brand suggestion - operation. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - brand_prefix (:class:`str`): - Required. The prefix of a brand name. - This corresponds to the ``brand_prefix`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestBrandsResponse: - Response message for - [BrandSuggestionService.SuggestBrands][google.ads.googleads.v19.services.BrandSuggestionService.SuggestBrands]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, brand_prefix] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, brand_suggestion_service.SuggestBrandsRequest - ): - request = brand_suggestion_service.SuggestBrandsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if brand_prefix is not None: - request.brand_prefix = brand_prefix - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.suggest_brands - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "BrandSuggestionServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("BrandSuggestionServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/brand_suggestion_service/client.py b/google/ads/googleads/v19/services/services/brand_suggestion_service/client.py deleted file mode 100644 index ecb493386..000000000 --- a/google/ads/googleads/v19/services/services/brand_suggestion_service/client.py +++ /dev/null @@ -1,841 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import brand_suggestion_service -from .transports.base import ( - BrandSuggestionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import BrandSuggestionServiceGrpcTransport -from .transports.grpc_asyncio import BrandSuggestionServiceGrpcAsyncIOTransport - - -class BrandSuggestionServiceClientMeta(type): - """Metaclass for the BrandSuggestionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[BrandSuggestionServiceTransport]] - _transport_registry["grpc"] = BrandSuggestionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - BrandSuggestionServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[BrandSuggestionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class BrandSuggestionServiceClient(metaclass=BrandSuggestionServiceClientMeta): - """This service will suggest brands based on a prefix.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BrandSuggestionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - BrandSuggestionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> BrandSuggestionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - BrandSuggestionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = BrandSuggestionServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = BrandSuggestionServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - BrandSuggestionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = BrandSuggestionServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - BrandSuggestionServiceTransport, - Callable[..., BrandSuggestionServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the brand suggestion service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,BrandSuggestionServiceTransport,Callable[..., BrandSuggestionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the BrandSuggestionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = BrandSuggestionServiceClient._read_environment_variables() - self._client_cert_source = ( - BrandSuggestionServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - BrandSuggestionServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, BrandSuggestionServiceTransport - ) - if transport_provided: - # transport is a BrandSuggestionServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(BrandSuggestionServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or BrandSuggestionServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[BrandSuggestionServiceTransport], - Callable[..., BrandSuggestionServiceTransport], - ] = ( - BrandSuggestionServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., BrandSuggestionServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.BrandSuggestionServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.BrandSuggestionService", - "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.ads.googleads.v19.services.BrandSuggestionService", - "credentialsType": None, - } - ), - ) - - def suggest_brands( - self, - request: Optional[ - Union[brand_suggestion_service.SuggestBrandsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - brand_prefix: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> brand_suggestion_service.SuggestBrandsResponse: - r"""Rpc to return a list of matching brands based on a - prefix for this customer. - - Args: - request (Union[google.ads.googleads.v19.services.types.SuggestBrandsRequest, dict]): - The request object. Request message for - [BrandSuggestionService.SuggestBrands][google.ads.googleads.v19.services.BrandSuggestionService.SuggestBrands]. - customer_id (str): - Required. The ID of the customer onto - which to apply the brand suggestion - operation. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - brand_prefix (str): - Required. The prefix of a brand name. - This corresponds to the ``brand_prefix`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestBrandsResponse: - Response message for - [BrandSuggestionService.SuggestBrands][google.ads.googleads.v19.services.BrandSuggestionService.SuggestBrands]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, brand_prefix] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, brand_suggestion_service.SuggestBrandsRequest - ): - request = brand_suggestion_service.SuggestBrandsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if brand_prefix is not None: - request.brand_prefix = brand_prefix - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.suggest_brands] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "BrandSuggestionServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("BrandSuggestionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/brand_suggestion_service/transports/base.py b/google/ads/googleads/v19/services/services/brand_suggestion_service/transports/base.py deleted file mode 100644 index 820dae442..000000000 --- a/google/ads/googleads/v19/services/services/brand_suggestion_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import brand_suggestion_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class BrandSuggestionServiceTransport(abc.ABC): - """Abstract transport class for BrandSuggestionService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.suggest_brands: gapic_v1.method.wrap_method( - self.suggest_brands, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def suggest_brands( - self, - ) -> Callable[ - [brand_suggestion_service.SuggestBrandsRequest], - Union[ - brand_suggestion_service.SuggestBrandsResponse, - Awaitable[brand_suggestion_service.SuggestBrandsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("BrandSuggestionServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/brand_suggestion_service/transports/grpc.py b/google/ads/googleads/v19/services/services/brand_suggestion_service/transports/grpc.py deleted file mode 100644 index b51ae7363..000000000 --- a/google/ads/googleads/v19/services/services/brand_suggestion_service/transports/grpc.py +++ /dev/null @@ -1,380 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import brand_suggestion_service -from .base import BrandSuggestionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.BrandSuggestionService", - "rpcName": str(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.ads.googleads.v19.services.BrandSuggestionService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BrandSuggestionServiceGrpcTransport(BrandSuggestionServiceTransport): - """gRPC backend transport for BrandSuggestionService. - - This service will suggest brands based on a prefix. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def suggest_brands( - self, - ) -> Callable[ - [brand_suggestion_service.SuggestBrandsRequest], - brand_suggestion_service.SuggestBrandsResponse, - ]: - r"""Return a callable for the suggest brands method over gRPC. - - Rpc to return a list of matching brands based on a - prefix for this customer. - - Returns: - Callable[[~.SuggestBrandsRequest], - ~.SuggestBrandsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_brands" not in self._stubs: - self._stubs["suggest_brands"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BrandSuggestionService/SuggestBrands", - request_serializer=brand_suggestion_service.SuggestBrandsRequest.serialize, - response_deserializer=brand_suggestion_service.SuggestBrandsResponse.deserialize, - ) - return self._stubs["suggest_brands"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("BrandSuggestionServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/brand_suggestion_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/brand_suggestion_service/transports/grpc_asyncio.py deleted file mode 100644 index 5fe0ad583..000000000 --- a/google/ads/googleads/v19/services/services/brand_suggestion_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,403 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import brand_suggestion_service -from .base import BrandSuggestionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.BrandSuggestionService", - "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.ads.googleads.v19.services.BrandSuggestionService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class BrandSuggestionServiceGrpcAsyncIOTransport( - BrandSuggestionServiceTransport -): - """gRPC AsyncIO backend transport for BrandSuggestionService. - - This service will suggest brands based on a prefix. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def suggest_brands( - self, - ) -> Callable[ - [brand_suggestion_service.SuggestBrandsRequest], - Awaitable[brand_suggestion_service.SuggestBrandsResponse], - ]: - r"""Return a callable for the suggest brands method over gRPC. - - Rpc to return a list of matching brands based on a - prefix for this customer. - - Returns: - Callable[[~.SuggestBrandsRequest], - Awaitable[~.SuggestBrandsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_brands" not in self._stubs: - self._stubs["suggest_brands"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.BrandSuggestionService/SuggestBrands", - request_serializer=brand_suggestion_service.SuggestBrandsRequest.serialize, - response_deserializer=brand_suggestion_service.SuggestBrandsResponse.deserialize, - ) - return self._stubs["suggest_brands"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.suggest_brands: self._wrap_method( - self.suggest_brands, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("BrandSuggestionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_asset_service/async_client.py deleted file mode 100644 index caeac69ef..000000000 --- a/google/ads/googleads/v19/services/services/campaign_asset_service/async_client.py +++ /dev/null @@ -1,433 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import campaign_asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignAssetServiceTransport, DEFAULT_CLIENT_INFO -from .client import CampaignAssetServiceClient - -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 CampaignAssetServiceAsyncClient: - """Service to manage campaign assets.""" - - _client: CampaignAssetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignAssetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CampaignAssetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignAssetServiceClient._DEFAULT_UNIVERSE - - asset_path = staticmethod(CampaignAssetServiceClient.asset_path) - parse_asset_path = staticmethod(CampaignAssetServiceClient.parse_asset_path) - campaign_path = staticmethod(CampaignAssetServiceClient.campaign_path) - parse_campaign_path = staticmethod( - CampaignAssetServiceClient.parse_campaign_path - ) - campaign_asset_path = staticmethod( - CampaignAssetServiceClient.campaign_asset_path - ) - parse_campaign_asset_path = staticmethod( - CampaignAssetServiceClient.parse_campaign_asset_path - ) - common_billing_account_path = staticmethod( - CampaignAssetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignAssetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignAssetServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignAssetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignAssetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignAssetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignAssetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignAssetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignAssetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignAssetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignAssetServiceAsyncClient: The constructed client. - """ - return CampaignAssetServiceClient.from_service_account_info.__func__(CampaignAssetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignAssetServiceAsyncClient: The constructed client. - """ - return CampaignAssetServiceClient.from_service_account_file.__func__(CampaignAssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignAssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignAssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignAssetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignAssetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignAssetServiceTransport, - Callable[..., CampaignAssetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign asset service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignAssetServiceTransport,Callable[..., CampaignAssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignAssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignAssetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignAssetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignAssetService", - "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.ads.googleads.v19.services.CampaignAssetService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaign_assets( - self, - request: Optional[ - Union[campaign_asset_service.MutateCampaignAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_asset_service.CampaignAssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_asset_service.MutateCampaignAssetsResponse: - r"""Creates, updates, or removes campaign assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignAssetsRequest, dict]]): - The request object. Request message for - [CampaignAssetService.MutateCampaignAssets][google.ads.googleads.v19.services.CampaignAssetService.MutateCampaignAssets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose campaign assets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignAssetOperation]`): - Required. The list of operations to - perform on individual campaign assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignAssetsResponse: - Response message for a campaign asset - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_asset_service.MutateCampaignAssetsRequest - ): - request = campaign_asset_service.MutateCampaignAssetsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaign_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignAssetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignAssetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_service/client.py b/google/ads/googleads/v19/services/services/campaign_asset_service/client.py deleted file mode 100644 index 2991be747..000000000 --- a/google/ads/googleads/v19/services/services/campaign_asset_service/client.py +++ /dev/null @@ -1,924 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import campaign_asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignAssetServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CampaignAssetServiceGrpcTransport -from .transports.grpc_asyncio import CampaignAssetServiceGrpcAsyncIOTransport - - -class CampaignAssetServiceClientMeta(type): - """Metaclass for the CampaignAssetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignAssetServiceTransport]] - _transport_registry["grpc"] = CampaignAssetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignAssetServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignAssetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignAssetServiceClient(metaclass=CampaignAssetServiceClientMeta): - """Service to manage campaign assets.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignAssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignAssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignAssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignAssetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_path( - customer_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset string.""" - return "customers/{customer_id}/assets/{asset_id}".format( - customer_id=customer_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_path(path: str) -> Dict[str, str]: - """Parses a asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assets/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_asset_path( - customer_id: str, - campaign_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified campaign_asset string.""" - return "customers/{customer_id}/campaignAssets/{campaign_id}~{asset_id}~{field_type}".format( - customer_id=customer_id, - campaign_id=campaign_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_campaign_asset_path(path: str) -> Dict[str, str]: - """Parses a campaign_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignAssets/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CampaignAssetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CampaignAssetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CampaignAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignAssetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignAssetServiceTransport, - Callable[..., CampaignAssetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign asset service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignAssetServiceTransport,Callable[..., CampaignAssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignAssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignAssetServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignAssetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = CampaignAssetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignAssetServiceTransport - ) - if transport_provided: - # transport is a CampaignAssetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CampaignAssetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignAssetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignAssetServiceTransport], - Callable[..., CampaignAssetServiceTransport], - ] = ( - CampaignAssetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignAssetServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignAssetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignAssetService", - "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.ads.googleads.v19.services.CampaignAssetService", - "credentialsType": None, - } - ), - ) - - def mutate_campaign_assets( - self, - request: Optional[ - Union[campaign_asset_service.MutateCampaignAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_asset_service.CampaignAssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_asset_service.MutateCampaignAssetsResponse: - r"""Creates, updates, or removes campaign assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignAssetsRequest, dict]): - The request object. Request message for - [CampaignAssetService.MutateCampaignAssets][google.ads.googleads.v19.services.CampaignAssetService.MutateCampaignAssets]. - customer_id (str): - Required. The ID of the customer - whose campaign assets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignAssetOperation]): - Required. The list of operations to - perform on individual campaign assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignAssetsResponse: - Response message for a campaign asset - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_asset_service.MutateCampaignAssetsRequest - ): - request = campaign_asset_service.MutateCampaignAssetsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_campaign_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignAssetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignAssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_asset_service/transports/base.py deleted file mode 100644 index 52b235d4c..000000000 --- a/google/ads/googleads/v19/services/services/campaign_asset_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import campaign_asset_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignAssetServiceTransport(abc.ABC): - """Abstract transport class for CampaignAssetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaign_assets: gapic_v1.method.wrap_method( - self.mutate_campaign_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_campaign_assets( - self, - ) -> Callable[ - [campaign_asset_service.MutateCampaignAssetsRequest], - Union[ - campaign_asset_service.MutateCampaignAssetsResponse, - Awaitable[campaign_asset_service.MutateCampaignAssetsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignAssetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_asset_service/transports/grpc.py deleted file mode 100644 index 1c335aa30..000000000 --- a/google/ads/googleads/v19/services/services/campaign_asset_service/transports/grpc.py +++ /dev/null @@ -1,388 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import campaign_asset_service -from .base import CampaignAssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignAssetService", - "rpcName": str(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.ads.googleads.v19.services.CampaignAssetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignAssetServiceGrpcTransport(CampaignAssetServiceTransport): - """gRPC backend transport for CampaignAssetService. - - Service to manage campaign assets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_campaign_assets( - self, - ) -> Callable[ - [campaign_asset_service.MutateCampaignAssetsRequest], - campaign_asset_service.MutateCampaignAssetsResponse, - ]: - r"""Return a callable for the mutate campaign assets method over gRPC. - - Creates, updates, or removes campaign assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateCampaignAssetsRequest], - ~.MutateCampaignAssetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_assets" not in self._stubs: - self._stubs["mutate_campaign_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignAssetService/MutateCampaignAssets", - request_serializer=campaign_asset_service.MutateCampaignAssetsRequest.serialize, - response_deserializer=campaign_asset_service.MutateCampaignAssetsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_assets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_asset_service/transports/grpc_asyncio.py deleted file mode 100644 index e27cfe5e2..000000000 --- a/google/ads/googleads/v19/services/services/campaign_asset_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import campaign_asset_service -from .base import CampaignAssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignAssetService", - "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.ads.googleads.v19.services.CampaignAssetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignAssetServiceGrpcAsyncIOTransport(CampaignAssetServiceTransport): - """gRPC AsyncIO backend transport for CampaignAssetService. - - Service to manage campaign assets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_campaign_assets( - self, - ) -> Callable[ - [campaign_asset_service.MutateCampaignAssetsRequest], - Awaitable[campaign_asset_service.MutateCampaignAssetsResponse], - ]: - r"""Return a callable for the mutate campaign assets method over gRPC. - - Creates, updates, or removes campaign assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateCampaignAssetsRequest], - Awaitable[~.MutateCampaignAssetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_assets" not in self._stubs: - self._stubs["mutate_campaign_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignAssetService/MutateCampaignAssets", - request_serializer=campaign_asset_service.MutateCampaignAssetsRequest.serialize, - response_deserializer=campaign_asset_service.MutateCampaignAssetsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_assets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaign_assets: self._wrap_method( - self.mutate_campaign_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignAssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_set_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_asset_set_service/async_client.py deleted file mode 100644 index 9daec52e5..000000000 --- a/google/ads/googleads/v19/services/services/campaign_asset_set_service/async_client.py +++ /dev/null @@ -1,437 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import campaign_asset_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CampaignAssetSetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CampaignAssetSetServiceClient - -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 CampaignAssetSetServiceAsyncClient: - """Service to manage campaign asset set""" - - _client: CampaignAssetSetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignAssetSetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CampaignAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignAssetSetServiceClient._DEFAULT_UNIVERSE - - asset_set_path = staticmethod(CampaignAssetSetServiceClient.asset_set_path) - parse_asset_set_path = staticmethod( - CampaignAssetSetServiceClient.parse_asset_set_path - ) - campaign_path = staticmethod(CampaignAssetSetServiceClient.campaign_path) - parse_campaign_path = staticmethod( - CampaignAssetSetServiceClient.parse_campaign_path - ) - campaign_asset_set_path = staticmethod( - CampaignAssetSetServiceClient.campaign_asset_set_path - ) - parse_campaign_asset_set_path = staticmethod( - CampaignAssetSetServiceClient.parse_campaign_asset_set_path - ) - common_billing_account_path = staticmethod( - CampaignAssetSetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignAssetSetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignAssetSetServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignAssetSetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignAssetSetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignAssetSetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignAssetSetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignAssetSetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignAssetSetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignAssetSetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignAssetSetServiceAsyncClient: The constructed client. - """ - return CampaignAssetSetServiceClient.from_service_account_info.__func__(CampaignAssetSetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignAssetSetServiceAsyncClient: The constructed client. - """ - return CampaignAssetSetServiceClient.from_service_account_file.__func__(CampaignAssetSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignAssetSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignAssetSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignAssetSetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignAssetSetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignAssetSetServiceTransport, - Callable[..., CampaignAssetSetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign asset set service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignAssetSetServiceTransport,Callable[..., CampaignAssetSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignAssetSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignAssetSetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignAssetSetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignAssetSetService", - "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.ads.googleads.v19.services.CampaignAssetSetService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaign_asset_sets( - self, - request: Optional[ - Union[ - campaign_asset_set_service.MutateCampaignAssetSetsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_asset_set_service.CampaignAssetSetOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_asset_set_service.MutateCampaignAssetSetsResponse: - r"""Creates, updates or removes campaign asset sets. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignAssetSetsRequest, dict]]): - The request object. Request message for - [CampaignAssetSetService.MutateCampaignAssetSets][google.ads.googleads.v19.services.CampaignAssetSetService.MutateCampaignAssetSets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose campaign asset sets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignAssetSetOperation]`): - Required. The list of operations to - perform on individual campaign asset - sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignAssetSetsResponse: - Response message for a campaign asset - set mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_asset_set_service.MutateCampaignAssetSetsRequest - ): - request = campaign_asset_set_service.MutateCampaignAssetSetsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaign_asset_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignAssetSetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignAssetSetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_set_service/client.py b/google/ads/googleads/v19/services/services/campaign_asset_set_service/client.py deleted file mode 100644 index c50c7063a..000000000 --- a/google/ads/googleads/v19/services/services/campaign_asset_set_service/client.py +++ /dev/null @@ -1,929 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import campaign_asset_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CampaignAssetSetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CampaignAssetSetServiceGrpcTransport -from .transports.grpc_asyncio import CampaignAssetSetServiceGrpcAsyncIOTransport - - -class CampaignAssetSetServiceClientMeta(type): - """Metaclass for the CampaignAssetSetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignAssetSetServiceTransport]] - _transport_registry["grpc"] = CampaignAssetSetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignAssetSetServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignAssetSetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignAssetSetServiceClient( - metaclass=CampaignAssetSetServiceClientMeta -): - """Service to manage campaign asset set""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignAssetSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignAssetSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignAssetSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignAssetSetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_set_path( - customer_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified asset_set string.""" - return "customers/{customer_id}/assetSets/{asset_set_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_asset_set_path(path: str) -> Dict[str, str]: - """Parses a asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_asset_set_path( - customer_id: str, - campaign_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified campaign_asset_set string.""" - return "customers/{customer_id}/campaignAssetSets/{campaign_id}~{asset_set_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_campaign_asset_set_path(path: str) -> Dict[str, str]: - """Parses a campaign_asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignAssetSets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CampaignAssetSetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CampaignAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CampaignAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignAssetSetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignAssetSetServiceTransport, - Callable[..., CampaignAssetSetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign asset set service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignAssetSetServiceTransport,Callable[..., CampaignAssetSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignAssetSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignAssetSetServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignAssetSetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CampaignAssetSetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignAssetSetServiceTransport - ) - if transport_provided: - # transport is a CampaignAssetSetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CampaignAssetSetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignAssetSetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignAssetSetServiceTransport], - Callable[..., CampaignAssetSetServiceTransport], - ] = ( - CampaignAssetSetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignAssetSetServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignAssetSetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignAssetSetService", - "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.ads.googleads.v19.services.CampaignAssetSetService", - "credentialsType": None, - } - ), - ) - - def mutate_campaign_asset_sets( - self, - request: Optional[ - Union[ - campaign_asset_set_service.MutateCampaignAssetSetsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_asset_set_service.CampaignAssetSetOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_asset_set_service.MutateCampaignAssetSetsResponse: - r"""Creates, updates or removes campaign asset sets. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignAssetSetsRequest, dict]): - The request object. Request message for - [CampaignAssetSetService.MutateCampaignAssetSets][google.ads.googleads.v19.services.CampaignAssetSetService.MutateCampaignAssetSets]. - customer_id (str): - Required. The ID of the customer - whose campaign asset sets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignAssetSetOperation]): - Required. The list of operations to - perform on individual campaign asset - sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignAssetSetsResponse: - Response message for a campaign asset - set mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_asset_set_service.MutateCampaignAssetSetsRequest - ): - request = campaign_asset_set_service.MutateCampaignAssetSetsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_campaign_asset_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignAssetSetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignAssetSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/base.py deleted file mode 100644 index d3f406946..000000000 --- a/google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import campaign_asset_set_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignAssetSetServiceTransport(abc.ABC): - """Abstract transport class for CampaignAssetSetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaign_asset_sets: gapic_v1.method.wrap_method( - self.mutate_campaign_asset_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_campaign_asset_sets( - self, - ) -> Callable[ - [campaign_asset_set_service.MutateCampaignAssetSetsRequest], - Union[ - campaign_asset_set_service.MutateCampaignAssetSetsResponse, - Awaitable[ - campaign_asset_set_service.MutateCampaignAssetSetsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignAssetSetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/grpc.py deleted file mode 100644 index 2a678c458..000000000 --- a/google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/grpc.py +++ /dev/null @@ -1,382 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import campaign_asset_set_service -from .base import CampaignAssetSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignAssetSetService", - "rpcName": str(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.ads.googleads.v19.services.CampaignAssetSetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignAssetSetServiceGrpcTransport(CampaignAssetSetServiceTransport): - """gRPC backend transport for CampaignAssetSetService. - - Service to manage campaign asset set - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_campaign_asset_sets( - self, - ) -> Callable[ - [campaign_asset_set_service.MutateCampaignAssetSetsRequest], - campaign_asset_set_service.MutateCampaignAssetSetsResponse, - ]: - r"""Return a callable for the mutate campaign asset sets method over gRPC. - - Creates, updates or removes campaign asset sets. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCampaignAssetSetsRequest], - ~.MutateCampaignAssetSetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_asset_sets" not in self._stubs: - self._stubs["mutate_campaign_asset_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignAssetSetService/MutateCampaignAssetSets", - request_serializer=campaign_asset_set_service.MutateCampaignAssetSetsRequest.serialize, - response_deserializer=campaign_asset_set_service.MutateCampaignAssetSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_asset_sets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignAssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/grpc_asyncio.py deleted file mode 100644 index 08a9f23df..000000000 --- a/google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,405 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import campaign_asset_set_service -from .base import CampaignAssetSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignAssetSetService", - "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.ads.googleads.v19.services.CampaignAssetSetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignAssetSetServiceGrpcAsyncIOTransport( - CampaignAssetSetServiceTransport -): - """gRPC AsyncIO backend transport for CampaignAssetSetService. - - Service to manage campaign asset set - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_campaign_asset_sets( - self, - ) -> Callable[ - [campaign_asset_set_service.MutateCampaignAssetSetsRequest], - Awaitable[campaign_asset_set_service.MutateCampaignAssetSetsResponse], - ]: - r"""Return a callable for the mutate campaign asset sets method over gRPC. - - Creates, updates or removes campaign asset sets. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCampaignAssetSetsRequest], - Awaitable[~.MutateCampaignAssetSetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_asset_sets" not in self._stubs: - self._stubs["mutate_campaign_asset_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignAssetSetService/MutateCampaignAssetSets", - request_serializer=campaign_asset_set_service.MutateCampaignAssetSetsRequest.serialize, - response_deserializer=campaign_asset_set_service.MutateCampaignAssetSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_asset_sets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaign_asset_sets: self._wrap_method( - self.mutate_campaign_asset_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignAssetSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/async_client.py deleted file mode 100644 index f4fd093a6..000000000 --- a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/async_client.py +++ /dev/null @@ -1,451 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - campaign_bid_modifier_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CampaignBidModifierServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CampaignBidModifierServiceClient - -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 CampaignBidModifierServiceAsyncClient: - """Service to manage campaign bid modifiers.""" - - _client: CampaignBidModifierServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignBidModifierServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CampaignBidModifierServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignBidModifierServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignBidModifierServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod(CampaignBidModifierServiceClient.campaign_path) - parse_campaign_path = staticmethod( - CampaignBidModifierServiceClient.parse_campaign_path - ) - campaign_bid_modifier_path = staticmethod( - CampaignBidModifierServiceClient.campaign_bid_modifier_path - ) - parse_campaign_bid_modifier_path = staticmethod( - CampaignBidModifierServiceClient.parse_campaign_bid_modifier_path - ) - common_billing_account_path = staticmethod( - CampaignBidModifierServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignBidModifierServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignBidModifierServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignBidModifierServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignBidModifierServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignBidModifierServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignBidModifierServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignBidModifierServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignBidModifierServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignBidModifierServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignBidModifierServiceAsyncClient: The constructed client. - """ - return CampaignBidModifierServiceClient.from_service_account_info.__func__(CampaignBidModifierServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignBidModifierServiceAsyncClient: The constructed client. - """ - return CampaignBidModifierServiceClient.from_service_account_file.__func__(CampaignBidModifierServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignBidModifierServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignBidModifierServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignBidModifierServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignBidModifierServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignBidModifierServiceTransport, - Callable[..., CampaignBidModifierServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign bid modifier service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignBidModifierServiceTransport,Callable[..., CampaignBidModifierServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignBidModifierServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignBidModifierServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignBidModifierServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignBidModifierService", - "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.ads.googleads.v19.services.CampaignBidModifierService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaign_bid_modifiers( - self, - request: Optional[ - Union[ - campaign_bid_modifier_service.MutateCampaignBidModifiersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_bid_modifier_service.CampaignBidModifierOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_bid_modifier_service.MutateCampaignBidModifiersResponse: - r"""Creates, updates, or removes campaign bid modifiers. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ContextError <>`__ - `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignBidModifiersRequest, dict]]): - The request object. Request message for - [CampaignBidModifierService.MutateCampaignBidModifiers][google.ads.googleads.v19.services.CampaignBidModifierService.MutateCampaignBidModifiers]. - customer_id (:class:`str`): - Required. ID of the customer whose - campaign bid modifiers are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignBidModifierOperation]`): - Required. The list of operations to - perform on individual campaign bid - modifiers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignBidModifiersResponse: - Response message for campaign bid - modifiers mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - campaign_bid_modifier_service.MutateCampaignBidModifiersRequest, - ): - request = ( - campaign_bid_modifier_service.MutateCampaignBidModifiersRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaign_bid_modifiers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignBidModifierServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignBidModifierServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/client.py b/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/client.py deleted file mode 100644 index 023aa170f..000000000 --- a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/client.py +++ /dev/null @@ -1,932 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - campaign_bid_modifier_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CampaignBidModifierServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CampaignBidModifierServiceGrpcTransport -from .transports.grpc_asyncio import ( - CampaignBidModifierServiceGrpcAsyncIOTransport, -) - - -class CampaignBidModifierServiceClientMeta(type): - """Metaclass for the CampaignBidModifierService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignBidModifierServiceTransport]] - _transport_registry["grpc"] = CampaignBidModifierServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignBidModifierServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignBidModifierServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignBidModifierServiceClient( - metaclass=CampaignBidModifierServiceClientMeta -): - """Service to manage campaign bid modifiers.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignBidModifierServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignBidModifierServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignBidModifierServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignBidModifierServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_bid_modifier_path( - customer_id: str, - campaign_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified campaign_bid_modifier string.""" - return "customers/{customer_id}/campaignBidModifiers/{campaign_id}~{criterion_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_campaign_bid_modifier_path(path: str) -> Dict[str, str]: - """Parses a campaign_bid_modifier path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignBidModifiers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CampaignBidModifierServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - CampaignBidModifierServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = CampaignBidModifierServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignBidModifierServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignBidModifierServiceTransport, - Callable[..., CampaignBidModifierServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign bid modifier service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignBidModifierServiceTransport,Callable[..., CampaignBidModifierServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignBidModifierServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignBidModifierServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignBidModifierServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CampaignBidModifierServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignBidModifierServiceTransport - ) - if transport_provided: - # transport is a CampaignBidModifierServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CampaignBidModifierServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignBidModifierServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignBidModifierServiceTransport], - Callable[..., CampaignBidModifierServiceTransport], - ] = ( - CampaignBidModifierServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignBidModifierServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignBidModifierServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignBidModifierService", - "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.ads.googleads.v19.services.CampaignBidModifierService", - "credentialsType": None, - } - ), - ) - - def mutate_campaign_bid_modifiers( - self, - request: Optional[ - Union[ - campaign_bid_modifier_service.MutateCampaignBidModifiersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_bid_modifier_service.CampaignBidModifierOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_bid_modifier_service.MutateCampaignBidModifiersResponse: - r"""Creates, updates, or removes campaign bid modifiers. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ContextError <>`__ - `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignBidModifiersRequest, dict]): - The request object. Request message for - [CampaignBidModifierService.MutateCampaignBidModifiers][google.ads.googleads.v19.services.CampaignBidModifierService.MutateCampaignBidModifiers]. - customer_id (str): - Required. ID of the customer whose - campaign bid modifiers are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignBidModifierOperation]): - Required. The list of operations to - perform on individual campaign bid - modifiers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignBidModifiersResponse: - Response message for campaign bid - modifiers mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - campaign_bid_modifier_service.MutateCampaignBidModifiersRequest, - ): - request = ( - campaign_bid_modifier_service.MutateCampaignBidModifiersRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_campaign_bid_modifiers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignBidModifierServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignBidModifierServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/base.py deleted file mode 100644 index 9c1220e2c..000000000 --- a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - campaign_bid_modifier_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignBidModifierServiceTransport(abc.ABC): - """Abstract transport class for CampaignBidModifierService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaign_bid_modifiers: gapic_v1.method.wrap_method( - self.mutate_campaign_bid_modifiers, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_campaign_bid_modifiers( - self, - ) -> Callable[ - [campaign_bid_modifier_service.MutateCampaignBidModifiersRequest], - Union[ - campaign_bid_modifier_service.MutateCampaignBidModifiersResponse, - Awaitable[ - campaign_bid_modifier_service.MutateCampaignBidModifiersResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignBidModifierServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/grpc.py deleted file mode 100644 index 7db76cacf..000000000 --- a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/grpc.py +++ /dev/null @@ -1,396 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - campaign_bid_modifier_service, -) -from .base import CampaignBidModifierServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignBidModifierService", - "rpcName": str(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.ads.googleads.v19.services.CampaignBidModifierService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignBidModifierServiceGrpcTransport( - CampaignBidModifierServiceTransport -): - """gRPC backend transport for CampaignBidModifierService. - - Service to manage campaign bid modifiers. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_campaign_bid_modifiers( - self, - ) -> Callable[ - [campaign_bid_modifier_service.MutateCampaignBidModifiersRequest], - campaign_bid_modifier_service.MutateCampaignBidModifiersResponse, - ]: - r"""Return a callable for the mutate campaign bid modifiers method over gRPC. - - Creates, updates, or removes campaign bid modifiers. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ContextError <>`__ - `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateCampaignBidModifiersRequest], - ~.MutateCampaignBidModifiersResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_bid_modifiers" not in self._stubs: - self._stubs["mutate_campaign_bid_modifiers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignBidModifierService/MutateCampaignBidModifiers", - request_serializer=campaign_bid_modifier_service.MutateCampaignBidModifiersRequest.serialize, - response_deserializer=campaign_bid_modifier_service.MutateCampaignBidModifiersResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_bid_modifiers"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignBidModifierServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/grpc_asyncio.py deleted file mode 100644 index 4245a12ac..000000000 --- a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,419 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - campaign_bid_modifier_service, -) -from .base import CampaignBidModifierServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignBidModifierService", - "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.ads.googleads.v19.services.CampaignBidModifierService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignBidModifierServiceGrpcAsyncIOTransport( - CampaignBidModifierServiceTransport -): - """gRPC AsyncIO backend transport for CampaignBidModifierService. - - Service to manage campaign bid modifiers. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_campaign_bid_modifiers( - self, - ) -> Callable[ - [campaign_bid_modifier_service.MutateCampaignBidModifiersRequest], - Awaitable[ - campaign_bid_modifier_service.MutateCampaignBidModifiersResponse - ], - ]: - r"""Return a callable for the mutate campaign bid modifiers method over gRPC. - - Creates, updates, or removes campaign bid modifiers. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ContextError <>`__ - `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateCampaignBidModifiersRequest], - Awaitable[~.MutateCampaignBidModifiersResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_bid_modifiers" not in self._stubs: - self._stubs["mutate_campaign_bid_modifiers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignBidModifierService/MutateCampaignBidModifiers", - request_serializer=campaign_bid_modifier_service.MutateCampaignBidModifiersRequest.serialize, - response_deserializer=campaign_bid_modifier_service.MutateCampaignBidModifiersResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_bid_modifiers"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaign_bid_modifiers: self._wrap_method( - self.mutate_campaign_bid_modifiers, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignBidModifierServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_budget_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_budget_service/async_client.py deleted file mode 100644 index cc6423034..000000000 --- a/google/ads/googleads/v19/services/services/campaign_budget_service/async_client.py +++ /dev/null @@ -1,430 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import campaign_budget_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignBudgetServiceTransport, DEFAULT_CLIENT_INFO -from .client import CampaignBudgetServiceClient - -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 CampaignBudgetServiceAsyncClient: - """Service to manage campaign budgets.""" - - _client: CampaignBudgetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignBudgetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CampaignBudgetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignBudgetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignBudgetServiceClient._DEFAULT_UNIVERSE - - campaign_budget_path = staticmethod( - CampaignBudgetServiceClient.campaign_budget_path - ) - parse_campaign_budget_path = staticmethod( - CampaignBudgetServiceClient.parse_campaign_budget_path - ) - common_billing_account_path = staticmethod( - CampaignBudgetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignBudgetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignBudgetServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignBudgetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignBudgetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignBudgetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignBudgetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignBudgetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignBudgetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignBudgetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignBudgetServiceAsyncClient: The constructed client. - """ - return CampaignBudgetServiceClient.from_service_account_info.__func__(CampaignBudgetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignBudgetServiceAsyncClient: The constructed client. - """ - return CampaignBudgetServiceClient.from_service_account_file.__func__(CampaignBudgetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignBudgetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignBudgetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignBudgetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignBudgetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignBudgetServiceTransport, - Callable[..., CampaignBudgetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign budget service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignBudgetServiceTransport,Callable[..., CampaignBudgetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignBudgetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignBudgetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignBudgetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignBudgetService", - "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.ads.googleads.v19.services.CampaignBudgetService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaign_budgets( - self, - request: Optional[ - Union[campaign_budget_service.MutateCampaignBudgetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_budget_service.CampaignBudgetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_budget_service.MutateCampaignBudgetsResponse: - r"""Creates, updates, or removes campaign budgets. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignBudgetError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `OperationAccessDeniedError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignBudgetsRequest, dict]]): - The request object. Request message for - [CampaignBudgetService.MutateCampaignBudgets][google.ads.googleads.v19.services.CampaignBudgetService.MutateCampaignBudgets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose campaign budgets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignBudgetOperation]`): - Required. The list of operations to - perform on individual campaign budgets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignBudgetsResponse: - Response message for campaign budget - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_budget_service.MutateCampaignBudgetsRequest - ): - request = campaign_budget_service.MutateCampaignBudgetsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaign_budgets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignBudgetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignBudgetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_budget_service/client.py b/google/ads/googleads/v19/services/services/campaign_budget_service/client.py deleted file mode 100644 index 26c7c10c0..000000000 --- a/google/ads/googleads/v19/services/services/campaign_budget_service/client.py +++ /dev/null @@ -1,886 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import campaign_budget_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignBudgetServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CampaignBudgetServiceGrpcTransport -from .transports.grpc_asyncio import CampaignBudgetServiceGrpcAsyncIOTransport - - -class CampaignBudgetServiceClientMeta(type): - """Metaclass for the CampaignBudgetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignBudgetServiceTransport]] - _transport_registry["grpc"] = CampaignBudgetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignBudgetServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignBudgetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignBudgetServiceClient(metaclass=CampaignBudgetServiceClientMeta): - """Service to manage campaign budgets.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignBudgetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignBudgetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignBudgetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignBudgetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_budget_path( - customer_id: str, - campaign_budget_id: str, - ) -> str: - """Returns a fully-qualified campaign_budget string.""" - return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( - customer_id=customer_id, - campaign_budget_id=campaign_budget_id, - ) - - @staticmethod - def parse_campaign_budget_path(path: str) -> Dict[str, str]: - """Parses a campaign_budget path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CampaignBudgetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CampaignBudgetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CampaignBudgetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignBudgetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignBudgetServiceTransport, - Callable[..., CampaignBudgetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign budget service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignBudgetServiceTransport,Callable[..., CampaignBudgetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignBudgetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignBudgetServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignBudgetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CampaignBudgetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignBudgetServiceTransport - ) - if transport_provided: - # transport is a CampaignBudgetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CampaignBudgetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignBudgetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignBudgetServiceTransport], - Callable[..., CampaignBudgetServiceTransport], - ] = ( - CampaignBudgetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignBudgetServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignBudgetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignBudgetService", - "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.ads.googleads.v19.services.CampaignBudgetService", - "credentialsType": None, - } - ), - ) - - def mutate_campaign_budgets( - self, - request: Optional[ - Union[campaign_budget_service.MutateCampaignBudgetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_budget_service.CampaignBudgetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_budget_service.MutateCampaignBudgetsResponse: - r"""Creates, updates, or removes campaign budgets. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignBudgetError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `OperationAccessDeniedError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignBudgetsRequest, dict]): - The request object. Request message for - [CampaignBudgetService.MutateCampaignBudgets][google.ads.googleads.v19.services.CampaignBudgetService.MutateCampaignBudgets]. - customer_id (str): - Required. The ID of the customer - whose campaign budgets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignBudgetOperation]): - Required. The list of operations to - perform on individual campaign budgets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignBudgetsResponse: - Response message for campaign budget - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_budget_service.MutateCampaignBudgetsRequest - ): - request = campaign_budget_service.MutateCampaignBudgetsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_campaign_budgets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignBudgetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignBudgetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_budget_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_budget_service/transports/base.py deleted file mode 100644 index 102a6a230..000000000 --- a/google/ads/googleads/v19/services/services/campaign_budget_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import campaign_budget_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignBudgetServiceTransport(abc.ABC): - """Abstract transport class for CampaignBudgetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaign_budgets: gapic_v1.method.wrap_method( - self.mutate_campaign_budgets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_campaign_budgets( - self, - ) -> Callable[ - [campaign_budget_service.MutateCampaignBudgetsRequest], - Union[ - campaign_budget_service.MutateCampaignBudgetsResponse, - Awaitable[campaign_budget_service.MutateCampaignBudgetsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignBudgetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_budget_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_budget_service/transports/grpc.py deleted file mode 100644 index 853d7120a..000000000 --- a/google/ads/googleads/v19/services/services/campaign_budget_service/transports/grpc.py +++ /dev/null @@ -1,391 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import campaign_budget_service -from .base import CampaignBudgetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignBudgetService", - "rpcName": str(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.ads.googleads.v19.services.CampaignBudgetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignBudgetServiceGrpcTransport(CampaignBudgetServiceTransport): - """gRPC backend transport for CampaignBudgetService. - - Service to manage campaign budgets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_campaign_budgets( - self, - ) -> Callable[ - [campaign_budget_service.MutateCampaignBudgetsRequest], - campaign_budget_service.MutateCampaignBudgetsResponse, - ]: - r"""Return a callable for the mutate campaign budgets method over gRPC. - - Creates, updates, or removes campaign budgets. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignBudgetError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `OperationAccessDeniedError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateCampaignBudgetsRequest], - ~.MutateCampaignBudgetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_budgets" not in self._stubs: - self._stubs["mutate_campaign_budgets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignBudgetService/MutateCampaignBudgets", - request_serializer=campaign_budget_service.MutateCampaignBudgetsRequest.serialize, - response_deserializer=campaign_budget_service.MutateCampaignBudgetsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_budgets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignBudgetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_budget_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_budget_service/transports/grpc_asyncio.py deleted file mode 100644 index 84c3e923d..000000000 --- a/google/ads/googleads/v19/services/services/campaign_budget_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,412 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import campaign_budget_service -from .base import CampaignBudgetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignBudgetService", - "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.ads.googleads.v19.services.CampaignBudgetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignBudgetServiceGrpcAsyncIOTransport(CampaignBudgetServiceTransport): - """gRPC AsyncIO backend transport for CampaignBudgetService. - - Service to manage campaign budgets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_campaign_budgets( - self, - ) -> Callable[ - [campaign_budget_service.MutateCampaignBudgetsRequest], - Awaitable[campaign_budget_service.MutateCampaignBudgetsResponse], - ]: - r"""Return a callable for the mutate campaign budgets method over gRPC. - - Creates, updates, or removes campaign budgets. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignBudgetError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `OperationAccessDeniedError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateCampaignBudgetsRequest], - Awaitable[~.MutateCampaignBudgetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_budgets" not in self._stubs: - self._stubs["mutate_campaign_budgets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignBudgetService/MutateCampaignBudgets", - request_serializer=campaign_budget_service.MutateCampaignBudgetsRequest.serialize, - response_deserializer=campaign_budget_service.MutateCampaignBudgetsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_budgets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaign_budgets: self._wrap_method( - self.mutate_campaign_budgets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignBudgetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/async_client.py deleted file mode 100644 index fa0d53aa1..000000000 --- a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/async_client.py +++ /dev/null @@ -1,442 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - campaign_conversion_goal_service, -) -from .transports.base import ( - CampaignConversionGoalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CampaignConversionGoalServiceClient - -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 CampaignConversionGoalServiceAsyncClient: - """Service to manage campaign conversion goal.""" - - _client: CampaignConversionGoalServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignConversionGoalServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CampaignConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignConversionGoalServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod( - CampaignConversionGoalServiceClient.campaign_path - ) - parse_campaign_path = staticmethod( - CampaignConversionGoalServiceClient.parse_campaign_path - ) - campaign_conversion_goal_path = staticmethod( - CampaignConversionGoalServiceClient.campaign_conversion_goal_path - ) - parse_campaign_conversion_goal_path = staticmethod( - CampaignConversionGoalServiceClient.parse_campaign_conversion_goal_path - ) - common_billing_account_path = staticmethod( - CampaignConversionGoalServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignConversionGoalServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignConversionGoalServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignConversionGoalServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignConversionGoalServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignConversionGoalServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignConversionGoalServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignConversionGoalServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignConversionGoalServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignConversionGoalServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignConversionGoalServiceAsyncClient: The constructed client. - """ - return CampaignConversionGoalServiceClient.from_service_account_info.__func__(CampaignConversionGoalServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignConversionGoalServiceAsyncClient: The constructed client. - """ - return CampaignConversionGoalServiceClient.from_service_account_file.__func__(CampaignConversionGoalServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignConversionGoalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignConversionGoalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignConversionGoalServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - CampaignConversionGoalServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignConversionGoalServiceTransport, - Callable[..., CampaignConversionGoalServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign conversion goal service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignConversionGoalServiceTransport,Callable[..., CampaignConversionGoalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignConversionGoalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignConversionGoalServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignConversionGoalServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignConversionGoalService", - "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.ads.googleads.v19.services.CampaignConversionGoalService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaign_conversion_goals( - self, - request: Optional[ - Union[ - campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_conversion_goal_service.CampaignConversionGoalOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse: - r"""Creates, updates or removes campaign conversion - goals. Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignConversionGoalsRequest, dict]]): - The request object. Request message for - [CampaignConversionGoalService.MutateCampaignConversionGoals][google.ads.googleads.v19.services.CampaignConversionGoalService.MutateCampaignConversionGoals]. - customer_id (:class:`str`): - Required. The ID of the customer - whose campaign conversion goals are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignConversionGoalOperation]`): - Required. The list of operations to - perform on individual campaign - conversion goal. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignConversionGoalsResponse: - Response message for a campaign - conversion goal mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest, - ): - request = campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaign_conversion_goals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignConversionGoalServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignConversionGoalServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/client.py b/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/client.py deleted file mode 100644 index 9200b5a14..000000000 --- a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/client.py +++ /dev/null @@ -1,923 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - campaign_conversion_goal_service, -) -from .transports.base import ( - CampaignConversionGoalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CampaignConversionGoalServiceGrpcTransport -from .transports.grpc_asyncio import ( - CampaignConversionGoalServiceGrpcAsyncIOTransport, -) - - -class CampaignConversionGoalServiceClientMeta(type): - """Metaclass for the CampaignConversionGoalService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignConversionGoalServiceTransport]] - _transport_registry["grpc"] = CampaignConversionGoalServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignConversionGoalServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignConversionGoalServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignConversionGoalServiceClient( - metaclass=CampaignConversionGoalServiceClientMeta -): - """Service to manage campaign conversion goal.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignConversionGoalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignConversionGoalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignConversionGoalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignConversionGoalServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_conversion_goal_path( - customer_id: str, - campaign_id: str, - category: str, - source: str, - ) -> str: - """Returns a fully-qualified campaign_conversion_goal string.""" - return "customers/{customer_id}/campaignConversionGoals/{campaign_id}~{category}~{source}".format( - customer_id=customer_id, - campaign_id=campaign_id, - category=category, - source=source, - ) - - @staticmethod - def parse_campaign_conversion_goal_path(path: str) -> Dict[str, str]: - """Parses a campaign_conversion_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignConversionGoals/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CampaignConversionGoalServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - CampaignConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = CampaignConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignConversionGoalServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignConversionGoalServiceTransport, - Callable[..., CampaignConversionGoalServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign conversion goal service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignConversionGoalServiceTransport,Callable[..., CampaignConversionGoalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignConversionGoalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignConversionGoalServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignConversionGoalServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CampaignConversionGoalServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignConversionGoalServiceTransport - ) - if transport_provided: - # transport is a CampaignConversionGoalServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CampaignConversionGoalServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignConversionGoalServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignConversionGoalServiceTransport], - Callable[..., CampaignConversionGoalServiceTransport], - ] = ( - CampaignConversionGoalServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignConversionGoalServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignConversionGoalServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignConversionGoalService", - "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.ads.googleads.v19.services.CampaignConversionGoalService", - "credentialsType": None, - } - ), - ) - - def mutate_campaign_conversion_goals( - self, - request: Optional[ - Union[ - campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_conversion_goal_service.CampaignConversionGoalOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse: - r"""Creates, updates or removes campaign conversion - goals. Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignConversionGoalsRequest, dict]): - The request object. Request message for - [CampaignConversionGoalService.MutateCampaignConversionGoals][google.ads.googleads.v19.services.CampaignConversionGoalService.MutateCampaignConversionGoals]. - customer_id (str): - Required. The ID of the customer - whose campaign conversion goals are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignConversionGoalOperation]): - Required. The list of operations to - perform on individual campaign - conversion goal. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignConversionGoalsResponse: - Response message for a campaign - conversion goal mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest, - ): - request = campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_campaign_conversion_goals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignConversionGoalServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignConversionGoalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/base.py deleted file mode 100644 index c9586e29c..000000000 --- a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - campaign_conversion_goal_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignConversionGoalServiceTransport(abc.ABC): - """Abstract transport class for CampaignConversionGoalService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaign_conversion_goals: gapic_v1.method.wrap_method( - self.mutate_campaign_conversion_goals, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_campaign_conversion_goals( - self, - ) -> Callable[ - [campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest], - Union[ - campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse, - Awaitable[ - campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignConversionGoalServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/grpc.py deleted file mode 100644 index cadd25541..000000000 --- a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/grpc.py +++ /dev/null @@ -1,387 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - campaign_conversion_goal_service, -) -from .base import CampaignConversionGoalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignConversionGoalService", - "rpcName": str(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.ads.googleads.v19.services.CampaignConversionGoalService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignConversionGoalServiceGrpcTransport( - CampaignConversionGoalServiceTransport -): - """gRPC backend transport for CampaignConversionGoalService. - - Service to manage campaign conversion goal. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_campaign_conversion_goals( - self, - ) -> Callable[ - [campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest], - campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse, - ]: - r"""Return a callable for the mutate campaign conversion - goals method over gRPC. - - Creates, updates or removes campaign conversion - goals. Operation statuses are returned. - - Returns: - Callable[[~.MutateCampaignConversionGoalsRequest], - ~.MutateCampaignConversionGoalsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_conversion_goals" not in self._stubs: - self._stubs["mutate_campaign_conversion_goals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignConversionGoalService/MutateCampaignConversionGoals", - request_serializer=campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest.serialize, - response_deserializer=campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_conversion_goals"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignConversionGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/grpc_asyncio.py deleted file mode 100644 index 1cb405608..000000000 --- a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,410 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - campaign_conversion_goal_service, -) -from .base import CampaignConversionGoalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignConversionGoalService", - "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.ads.googleads.v19.services.CampaignConversionGoalService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignConversionGoalServiceGrpcAsyncIOTransport( - CampaignConversionGoalServiceTransport -): - """gRPC AsyncIO backend transport for CampaignConversionGoalService. - - Service to manage campaign conversion goal. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_campaign_conversion_goals( - self, - ) -> Callable[ - [campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest], - Awaitable[ - campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse - ], - ]: - r"""Return a callable for the mutate campaign conversion - goals method over gRPC. - - Creates, updates or removes campaign conversion - goals. Operation statuses are returned. - - Returns: - Callable[[~.MutateCampaignConversionGoalsRequest], - Awaitable[~.MutateCampaignConversionGoalsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_conversion_goals" not in self._stubs: - self._stubs["mutate_campaign_conversion_goals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignConversionGoalService/MutateCampaignConversionGoals", - request_serializer=campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest.serialize, - response_deserializer=campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_conversion_goals"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaign_conversion_goals: self._wrap_method( - self.mutate_campaign_conversion_goals, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignConversionGoalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_criterion_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_criterion_service/async_client.py deleted file mode 100644 index 1f7fed7eb..000000000 --- a/google/ads/googleads/v19/services/services/campaign_criterion_service/async_client.py +++ /dev/null @@ -1,487 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import campaign_criterion_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CampaignCriterionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CampaignCriterionServiceClient - -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 CampaignCriterionServiceAsyncClient: - """Service to manage campaign criteria.""" - - _client: CampaignCriterionServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignCriterionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CampaignCriterionServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignCriterionServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod(CampaignCriterionServiceClient.campaign_path) - parse_campaign_path = staticmethod( - CampaignCriterionServiceClient.parse_campaign_path - ) - campaign_criterion_path = staticmethod( - CampaignCriterionServiceClient.campaign_criterion_path - ) - parse_campaign_criterion_path = staticmethod( - CampaignCriterionServiceClient.parse_campaign_criterion_path - ) - carrier_constant_path = staticmethod( - CampaignCriterionServiceClient.carrier_constant_path - ) - parse_carrier_constant_path = staticmethod( - CampaignCriterionServiceClient.parse_carrier_constant_path - ) - combined_audience_path = staticmethod( - CampaignCriterionServiceClient.combined_audience_path - ) - parse_combined_audience_path = staticmethod( - CampaignCriterionServiceClient.parse_combined_audience_path - ) - keyword_theme_constant_path = staticmethod( - CampaignCriterionServiceClient.keyword_theme_constant_path - ) - parse_keyword_theme_constant_path = staticmethod( - CampaignCriterionServiceClient.parse_keyword_theme_constant_path - ) - mobile_app_category_constant_path = staticmethod( - CampaignCriterionServiceClient.mobile_app_category_constant_path - ) - parse_mobile_app_category_constant_path = staticmethod( - CampaignCriterionServiceClient.parse_mobile_app_category_constant_path - ) - mobile_device_constant_path = staticmethod( - CampaignCriterionServiceClient.mobile_device_constant_path - ) - parse_mobile_device_constant_path = staticmethod( - CampaignCriterionServiceClient.parse_mobile_device_constant_path - ) - operating_system_version_constant_path = staticmethod( - CampaignCriterionServiceClient.operating_system_version_constant_path - ) - parse_operating_system_version_constant_path = staticmethod( - CampaignCriterionServiceClient.parse_operating_system_version_constant_path - ) - topic_constant_path = staticmethod( - CampaignCriterionServiceClient.topic_constant_path - ) - parse_topic_constant_path = staticmethod( - CampaignCriterionServiceClient.parse_topic_constant_path - ) - common_billing_account_path = staticmethod( - CampaignCriterionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignCriterionServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignCriterionServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignCriterionServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignCriterionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignCriterionServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignCriterionServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignCriterionServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignCriterionServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignCriterionServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignCriterionServiceAsyncClient: The constructed client. - """ - return CampaignCriterionServiceClient.from_service_account_info.__func__(CampaignCriterionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignCriterionServiceAsyncClient: The constructed client. - """ - return CampaignCriterionServiceClient.from_service_account_file.__func__(CampaignCriterionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignCriterionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignCriterionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignCriterionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignCriterionServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignCriterionServiceTransport, - Callable[..., CampaignCriterionServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign criterion service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignCriterionServiceTransport,Callable[..., CampaignCriterionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignCriterionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignCriterionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignCriterionServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignCriterionService", - "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.ads.googleads.v19.services.CampaignCriterionService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaign_criteria( - self, - request: Optional[ - Union[ - campaign_criterion_service.MutateCampaignCriteriaRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_criterion_service.CampaignCriterionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_criterion_service.MutateCampaignCriteriaResponse: - r"""Creates, updates, or removes criteria. Operation statuses are - returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CampaignCriterionError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `FunctionError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RegionCodeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignCriteriaRequest, dict]]): - The request object. Request message for - [CampaignCriterionService.MutateCampaignCriteria][google.ads.googleads.v19.services.CampaignCriterionService.MutateCampaignCriteria]. - customer_id (:class:`str`): - Required. The ID of the customer - whose criteria are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignCriterionOperation]`): - Required. The list of operations to - perform on individual criteria. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignCriteriaResponse: - Response message for campaign - criterion mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_criterion_service.MutateCampaignCriteriaRequest - ): - request = campaign_criterion_service.MutateCampaignCriteriaRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaign_criteria - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignCriterionServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignCriterionServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_criterion_service/client.py b/google/ads/googleads/v19/services/services/campaign_criterion_service/client.py deleted file mode 100644 index c01aa2422..000000000 --- a/google/ads/googleads/v19/services/services/campaign_criterion_service/client.py +++ /dev/null @@ -1,1043 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import campaign_criterion_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CampaignCriterionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CampaignCriterionServiceGrpcTransport -from .transports.grpc_asyncio import ( - CampaignCriterionServiceGrpcAsyncIOTransport, -) - - -class CampaignCriterionServiceClientMeta(type): - """Metaclass for the CampaignCriterionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignCriterionServiceTransport]] - _transport_registry["grpc"] = CampaignCriterionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignCriterionServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignCriterionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignCriterionServiceClient( - metaclass=CampaignCriterionServiceClientMeta -): - """Service to manage campaign criteria.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignCriterionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignCriterionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignCriterionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignCriterionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_criterion_path( - customer_id: str, - campaign_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified campaign_criterion string.""" - return "customers/{customer_id}/campaignCriteria/{campaign_id}~{criterion_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_campaign_criterion_path(path: str) -> Dict[str, str]: - """Parses a campaign_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def carrier_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified carrier_constant string.""" - return "carrierConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_carrier_constant_path(path: str) -> Dict[str, str]: - """Parses a carrier_constant path into its component segments.""" - m = re.match(r"^carrierConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def combined_audience_path( - customer_id: str, - combined_audience_id: str, - ) -> str: - """Returns a fully-qualified combined_audience string.""" - return "customers/{customer_id}/combinedAudiences/{combined_audience_id}".format( - customer_id=customer_id, - combined_audience_id=combined_audience_id, - ) - - @staticmethod - def parse_combined_audience_path(path: str) -> Dict[str, str]: - """Parses a combined_audience path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/combinedAudiences/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_theme_constant_path( - express_category_id: str, - express_sub_category_id: str, - ) -> str: - """Returns a fully-qualified keyword_theme_constant string.""" - return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( - express_category_id=express_category_id, - express_sub_category_id=express_sub_category_id, - ) - - @staticmethod - def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: - """Parses a keyword_theme_constant path into its component segments.""" - m = re.match( - r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def mobile_app_category_constant_path( - mobile_app_category_id: str, - ) -> str: - """Returns a fully-qualified mobile_app_category_constant string.""" - return "mobileAppCategoryConstants/{mobile_app_category_id}".format( - mobile_app_category_id=mobile_app_category_id, - ) - - @staticmethod - def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: - """Parses a mobile_app_category_constant path into its component segments.""" - m = re.match( - r"^mobileAppCategoryConstants/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def mobile_device_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified mobile_device_constant string.""" - return "mobileDeviceConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_mobile_device_constant_path(path: str) -> Dict[str, str]: - """Parses a mobile_device_constant path into its component segments.""" - m = re.match(r"^mobileDeviceConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def operating_system_version_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified operating_system_version_constant string.""" - return "operatingSystemVersionConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_operating_system_version_constant_path( - path: str, - ) -> Dict[str, str]: - """Parses a operating_system_version_constant path into its component segments.""" - m = re.match( - r"^operatingSystemVersionConstants/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def topic_constant_path( - topic_id: str, - ) -> str: - """Returns a fully-qualified topic_constant string.""" - return "topicConstants/{topic_id}".format( - topic_id=topic_id, - ) - - @staticmethod - def parse_topic_constant_path(path: str) -> Dict[str, str]: - """Parses a topic_constant path into its component segments.""" - m = re.match(r"^topicConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CampaignCriterionServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CampaignCriterionServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = CampaignCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignCriterionServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignCriterionServiceTransport, - Callable[..., CampaignCriterionServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign criterion service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignCriterionServiceTransport,Callable[..., CampaignCriterionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignCriterionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignCriterionServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignCriterionServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CampaignCriterionServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignCriterionServiceTransport - ) - if transport_provided: - # transport is a CampaignCriterionServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CampaignCriterionServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignCriterionServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignCriterionServiceTransport], - Callable[..., CampaignCriterionServiceTransport], - ] = ( - CampaignCriterionServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignCriterionServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignCriterionServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignCriterionService", - "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.ads.googleads.v19.services.CampaignCriterionService", - "credentialsType": None, - } - ), - ) - - def mutate_campaign_criteria( - self, - request: Optional[ - Union[ - campaign_criterion_service.MutateCampaignCriteriaRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_criterion_service.CampaignCriterionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_criterion_service.MutateCampaignCriteriaResponse: - r"""Creates, updates, or removes criteria. Operation statuses are - returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CampaignCriterionError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `FunctionError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RegionCodeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignCriteriaRequest, dict]): - The request object. Request message for - [CampaignCriterionService.MutateCampaignCriteria][google.ads.googleads.v19.services.CampaignCriterionService.MutateCampaignCriteria]. - customer_id (str): - Required. The ID of the customer - whose criteria are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignCriterionOperation]): - Required. The list of operations to - perform on individual criteria. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignCriteriaResponse: - Response message for campaign - criterion mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_criterion_service.MutateCampaignCriteriaRequest - ): - request = campaign_criterion_service.MutateCampaignCriteriaRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_campaign_criteria - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignCriterionServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignCriterionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_criterion_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_criterion_service/transports/base.py deleted file mode 100644 index 99c04b779..000000000 --- a/google/ads/googleads/v19/services/services/campaign_criterion_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import campaign_criterion_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignCriterionServiceTransport(abc.ABC): - """Abstract transport class for CampaignCriterionService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaign_criteria: gapic_v1.method.wrap_method( - self.mutate_campaign_criteria, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_campaign_criteria( - self, - ) -> Callable[ - [campaign_criterion_service.MutateCampaignCriteriaRequest], - Union[ - campaign_criterion_service.MutateCampaignCriteriaResponse, - Awaitable[ - campaign_criterion_service.MutateCampaignCriteriaResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignCriterionServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_criterion_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_criterion_service/transports/grpc.py deleted file mode 100644 index 308fe7663..000000000 --- a/google/ads/googleads/v19/services/services/campaign_criterion_service/transports/grpc.py +++ /dev/null @@ -1,396 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import campaign_criterion_service -from .base import CampaignCriterionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignCriterionService", - "rpcName": str(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.ads.googleads.v19.services.CampaignCriterionService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignCriterionServiceGrpcTransport(CampaignCriterionServiceTransport): - """gRPC backend transport for CampaignCriterionService. - - Service to manage campaign criteria. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_campaign_criteria( - self, - ) -> Callable[ - [campaign_criterion_service.MutateCampaignCriteriaRequest], - campaign_criterion_service.MutateCampaignCriteriaResponse, - ]: - r"""Return a callable for the mutate campaign criteria method over gRPC. - - Creates, updates, or removes criteria. Operation statuses are - returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CampaignCriterionError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `FunctionError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RegionCodeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateCampaignCriteriaRequest], - ~.MutateCampaignCriteriaResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_criteria" not in self._stubs: - self._stubs["mutate_campaign_criteria"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignCriterionService/MutateCampaignCriteria", - request_serializer=campaign_criterion_service.MutateCampaignCriteriaRequest.serialize, - response_deserializer=campaign_criterion_service.MutateCampaignCriteriaResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_criteria"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_criterion_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_criterion_service/transports/grpc_asyncio.py deleted file mode 100644 index 808f70284..000000000 --- a/google/ads/googleads/v19/services/services/campaign_criterion_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,419 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import campaign_criterion_service -from .base import CampaignCriterionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignCriterionService", - "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.ads.googleads.v19.services.CampaignCriterionService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignCriterionServiceGrpcAsyncIOTransport( - CampaignCriterionServiceTransport -): - """gRPC AsyncIO backend transport for CampaignCriterionService. - - Service to manage campaign criteria. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_campaign_criteria( - self, - ) -> Callable[ - [campaign_criterion_service.MutateCampaignCriteriaRequest], - Awaitable[campaign_criterion_service.MutateCampaignCriteriaResponse], - ]: - r"""Return a callable for the mutate campaign criteria method over gRPC. - - Creates, updates, or removes criteria. Operation statuses are - returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CampaignCriterionError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `FunctionError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperationAccessDeniedError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RegionCodeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateCampaignCriteriaRequest], - Awaitable[~.MutateCampaignCriteriaResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_criteria" not in self._stubs: - self._stubs["mutate_campaign_criteria"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignCriterionService/MutateCampaignCriteria", - request_serializer=campaign_criterion_service.MutateCampaignCriteriaRequest.serialize, - response_deserializer=campaign_criterion_service.MutateCampaignCriteriaResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_criteria"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaign_criteria: self._wrap_method( - self.mutate_campaign_criteria, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignCriterionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_customizer_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_customizer_service/async_client.py deleted file mode 100644 index 1f9a58287..000000000 --- a/google/ads/googleads/v19/services/services/campaign_customizer_service/async_client.py +++ /dev/null @@ -1,445 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import campaign_customizer_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CampaignCustomizerServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CampaignCustomizerServiceClient - -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 CampaignCustomizerServiceAsyncClient: - """Service to manage campaign customizer""" - - _client: CampaignCustomizerServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignCustomizerServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CampaignCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignCustomizerServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod(CampaignCustomizerServiceClient.campaign_path) - parse_campaign_path = staticmethod( - CampaignCustomizerServiceClient.parse_campaign_path - ) - campaign_customizer_path = staticmethod( - CampaignCustomizerServiceClient.campaign_customizer_path - ) - parse_campaign_customizer_path = staticmethod( - CampaignCustomizerServiceClient.parse_campaign_customizer_path - ) - customizer_attribute_path = staticmethod( - CampaignCustomizerServiceClient.customizer_attribute_path - ) - parse_customizer_attribute_path = staticmethod( - CampaignCustomizerServiceClient.parse_customizer_attribute_path - ) - common_billing_account_path = staticmethod( - CampaignCustomizerServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignCustomizerServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignCustomizerServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignCustomizerServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignCustomizerServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignCustomizerServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignCustomizerServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignCustomizerServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignCustomizerServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignCustomizerServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignCustomizerServiceAsyncClient: The constructed client. - """ - return CampaignCustomizerServiceClient.from_service_account_info.__func__(CampaignCustomizerServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignCustomizerServiceAsyncClient: The constructed client. - """ - return CampaignCustomizerServiceClient.from_service_account_file.__func__(CampaignCustomizerServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignCustomizerServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignCustomizerServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignCustomizerServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignCustomizerServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignCustomizerServiceTransport, - Callable[..., CampaignCustomizerServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign customizer service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignCustomizerServiceTransport,Callable[..., CampaignCustomizerServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignCustomizerServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignCustomizerServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignCustomizerServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignCustomizerService", - "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.ads.googleads.v19.services.CampaignCustomizerService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaign_customizers( - self, - request: Optional[ - Union[ - campaign_customizer_service.MutateCampaignCustomizersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_customizer_service.CampaignCustomizerOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_customizer_service.MutateCampaignCustomizersResponse: - r"""Creates, updates or removes campaign customizers. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignCustomizersRequest, dict]]): - The request object. Request message for - [CampaignCustomizerService.MutateCampaignCustomizers][google.ads.googleads.v19.services.CampaignCustomizerService.MutateCampaignCustomizers]. - customer_id (:class:`str`): - Required. The ID of the customer - whose campaign customizers are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignCustomizerOperation]`): - Required. The list of operations to - perform on individual campaign - customizers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignCustomizersResponse: - Response message for a campaign - customizer mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - campaign_customizer_service.MutateCampaignCustomizersRequest, - ): - request = ( - campaign_customizer_service.MutateCampaignCustomizersRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaign_customizers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignCustomizerServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignCustomizerServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_customizer_service/client.py b/google/ads/googleads/v19/services/services/campaign_customizer_service/client.py deleted file mode 100644 index e2f138ab9..000000000 --- a/google/ads/googleads/v19/services/services/campaign_customizer_service/client.py +++ /dev/null @@ -1,937 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import campaign_customizer_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CampaignCustomizerServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CampaignCustomizerServiceGrpcTransport -from .transports.grpc_asyncio import ( - CampaignCustomizerServiceGrpcAsyncIOTransport, -) - - -class CampaignCustomizerServiceClientMeta(type): - """Metaclass for the CampaignCustomizerService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignCustomizerServiceTransport]] - _transport_registry["grpc"] = CampaignCustomizerServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignCustomizerServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignCustomizerServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignCustomizerServiceClient( - metaclass=CampaignCustomizerServiceClientMeta -): - """Service to manage campaign customizer""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignCustomizerServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignCustomizerServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignCustomizerServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignCustomizerServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_customizer_path( - customer_id: str, - campaign_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified campaign_customizer string.""" - return "customers/{customer_id}/campaignCustomizers/{campaign_id}~{customizer_attribute_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_campaign_customizer_path(path: str) -> Dict[str, str]: - """Parses a campaign_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignCustomizers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customizer_attribute_path( - customer_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified customizer_attribute string.""" - return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( - customer_id=customer_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_customizer_attribute_path(path: str) -> Dict[str, str]: - """Parses a customizer_attribute path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CampaignCustomizerServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CampaignCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = CampaignCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignCustomizerServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignCustomizerServiceTransport, - Callable[..., CampaignCustomizerServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign customizer service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignCustomizerServiceTransport,Callable[..., CampaignCustomizerServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignCustomizerServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignCustomizerServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignCustomizerServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CampaignCustomizerServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignCustomizerServiceTransport - ) - if transport_provided: - # transport is a CampaignCustomizerServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CampaignCustomizerServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignCustomizerServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignCustomizerServiceTransport], - Callable[..., CampaignCustomizerServiceTransport], - ] = ( - CampaignCustomizerServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignCustomizerServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignCustomizerServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignCustomizerService", - "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.ads.googleads.v19.services.CampaignCustomizerService", - "credentialsType": None, - } - ), - ) - - def mutate_campaign_customizers( - self, - request: Optional[ - Union[ - campaign_customizer_service.MutateCampaignCustomizersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_customizer_service.CampaignCustomizerOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_customizer_service.MutateCampaignCustomizersResponse: - r"""Creates, updates or removes campaign customizers. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignCustomizersRequest, dict]): - The request object. Request message for - [CampaignCustomizerService.MutateCampaignCustomizers][google.ads.googleads.v19.services.CampaignCustomizerService.MutateCampaignCustomizers]. - customer_id (str): - Required. The ID of the customer - whose campaign customizers are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignCustomizerOperation]): - Required. The list of operations to - perform on individual campaign - customizers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignCustomizersResponse: - Response message for a campaign - customizer mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - campaign_customizer_service.MutateCampaignCustomizersRequest, - ): - request = ( - campaign_customizer_service.MutateCampaignCustomizersRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_campaign_customizers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignCustomizerServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignCustomizerServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_customizer_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_customizer_service/transports/base.py deleted file mode 100644 index 24ab3c3f5..000000000 --- a/google/ads/googleads/v19/services/services/campaign_customizer_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import campaign_customizer_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignCustomizerServiceTransport(abc.ABC): - """Abstract transport class for CampaignCustomizerService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaign_customizers: gapic_v1.method.wrap_method( - self.mutate_campaign_customizers, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_campaign_customizers( - self, - ) -> Callable[ - [campaign_customizer_service.MutateCampaignCustomizersRequest], - Union[ - campaign_customizer_service.MutateCampaignCustomizersResponse, - Awaitable[ - campaign_customizer_service.MutateCampaignCustomizersResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignCustomizerServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_customizer_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_customizer_service/transports/grpc.py deleted file mode 100644 index e5d09b203..000000000 --- a/google/ads/googleads/v19/services/services/campaign_customizer_service/transports/grpc.py +++ /dev/null @@ -1,384 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import campaign_customizer_service -from .base import CampaignCustomizerServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignCustomizerService", - "rpcName": str(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.ads.googleads.v19.services.CampaignCustomizerService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignCustomizerServiceGrpcTransport( - CampaignCustomizerServiceTransport -): - """gRPC backend transport for CampaignCustomizerService. - - Service to manage campaign customizer - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_campaign_customizers( - self, - ) -> Callable[ - [campaign_customizer_service.MutateCampaignCustomizersRequest], - campaign_customizer_service.MutateCampaignCustomizersResponse, - ]: - r"""Return a callable for the mutate campaign customizers method over gRPC. - - Creates, updates or removes campaign customizers. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCampaignCustomizersRequest], - ~.MutateCampaignCustomizersResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_customizers" not in self._stubs: - self._stubs["mutate_campaign_customizers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignCustomizerService/MutateCampaignCustomizers", - request_serializer=campaign_customizer_service.MutateCampaignCustomizersRequest.serialize, - response_deserializer=campaign_customizer_service.MutateCampaignCustomizersResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_customizers"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_customizer_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_customizer_service/transports/grpc_asyncio.py deleted file mode 100644 index f8cd26de9..000000000 --- a/google/ads/googleads/v19/services/services/campaign_customizer_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,407 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import campaign_customizer_service -from .base import CampaignCustomizerServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignCustomizerService", - "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.ads.googleads.v19.services.CampaignCustomizerService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignCustomizerServiceGrpcAsyncIOTransport( - CampaignCustomizerServiceTransport -): - """gRPC AsyncIO backend transport for CampaignCustomizerService. - - Service to manage campaign customizer - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_campaign_customizers( - self, - ) -> Callable[ - [campaign_customizer_service.MutateCampaignCustomizersRequest], - Awaitable[ - campaign_customizer_service.MutateCampaignCustomizersResponse - ], - ]: - r"""Return a callable for the mutate campaign customizers method over gRPC. - - Creates, updates or removes campaign customizers. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCampaignCustomizersRequest], - Awaitable[~.MutateCampaignCustomizersResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_customizers" not in self._stubs: - self._stubs["mutate_campaign_customizers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignCustomizerService/MutateCampaignCustomizers", - request_serializer=campaign_customizer_service.MutateCampaignCustomizersRequest.serialize, - response_deserializer=campaign_customizer_service.MutateCampaignCustomizersResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_customizers"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaign_customizers: self._wrap_method( - self.mutate_campaign_customizers, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignCustomizerServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_draft_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_draft_service/async_client.py deleted file mode 100644 index ad1916f79..000000000 --- a/google/ads/googleads/v19/services/services/campaign_draft_service/async_client.py +++ /dev/null @@ -1,680 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.services.campaign_draft_service import ( - pagers, -) -from google.ads.googleads.v19.services.types import campaign_draft_service -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignDraftServiceTransport, DEFAULT_CLIENT_INFO -from .client import CampaignDraftServiceClient - -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 CampaignDraftServiceAsyncClient: - """Service to manage campaign drafts.""" - - _client: CampaignDraftServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignDraftServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CampaignDraftServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignDraftServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignDraftServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod(CampaignDraftServiceClient.campaign_path) - parse_campaign_path = staticmethod( - CampaignDraftServiceClient.parse_campaign_path - ) - campaign_draft_path = staticmethod( - CampaignDraftServiceClient.campaign_draft_path - ) - parse_campaign_draft_path = staticmethod( - CampaignDraftServiceClient.parse_campaign_draft_path - ) - common_billing_account_path = staticmethod( - CampaignDraftServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignDraftServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignDraftServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignDraftServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignDraftServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignDraftServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignDraftServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignDraftServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignDraftServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignDraftServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignDraftServiceAsyncClient: The constructed client. - """ - return CampaignDraftServiceClient.from_service_account_info.__func__(CampaignDraftServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignDraftServiceAsyncClient: The constructed client. - """ - return CampaignDraftServiceClient.from_service_account_file.__func__(CampaignDraftServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignDraftServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignDraftServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignDraftServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignDraftServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignDraftServiceTransport, - Callable[..., CampaignDraftServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign draft service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignDraftServiceTransport,Callable[..., CampaignDraftServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignDraftServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignDraftServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignDraftServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignDraftService", - "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.ads.googleads.v19.services.CampaignDraftService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaign_drafts( - self, - request: Optional[ - Union[campaign_draft_service.MutateCampaignDraftsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_draft_service.CampaignDraftOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_draft_service.MutateCampaignDraftsResponse: - r"""Creates, updates, or removes campaign drafts. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignDraftError <>`__ - `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignDraftsRequest, dict]]): - The request object. Request message for - [CampaignDraftService.MutateCampaignDrafts][google.ads.googleads.v19.services.CampaignDraftService.MutateCampaignDrafts]. - customer_id (:class:`str`): - Required. The ID of the customer - whose campaign drafts are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignDraftOperation]`): - Required. The list of operations to - perform on individual campaign drafts. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignDraftsResponse: - Response message for campaign draft - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_draft_service.MutateCampaignDraftsRequest - ): - request = campaign_draft_service.MutateCampaignDraftsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaign_drafts - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def promote_campaign_draft( - self, - request: Optional[ - Union[campaign_draft_service.PromoteCampaignDraftRequest, dict] - ] = None, - *, - campaign_draft: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operation_async.AsyncOperation: - r"""Promotes the changes in a draft back to the base campaign. - - This method returns a Long Running Operation (LRO) indicating if - the Promote is done. Use [Operations.GetOperation] to poll the - LRO until it is done. Only a done status is returned in the - response. See the status in the Campaign Draft resource to - determine if the promotion was successful. If the LRO failed, - use - [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v19.services.CampaignDraftService.ListCampaignDraftAsyncErrors] - to view the list of error reasons. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignDraftError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.PromoteCampaignDraftRequest, dict]]): - The request object. Request message for - [CampaignDraftService.PromoteCampaignDraft][google.ads.googleads.v19.services.CampaignDraftService.PromoteCampaignDraft]. - campaign_draft (:class:`str`): - Required. The resource name of the - campaign draft to promote. - - This corresponds to the ``campaign_draft`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [campaign_draft] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_draft_service.PromoteCampaignDraftRequest - ): - request = campaign_draft_service.PromoteCampaignDraftRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if campaign_draft is not None: - request.campaign_draft = campaign_draft - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.promote_campaign_draft - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("campaign_draft", request.campaign_draft),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - empty_pb2.Empty, - metadata_type=empty_pb2.Empty, - ) - - # Done; return the response. - return response - - async def list_campaign_draft_async_errors( - self, - request: Optional[ - Union[ - campaign_draft_service.ListCampaignDraftAsyncErrorsRequest, dict - ] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListCampaignDraftAsyncErrorsAsyncPager: - r"""Returns all errors that occurred during CampaignDraft promote. - Throws an error if called before campaign draft is promoted. - Supports standard list paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ListCampaignDraftAsyncErrorsRequest, dict]]): - The request object. Request message for - [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v19.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. - resource_name (:class:`str`): - Required. The name of the campaign - draft from which to retrieve the async - errors. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.campaign_draft_service.pagers.ListCampaignDraftAsyncErrorsAsyncPager: - Response message for - [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v19.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_draft_service.ListCampaignDraftAsyncErrorsRequest - ): - request = ( - campaign_draft_service.ListCampaignDraftAsyncErrorsRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_campaign_draft_async_errors - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.ListCampaignDraftAsyncErrorsAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignDraftServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignDraftServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_draft_service/client.py b/google/ads/googleads/v19/services/services/campaign_draft_service/client.py deleted file mode 100644 index 47806f71b..000000000 --- a/google/ads/googleads/v19/services/services/campaign_draft_service/client.py +++ /dev/null @@ -1,1150 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.services.campaign_draft_service import ( - pagers, -) -from google.ads.googleads.v19.services.types import campaign_draft_service -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignDraftServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CampaignDraftServiceGrpcTransport -from .transports.grpc_asyncio import CampaignDraftServiceGrpcAsyncIOTransport - - -class CampaignDraftServiceClientMeta(type): - """Metaclass for the CampaignDraftService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignDraftServiceTransport]] - _transport_registry["grpc"] = CampaignDraftServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignDraftServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignDraftServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignDraftServiceClient(metaclass=CampaignDraftServiceClientMeta): - """Service to manage campaign drafts.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignDraftServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignDraftServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignDraftServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignDraftServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_draft_path( - customer_id: str, - base_campaign_id: str, - draft_id: str, - ) -> str: - """Returns a fully-qualified campaign_draft string.""" - return "customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}".format( - customer_id=customer_id, - base_campaign_id=base_campaign_id, - draft_id=draft_id, - ) - - @staticmethod - def parse_campaign_draft_path(path: str) -> Dict[str, str]: - """Parses a campaign_draft path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignDrafts/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CampaignDraftServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CampaignDraftServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CampaignDraftServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignDraftServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignDraftServiceTransport, - Callable[..., CampaignDraftServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign draft service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignDraftServiceTransport,Callable[..., CampaignDraftServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignDraftServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignDraftServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignDraftServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = CampaignDraftServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignDraftServiceTransport - ) - if transport_provided: - # transport is a CampaignDraftServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CampaignDraftServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignDraftServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignDraftServiceTransport], - Callable[..., CampaignDraftServiceTransport], - ] = ( - CampaignDraftServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignDraftServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignDraftServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignDraftService", - "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.ads.googleads.v19.services.CampaignDraftService", - "credentialsType": None, - } - ), - ) - - def mutate_campaign_drafts( - self, - request: Optional[ - Union[campaign_draft_service.MutateCampaignDraftsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_draft_service.CampaignDraftOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_draft_service.MutateCampaignDraftsResponse: - r"""Creates, updates, or removes campaign drafts. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignDraftError <>`__ - `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignDraftsRequest, dict]): - The request object. Request message for - [CampaignDraftService.MutateCampaignDrafts][google.ads.googleads.v19.services.CampaignDraftService.MutateCampaignDrafts]. - customer_id (str): - Required. The ID of the customer - whose campaign drafts are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignDraftOperation]): - Required. The list of operations to - perform on individual campaign drafts. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignDraftsResponse: - Response message for campaign draft - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_draft_service.MutateCampaignDraftsRequest - ): - request = campaign_draft_service.MutateCampaignDraftsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_campaign_drafts - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def promote_campaign_draft( - self, - request: Optional[ - Union[campaign_draft_service.PromoteCampaignDraftRequest, dict] - ] = None, - *, - campaign_draft: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operation.Operation: - r"""Promotes the changes in a draft back to the base campaign. - - This method returns a Long Running Operation (LRO) indicating if - the Promote is done. Use [Operations.GetOperation] to poll the - LRO until it is done. Only a done status is returned in the - response. See the status in the Campaign Draft resource to - determine if the promotion was successful. If the LRO failed, - use - [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v19.services.CampaignDraftService.ListCampaignDraftAsyncErrors] - to view the list of error reasons. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignDraftError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.PromoteCampaignDraftRequest, dict]): - The request object. Request message for - [CampaignDraftService.PromoteCampaignDraft][google.ads.googleads.v19.services.CampaignDraftService.PromoteCampaignDraft]. - campaign_draft (str): - Required. The resource name of the - campaign draft to promote. - - This corresponds to the ``campaign_draft`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [campaign_draft] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_draft_service.PromoteCampaignDraftRequest - ): - request = campaign_draft_service.PromoteCampaignDraftRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if campaign_draft is not None: - request.campaign_draft = campaign_draft - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.promote_campaign_draft - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("campaign_draft", request.campaign_draft),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - empty_pb2.Empty, - metadata_type=empty_pb2.Empty, - ) - - # Done; return the response. - return response - - def list_campaign_draft_async_errors( - self, - request: Optional[ - Union[ - campaign_draft_service.ListCampaignDraftAsyncErrorsRequest, dict - ] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListCampaignDraftAsyncErrorsPager: - r"""Returns all errors that occurred during CampaignDraft promote. - Throws an error if called before campaign draft is promoted. - Supports standard list paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ListCampaignDraftAsyncErrorsRequest, dict]): - The request object. Request message for - [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v19.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. - resource_name (str): - Required. The name of the campaign - draft from which to retrieve the async - errors. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.campaign_draft_service.pagers.ListCampaignDraftAsyncErrorsPager: - Response message for - [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v19.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_draft_service.ListCampaignDraftAsyncErrorsRequest - ): - request = ( - campaign_draft_service.ListCampaignDraftAsyncErrorsRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.list_campaign_draft_async_errors - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.ListCampaignDraftAsyncErrorsPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignDraftServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignDraftServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_draft_service/pagers.py b/google/ads/googleads/v19/services/services/campaign_draft_service/pagers.py deleted file mode 100644 index 633e8eb41..000000000 --- a/google/ads/googleads/v19/services/services/campaign_draft_service/pagers.py +++ /dev/null @@ -1,213 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import retry_async as retries_async -from typing import ( - Any, - AsyncIterator, - Awaitable, - Callable, - Sequence, - Tuple, - Iterator, - Union, -) - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] - OptionalAsyncRetry = Union[ - retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import campaign_draft_service -from google.rpc import status_pb2 # type: ignore - - -class ListCampaignDraftAsyncErrorsPager: - """A pager for iterating through ``list_campaign_draft_async_errors`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.ListCampaignDraftAsyncErrorsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``errors`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListCampaignDraftAsyncErrors`` requests and continue to iterate - through the ``errors`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.ListCampaignDraftAsyncErrorsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[ - ..., campaign_draft_service.ListCampaignDraftAsyncErrorsResponse - ], - request: campaign_draft_service.ListCampaignDraftAsyncErrorsRequest, - response: campaign_draft_service.ListCampaignDraftAsyncErrorsResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.ListCampaignDraftAsyncErrorsRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.ListCampaignDraftAsyncErrorsResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = ( - campaign_draft_service.ListCampaignDraftAsyncErrorsRequest(request) - ) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages( - self, - ) -> Iterator[campaign_draft_service.ListCampaignDraftAsyncErrorsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __iter__(self) -> Iterator[status_pb2.Status]: - for page in self.pages: - yield from page.errors - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) - - -class ListCampaignDraftAsyncErrorsAsyncPager: - """A pager for iterating through ``list_campaign_draft_async_errors`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.ListCampaignDraftAsyncErrorsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``errors`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListCampaignDraftAsyncErrors`` requests and continue to iterate - through the ``errors`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.ListCampaignDraftAsyncErrorsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[ - ..., - Awaitable[ - campaign_draft_service.ListCampaignDraftAsyncErrorsResponse - ], - ], - request: campaign_draft_service.ListCampaignDraftAsyncErrorsRequest, - response: campaign_draft_service.ListCampaignDraftAsyncErrorsResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.ListCampaignDraftAsyncErrorsRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.ListCampaignDraftAsyncErrorsResponse): - The initial response object. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = ( - campaign_draft_service.ListCampaignDraftAsyncErrorsRequest(request) - ) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages( - self, - ) -> AsyncIterator[ - campaign_draft_service.ListCampaignDraftAsyncErrorsResponse - ]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __aiter__(self) -> AsyncIterator[status_pb2.Status]: - async def async_generator(): - async for page in self.pages: - for response in page.errors: - yield response - - return async_generator() - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/campaign_draft_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_draft_service/transports/base.py deleted file mode 100644 index 707e84f0a..000000000 --- a/google/ads/googleads/v19/services/services/campaign_draft_service/transports/base.py +++ /dev/null @@ -1,211 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import campaign_draft_service -from google.longrunning import operations_pb2 # type: ignore - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignDraftServiceTransport(abc.ABC): - """Abstract transport class for CampaignDraftService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaign_drafts: gapic_v1.method.wrap_method( - self.mutate_campaign_drafts, - default_timeout=None, - client_info=client_info, - ), - self.promote_campaign_draft: gapic_v1.method.wrap_method( - self.promote_campaign_draft, - default_timeout=None, - client_info=client_info, - ), - self.list_campaign_draft_async_errors: gapic_v1.method.wrap_method( - self.list_campaign_draft_async_errors, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def operations_client(self): - """Return the client designed to process long-running operations.""" - raise NotImplementedError() - - @property - def mutate_campaign_drafts( - self, - ) -> Callable[ - [campaign_draft_service.MutateCampaignDraftsRequest], - Union[ - campaign_draft_service.MutateCampaignDraftsResponse, - Awaitable[campaign_draft_service.MutateCampaignDraftsResponse], - ], - ]: - raise NotImplementedError() - - @property - def promote_campaign_draft( - self, - ) -> Callable[ - [campaign_draft_service.PromoteCampaignDraftRequest], - Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], - ]: - raise NotImplementedError() - - @property - def list_campaign_draft_async_errors( - self, - ) -> Callable[ - [campaign_draft_service.ListCampaignDraftAsyncErrorsRequest], - Union[ - campaign_draft_service.ListCampaignDraftAsyncErrorsResponse, - Awaitable[ - campaign_draft_service.ListCampaignDraftAsyncErrorsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignDraftServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_draft_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_draft_service/transports/grpc.py deleted file mode 100644 index 23b41bae5..000000000 --- a/google/ads/googleads/v19/services/services/campaign_draft_service/transports/grpc.py +++ /dev/null @@ -1,490 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import operations_v1 -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import campaign_draft_service -from google.longrunning import operations_pb2 # type: ignore -from .base import CampaignDraftServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignDraftService", - "rpcName": str(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.ads.googleads.v19.services.CampaignDraftService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignDraftServiceGrpcTransport(CampaignDraftServiceTransport): - """gRPC backend transport for CampaignDraftService. - - Service to manage campaign drafts. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[operations_v1.OperationsClient] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # 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._logged_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def mutate_campaign_drafts( - self, - ) -> Callable[ - [campaign_draft_service.MutateCampaignDraftsRequest], - campaign_draft_service.MutateCampaignDraftsResponse, - ]: - r"""Return a callable for the mutate campaign drafts method over gRPC. - - Creates, updates, or removes campaign drafts. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignDraftError <>`__ - `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCampaignDraftsRequest], - ~.MutateCampaignDraftsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_drafts" not in self._stubs: - self._stubs["mutate_campaign_drafts"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignDraftService/MutateCampaignDrafts", - request_serializer=campaign_draft_service.MutateCampaignDraftsRequest.serialize, - response_deserializer=campaign_draft_service.MutateCampaignDraftsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_drafts"] - - @property - def promote_campaign_draft( - self, - ) -> Callable[ - [campaign_draft_service.PromoteCampaignDraftRequest], - operations_pb2.Operation, - ]: - r"""Return a callable for the promote campaign draft method over gRPC. - - Promotes the changes in a draft back to the base campaign. - - This method returns a Long Running Operation (LRO) indicating if - the Promote is done. Use [Operations.GetOperation] to poll the - LRO until it is done. Only a done status is returned in the - response. See the status in the Campaign Draft resource to - determine if the promotion was successful. If the LRO failed, - use - [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v19.services.CampaignDraftService.ListCampaignDraftAsyncErrors] - to view the list of error reasons. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignDraftError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.PromoteCampaignDraftRequest], - ~.Operation]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "promote_campaign_draft" not in self._stubs: - self._stubs["promote_campaign_draft"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignDraftService/PromoteCampaignDraft", - request_serializer=campaign_draft_service.PromoteCampaignDraftRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - ) - return self._stubs["promote_campaign_draft"] - - @property - def list_campaign_draft_async_errors( - self, - ) -> Callable[ - [campaign_draft_service.ListCampaignDraftAsyncErrorsRequest], - campaign_draft_service.ListCampaignDraftAsyncErrorsResponse, - ]: - r"""Return a callable for the list campaign draft async - errors method over gRPC. - - Returns all errors that occurred during CampaignDraft promote. - Throws an error if called before campaign draft is promoted. - Supports standard list paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListCampaignDraftAsyncErrorsRequest], - ~.ListCampaignDraftAsyncErrorsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_campaign_draft_async_errors" not in self._stubs: - self._stubs["list_campaign_draft_async_errors"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignDraftService/ListCampaignDraftAsyncErrors", - request_serializer=campaign_draft_service.ListCampaignDraftAsyncErrorsRequest.serialize, - response_deserializer=campaign_draft_service.ListCampaignDraftAsyncErrorsResponse.deserialize, - ) - ) - return self._stubs["list_campaign_draft_async_errors"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignDraftServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_draft_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_draft_service/transports/grpc_asyncio.py deleted file mode 100644 index 2f7e0eadc..000000000 --- a/google/ads/googleads/v19/services/services/campaign_draft_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,523 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.api_core import operations_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import campaign_draft_service -from google.longrunning import operations_pb2 # type: ignore -from .base import CampaignDraftServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignDraftService", - "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.ads.googleads.v19.services.CampaignDraftService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignDraftServiceGrpcAsyncIOTransport(CampaignDraftServiceTransport): - """gRPC AsyncIO backend transport for CampaignDraftService. - - Service to manage campaign drafts. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[ - operations_v1.OperationsAsyncClient - ] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsAsyncClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # 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._logged_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def mutate_campaign_drafts( - self, - ) -> Callable[ - [campaign_draft_service.MutateCampaignDraftsRequest], - Awaitable[campaign_draft_service.MutateCampaignDraftsResponse], - ]: - r"""Return a callable for the mutate campaign drafts method over gRPC. - - Creates, updates, or removes campaign drafts. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignDraftError <>`__ - `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCampaignDraftsRequest], - Awaitable[~.MutateCampaignDraftsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_drafts" not in self._stubs: - self._stubs["mutate_campaign_drafts"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignDraftService/MutateCampaignDrafts", - request_serializer=campaign_draft_service.MutateCampaignDraftsRequest.serialize, - response_deserializer=campaign_draft_service.MutateCampaignDraftsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_drafts"] - - @property - def promote_campaign_draft( - self, - ) -> Callable[ - [campaign_draft_service.PromoteCampaignDraftRequest], - Awaitable[operations_pb2.Operation], - ]: - r"""Return a callable for the promote campaign draft method over gRPC. - - Promotes the changes in a draft back to the base campaign. - - This method returns a Long Running Operation (LRO) indicating if - the Promote is done. Use [Operations.GetOperation] to poll the - LRO until it is done. Only a done status is returned in the - response. See the status in the Campaign Draft resource to - determine if the promotion was successful. If the LRO failed, - use - [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v19.services.CampaignDraftService.ListCampaignDraftAsyncErrors] - to view the list of error reasons. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignDraftError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.PromoteCampaignDraftRequest], - Awaitable[~.Operation]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "promote_campaign_draft" not in self._stubs: - self._stubs["promote_campaign_draft"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignDraftService/PromoteCampaignDraft", - request_serializer=campaign_draft_service.PromoteCampaignDraftRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - ) - return self._stubs["promote_campaign_draft"] - - @property - def list_campaign_draft_async_errors( - self, - ) -> Callable[ - [campaign_draft_service.ListCampaignDraftAsyncErrorsRequest], - Awaitable[campaign_draft_service.ListCampaignDraftAsyncErrorsResponse], - ]: - r"""Return a callable for the list campaign draft async - errors method over gRPC. - - Returns all errors that occurred during CampaignDraft promote. - Throws an error if called before campaign draft is promoted. - Supports standard list paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListCampaignDraftAsyncErrorsRequest], - Awaitable[~.ListCampaignDraftAsyncErrorsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_campaign_draft_async_errors" not in self._stubs: - self._stubs["list_campaign_draft_async_errors"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignDraftService/ListCampaignDraftAsyncErrors", - request_serializer=campaign_draft_service.ListCampaignDraftAsyncErrorsRequest.serialize, - response_deserializer=campaign_draft_service.ListCampaignDraftAsyncErrorsResponse.deserialize, - ) - ) - return self._stubs["list_campaign_draft_async_errors"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaign_drafts: self._wrap_method( - self.mutate_campaign_drafts, - default_timeout=None, - client_info=client_info, - ), - self.promote_campaign_draft: self._wrap_method( - self.promote_campaign_draft, - default_timeout=None, - client_info=client_info, - ), - self.list_campaign_draft_async_errors: self._wrap_method( - self.list_campaign_draft_async_errors, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignDraftServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_group_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_group_service/async_client.py deleted file mode 100644 index 9bd91485f..000000000 --- a/google/ads/googleads/v19/services/services/campaign_group_service/async_client.py +++ /dev/null @@ -1,421 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import campaign_group_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignGroupServiceTransport, DEFAULT_CLIENT_INFO -from .client import CampaignGroupServiceClient - -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 CampaignGroupServiceAsyncClient: - """Service to manage campaign groups.""" - - _client: CampaignGroupServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignGroupServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CampaignGroupServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignGroupServiceClient._DEFAULT_UNIVERSE - - campaign_group_path = staticmethod( - CampaignGroupServiceClient.campaign_group_path - ) - parse_campaign_group_path = staticmethod( - CampaignGroupServiceClient.parse_campaign_group_path - ) - common_billing_account_path = staticmethod( - CampaignGroupServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignGroupServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignGroupServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignGroupServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignGroupServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignGroupServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignGroupServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignGroupServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignGroupServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignGroupServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignGroupServiceAsyncClient: The constructed client. - """ - return CampaignGroupServiceClient.from_service_account_info.__func__(CampaignGroupServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignGroupServiceAsyncClient: The constructed client. - """ - return CampaignGroupServiceClient.from_service_account_file.__func__(CampaignGroupServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignGroupServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignGroupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignGroupServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignGroupServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignGroupServiceTransport, - Callable[..., CampaignGroupServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign group service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignGroupServiceTransport,Callable[..., CampaignGroupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignGroupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignGroupServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignGroupServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignGroupService", - "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.ads.googleads.v19.services.CampaignGroupService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaign_groups( - self, - request: Optional[ - Union[campaign_group_service.MutateCampaignGroupsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_group_service.CampaignGroupOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_group_service.MutateCampaignGroupsResponse: - r"""Creates, updates, or removes campaign groups. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignGroupsRequest, dict]]): - The request object. Request message for - [CampaignGroupService.MutateCampaignGroups][google.ads.googleads.v19.services.CampaignGroupService.MutateCampaignGroups]. - customer_id (:class:`str`): - Required. The ID of the customer - whose campaign groups are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignGroupOperation]`): - Required. The list of operations to - perform on individual campaign groups. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignGroupsResponse: - Response message for campaign group - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_group_service.MutateCampaignGroupsRequest - ): - request = campaign_group_service.MutateCampaignGroupsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaign_groups - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignGroupServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignGroupServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_group_service/client.py b/google/ads/googleads/v19/services/services/campaign_group_service/client.py deleted file mode 100644 index cd08c3f9d..000000000 --- a/google/ads/googleads/v19/services/services/campaign_group_service/client.py +++ /dev/null @@ -1,877 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import campaign_group_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignGroupServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CampaignGroupServiceGrpcTransport -from .transports.grpc_asyncio import CampaignGroupServiceGrpcAsyncIOTransport - - -class CampaignGroupServiceClientMeta(type): - """Metaclass for the CampaignGroupService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignGroupServiceTransport]] - _transport_registry["grpc"] = CampaignGroupServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignGroupServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignGroupServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignGroupServiceClient(metaclass=CampaignGroupServiceClientMeta): - """Service to manage campaign groups.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignGroupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignGroupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignGroupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignGroupServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_group_path( - customer_id: str, - campaign_group_id: str, - ) -> str: - """Returns a fully-qualified campaign_group string.""" - return ( - "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( - customer_id=customer_id, - campaign_group_id=campaign_group_id, - ) - ) - - @staticmethod - def parse_campaign_group_path(path: str) -> Dict[str, str]: - """Parses a campaign_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CampaignGroupServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CampaignGroupServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CampaignGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignGroupServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignGroupServiceTransport, - Callable[..., CampaignGroupServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign group service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignGroupServiceTransport,Callable[..., CampaignGroupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignGroupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignGroupServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignGroupServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = CampaignGroupServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignGroupServiceTransport - ) - if transport_provided: - # transport is a CampaignGroupServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CampaignGroupServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignGroupServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignGroupServiceTransport], - Callable[..., CampaignGroupServiceTransport], - ] = ( - CampaignGroupServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignGroupServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignGroupServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignGroupService", - "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.ads.googleads.v19.services.CampaignGroupService", - "credentialsType": None, - } - ), - ) - - def mutate_campaign_groups( - self, - request: Optional[ - Union[campaign_group_service.MutateCampaignGroupsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_group_service.CampaignGroupOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_group_service.MutateCampaignGroupsResponse: - r"""Creates, updates, or removes campaign groups. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignGroupsRequest, dict]): - The request object. Request message for - [CampaignGroupService.MutateCampaignGroups][google.ads.googleads.v19.services.CampaignGroupService.MutateCampaignGroups]. - customer_id (str): - Required. The ID of the customer - whose campaign groups are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignGroupOperation]): - Required. The list of operations to - perform on individual campaign groups. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignGroupsResponse: - Response message for campaign group - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_group_service.MutateCampaignGroupsRequest - ): - request = campaign_group_service.MutateCampaignGroupsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_campaign_groups - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignGroupServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignGroupServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_group_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_group_service/transports/base.py deleted file mode 100644 index 515f8c7f3..000000000 --- a/google/ads/googleads/v19/services/services/campaign_group_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import campaign_group_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignGroupServiceTransport(abc.ABC): - """Abstract transport class for CampaignGroupService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaign_groups: gapic_v1.method.wrap_method( - self.mutate_campaign_groups, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_campaign_groups( - self, - ) -> Callable[ - [campaign_group_service.MutateCampaignGroupsRequest], - Union[ - campaign_group_service.MutateCampaignGroupsResponse, - Awaitable[campaign_group_service.MutateCampaignGroupsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignGroupServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_group_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_group_service/transports/grpc.py deleted file mode 100644 index f3223a47f..000000000 --- a/google/ads/googleads/v19/services/services/campaign_group_service/transports/grpc.py +++ /dev/null @@ -1,382 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import campaign_group_service -from .base import CampaignGroupServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignGroupService", - "rpcName": str(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.ads.googleads.v19.services.CampaignGroupService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignGroupServiceGrpcTransport(CampaignGroupServiceTransport): - """gRPC backend transport for CampaignGroupService. - - Service to manage campaign groups. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_campaign_groups( - self, - ) -> Callable[ - [campaign_group_service.MutateCampaignGroupsRequest], - campaign_group_service.MutateCampaignGroupsResponse, - ]: - r"""Return a callable for the mutate campaign groups method over gRPC. - - Creates, updates, or removes campaign groups. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCampaignGroupsRequest], - ~.MutateCampaignGroupsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_groups" not in self._stubs: - self._stubs["mutate_campaign_groups"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignGroupService/MutateCampaignGroups", - request_serializer=campaign_group_service.MutateCampaignGroupsRequest.serialize, - response_deserializer=campaign_group_service.MutateCampaignGroupsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_groups"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_group_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_group_service/transports/grpc_asyncio.py deleted file mode 100644 index 06697d000..000000000 --- a/google/ads/googleads/v19/services/services/campaign_group_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,403 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import campaign_group_service -from .base import CampaignGroupServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignGroupService", - "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.ads.googleads.v19.services.CampaignGroupService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignGroupServiceGrpcAsyncIOTransport(CampaignGroupServiceTransport): - """gRPC AsyncIO backend transport for CampaignGroupService. - - Service to manage campaign groups. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_campaign_groups( - self, - ) -> Callable[ - [campaign_group_service.MutateCampaignGroupsRequest], - Awaitable[campaign_group_service.MutateCampaignGroupsResponse], - ]: - r"""Return a callable for the mutate campaign groups method over gRPC. - - Creates, updates, or removes campaign groups. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCampaignGroupsRequest], - Awaitable[~.MutateCampaignGroupsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_groups" not in self._stubs: - self._stubs["mutate_campaign_groups"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignGroupService/MutateCampaignGroups", - request_serializer=campaign_group_service.MutateCampaignGroupsRequest.serialize, - response_deserializer=campaign_group_service.MutateCampaignGroupsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_groups"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaign_groups: self._wrap_method( - self.mutate_campaign_groups, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignGroupServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_label_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_label_service/async_client.py deleted file mode 100644 index 6c7e243d5..000000000 --- a/google/ads/googleads/v19/services/services/campaign_label_service/async_client.py +++ /dev/null @@ -1,433 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import campaign_label_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignLabelServiceTransport, DEFAULT_CLIENT_INFO -from .client import CampaignLabelServiceClient - -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 CampaignLabelServiceAsyncClient: - """Service to manage labels on campaigns.""" - - _client: CampaignLabelServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignLabelServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CampaignLabelServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignLabelServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod(CampaignLabelServiceClient.campaign_path) - parse_campaign_path = staticmethod( - CampaignLabelServiceClient.parse_campaign_path - ) - campaign_label_path = staticmethod( - CampaignLabelServiceClient.campaign_label_path - ) - parse_campaign_label_path = staticmethod( - CampaignLabelServiceClient.parse_campaign_label_path - ) - label_path = staticmethod(CampaignLabelServiceClient.label_path) - parse_label_path = staticmethod(CampaignLabelServiceClient.parse_label_path) - common_billing_account_path = staticmethod( - CampaignLabelServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignLabelServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignLabelServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignLabelServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignLabelServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignLabelServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignLabelServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignLabelServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignLabelServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignLabelServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignLabelServiceAsyncClient: The constructed client. - """ - return CampaignLabelServiceClient.from_service_account_info.__func__(CampaignLabelServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignLabelServiceAsyncClient: The constructed client. - """ - return CampaignLabelServiceClient.from_service_account_file.__func__(CampaignLabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignLabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignLabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignLabelServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignLabelServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignLabelServiceTransport, - Callable[..., CampaignLabelServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign label service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignLabelServiceTransport,Callable[..., CampaignLabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignLabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignLabelServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignLabelServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignLabelService", - "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.ads.googleads.v19.services.CampaignLabelService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaign_labels( - self, - request: Optional[ - Union[campaign_label_service.MutateCampaignLabelsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_label_service.CampaignLabelOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_label_service.MutateCampaignLabelsResponse: - r"""Creates and removes campaign-label relationships. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignLabelsRequest, dict]]): - The request object. Request message for - [CampaignLabelService.MutateCampaignLabels][google.ads.googleads.v19.services.CampaignLabelService.MutateCampaignLabels]. - customer_id (:class:`str`): - Required. ID of the customer whose - campaign-label relationships are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignLabelOperation]`): - Required. The list of operations to - perform on campaign-label relationships. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignLabelsResponse: - Response message for a campaign - labels mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_label_service.MutateCampaignLabelsRequest - ): - request = campaign_label_service.MutateCampaignLabelsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaign_labels - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignLabelServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignLabelServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_label_service/client.py b/google/ads/googleads/v19/services/services/campaign_label_service/client.py deleted file mode 100644 index aa8ef0cd1..000000000 --- a/google/ads/googleads/v19/services/services/campaign_label_service/client.py +++ /dev/null @@ -1,922 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import campaign_label_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignLabelServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CampaignLabelServiceGrpcTransport -from .transports.grpc_asyncio import CampaignLabelServiceGrpcAsyncIOTransport - - -class CampaignLabelServiceClientMeta(type): - """Metaclass for the CampaignLabelService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignLabelServiceTransport]] - _transport_registry["grpc"] = CampaignLabelServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignLabelServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignLabelServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignLabelServiceClient(metaclass=CampaignLabelServiceClientMeta): - """Service to manage labels on campaigns.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignLabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignLabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignLabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignLabelServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_label_path( - customer_id: str, - campaign_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified campaign_label string.""" - return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - label_id=label_id, - ) - - @staticmethod - def parse_campaign_label_path(path: str) -> Dict[str, str]: - """Parses a campaign_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def label_path( - customer_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified label string.""" - return "customers/{customer_id}/labels/{label_id}".format( - customer_id=customer_id, - label_id=label_id, - ) - - @staticmethod - def parse_label_path(path: str) -> Dict[str, str]: - """Parses a label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/labels/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CampaignLabelServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CampaignLabelServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CampaignLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignLabelServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignLabelServiceTransport, - Callable[..., CampaignLabelServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign label service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignLabelServiceTransport,Callable[..., CampaignLabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignLabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignLabelServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignLabelServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = CampaignLabelServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignLabelServiceTransport - ) - if transport_provided: - # transport is a CampaignLabelServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CampaignLabelServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignLabelServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignLabelServiceTransport], - Callable[..., CampaignLabelServiceTransport], - ] = ( - CampaignLabelServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignLabelServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignLabelServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignLabelService", - "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.ads.googleads.v19.services.CampaignLabelService", - "credentialsType": None, - } - ), - ) - - def mutate_campaign_labels( - self, - request: Optional[ - Union[campaign_label_service.MutateCampaignLabelsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_label_service.CampaignLabelOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_label_service.MutateCampaignLabelsResponse: - r"""Creates and removes campaign-label relationships. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignLabelsRequest, dict]): - The request object. Request message for - [CampaignLabelService.MutateCampaignLabels][google.ads.googleads.v19.services.CampaignLabelService.MutateCampaignLabels]. - customer_id (str): - Required. ID of the customer whose - campaign-label relationships are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignLabelOperation]): - Required. The list of operations to - perform on campaign-label relationships. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignLabelsResponse: - Response message for a campaign - labels mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_label_service.MutateCampaignLabelsRequest - ): - request = campaign_label_service.MutateCampaignLabelsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_campaign_labels - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignLabelServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignLabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_label_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_label_service/transports/base.py deleted file mode 100644 index 994d9bbed..000000000 --- a/google/ads/googleads/v19/services/services/campaign_label_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import campaign_label_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignLabelServiceTransport(abc.ABC): - """Abstract transport class for CampaignLabelService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaign_labels: gapic_v1.method.wrap_method( - self.mutate_campaign_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_campaign_labels( - self, - ) -> Callable[ - [campaign_label_service.MutateCampaignLabelsRequest], - Union[ - campaign_label_service.MutateCampaignLabelsResponse, - Awaitable[campaign_label_service.MutateCampaignLabelsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignLabelServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_label_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_label_service/transports/grpc.py deleted file mode 100644 index 6676f4c66..000000000 --- a/google/ads/googleads/v19/services/services/campaign_label_service/transports/grpc.py +++ /dev/null @@ -1,388 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import campaign_label_service -from .base import CampaignLabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignLabelService", - "rpcName": str(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.ads.googleads.v19.services.CampaignLabelService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignLabelServiceGrpcTransport(CampaignLabelServiceTransport): - """gRPC backend transport for CampaignLabelService. - - Service to manage labels on campaigns. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_campaign_labels( - self, - ) -> Callable[ - [campaign_label_service.MutateCampaignLabelsRequest], - campaign_label_service.MutateCampaignLabelsResponse, - ]: - r"""Return a callable for the mutate campaign labels method over gRPC. - - Creates and removes campaign-label relationships. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateCampaignLabelsRequest], - ~.MutateCampaignLabelsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_labels" not in self._stubs: - self._stubs["mutate_campaign_labels"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignLabelService/MutateCampaignLabels", - request_serializer=campaign_label_service.MutateCampaignLabelsRequest.serialize, - response_deserializer=campaign_label_service.MutateCampaignLabelsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_labels"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_label_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_label_service/transports/grpc_asyncio.py deleted file mode 100644 index 6091a0c4b..000000000 --- a/google/ads/googleads/v19/services/services/campaign_label_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import campaign_label_service -from .base import CampaignLabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignLabelService", - "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.ads.googleads.v19.services.CampaignLabelService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignLabelServiceGrpcAsyncIOTransport(CampaignLabelServiceTransport): - """gRPC AsyncIO backend transport for CampaignLabelService. - - Service to manage labels on campaigns. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_campaign_labels( - self, - ) -> Callable[ - [campaign_label_service.MutateCampaignLabelsRequest], - Awaitable[campaign_label_service.MutateCampaignLabelsResponse], - ]: - r"""Return a callable for the mutate campaign labels method over gRPC. - - Creates and removes campaign-label relationships. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateCampaignLabelsRequest], - Awaitable[~.MutateCampaignLabelsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_labels" not in self._stubs: - self._stubs["mutate_campaign_labels"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignLabelService/MutateCampaignLabels", - request_serializer=campaign_label_service.MutateCampaignLabelsRequest.serialize, - response_deserializer=campaign_label_service.MutateCampaignLabelsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_labels"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaign_labels: self._wrap_method( - self.mutate_campaign_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignLabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/async_client.py deleted file mode 100644 index acaa29c70..000000000 --- a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/async_client.py +++ /dev/null @@ -1,442 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - campaign_lifecycle_goal_service, -) -from .transports.base import ( - CampaignLifecycleGoalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CampaignLifecycleGoalServiceClient - -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 CampaignLifecycleGoalServiceAsyncClient: - """Service to configure campaign lifecycle goals.""" - - _client: CampaignLifecycleGoalServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignLifecycleGoalServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CampaignLifecycleGoalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignLifecycleGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignLifecycleGoalServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod( - CampaignLifecycleGoalServiceClient.campaign_path - ) - parse_campaign_path = staticmethod( - CampaignLifecycleGoalServiceClient.parse_campaign_path - ) - campaign_lifecycle_goal_path = staticmethod( - CampaignLifecycleGoalServiceClient.campaign_lifecycle_goal_path - ) - parse_campaign_lifecycle_goal_path = staticmethod( - CampaignLifecycleGoalServiceClient.parse_campaign_lifecycle_goal_path - ) - common_billing_account_path = staticmethod( - CampaignLifecycleGoalServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignLifecycleGoalServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignLifecycleGoalServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignLifecycleGoalServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignLifecycleGoalServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignLifecycleGoalServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignLifecycleGoalServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignLifecycleGoalServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignLifecycleGoalServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignLifecycleGoalServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignLifecycleGoalServiceAsyncClient: The constructed client. - """ - return CampaignLifecycleGoalServiceClient.from_service_account_info.__func__(CampaignLifecycleGoalServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignLifecycleGoalServiceAsyncClient: The constructed client. - """ - return CampaignLifecycleGoalServiceClient.from_service_account_file.__func__(CampaignLifecycleGoalServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignLifecycleGoalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignLifecycleGoalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignLifecycleGoalServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignLifecycleGoalServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignLifecycleGoalServiceTransport, - Callable[..., CampaignLifecycleGoalServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign lifecycle goal service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignLifecycleGoalServiceTransport,Callable[..., CampaignLifecycleGoalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignLifecycleGoalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignLifecycleGoalServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignLifecycleGoalServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignLifecycleGoalService", - "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.ads.googleads.v19.services.CampaignLifecycleGoalService", - "credentialsType": None, - } - ), - ) - - async def configure_campaign_lifecycle_goals( - self, - request: Optional[ - Union[ - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - campaign_lifecycle_goal_service.CampaignLifecycleGoalOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse - ): - r"""Process the given campaign lifecycle configurations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `CampaignLifecycleGoalConfigError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ConfigureCampaignLifecycleGoalsRequest, dict]]): - The request object. Request message for - [CampaignLifecycleGoalService.configureCampaignLifecycleGoals][]. - customer_id (:class:`str`): - Required. The ID of the customer - performing the upload. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (:class:`google.ads.googleads.v19.services.types.CampaignLifecycleGoalOperation`): - Required. The operation to perform - campaign lifecycle goal update. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ConfigureCampaignLifecycleGoalsResponse: - Response message for - [CampaignLifecycleGoalService.configureCampaignLifecycleGoals][]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest, - ): - request = campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.configure_campaign_lifecycle_goals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignLifecycleGoalServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignLifecycleGoalServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/client.py b/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/client.py deleted file mode 100644 index bd4485982..000000000 --- a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/client.py +++ /dev/null @@ -1,911 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - campaign_lifecycle_goal_service, -) -from .transports.base import ( - CampaignLifecycleGoalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CampaignLifecycleGoalServiceGrpcTransport -from .transports.grpc_asyncio import ( - CampaignLifecycleGoalServiceGrpcAsyncIOTransport, -) - - -class CampaignLifecycleGoalServiceClientMeta(type): - """Metaclass for the CampaignLifecycleGoalService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignLifecycleGoalServiceTransport]] - _transport_registry["grpc"] = CampaignLifecycleGoalServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignLifecycleGoalServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignLifecycleGoalServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignLifecycleGoalServiceClient( - metaclass=CampaignLifecycleGoalServiceClientMeta -): - """Service to configure campaign lifecycle goals.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignLifecycleGoalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignLifecycleGoalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignLifecycleGoalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignLifecycleGoalServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_lifecycle_goal_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign_lifecycle_goal string.""" - return "customers/{customer_id}/campaignLifecycleGoals/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_lifecycle_goal_path(path: str) -> Dict[str, str]: - """Parses a campaign_lifecycle_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignLifecycleGoals/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CampaignLifecycleGoalServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - CampaignLifecycleGoalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = CampaignLifecycleGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignLifecycleGoalServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignLifecycleGoalServiceTransport, - Callable[..., CampaignLifecycleGoalServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign lifecycle goal service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignLifecycleGoalServiceTransport,Callable[..., CampaignLifecycleGoalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignLifecycleGoalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignLifecycleGoalServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignLifecycleGoalServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CampaignLifecycleGoalServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignLifecycleGoalServiceTransport - ) - if transport_provided: - # transport is a CampaignLifecycleGoalServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CampaignLifecycleGoalServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignLifecycleGoalServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignLifecycleGoalServiceTransport], - Callable[..., CampaignLifecycleGoalServiceTransport], - ] = ( - CampaignLifecycleGoalServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignLifecycleGoalServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignLifecycleGoalServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignLifecycleGoalService", - "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.ads.googleads.v19.services.CampaignLifecycleGoalService", - "credentialsType": None, - } - ), - ) - - def configure_campaign_lifecycle_goals( - self, - request: Optional[ - Union[ - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - campaign_lifecycle_goal_service.CampaignLifecycleGoalOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse - ): - r"""Process the given campaign lifecycle configurations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `CampaignLifecycleGoalConfigError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ConfigureCampaignLifecycleGoalsRequest, dict]): - The request object. Request message for - [CampaignLifecycleGoalService.configureCampaignLifecycleGoals][]. - customer_id (str): - Required. The ID of the customer - performing the upload. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (google.ads.googleads.v19.services.types.CampaignLifecycleGoalOperation): - Required. The operation to perform - campaign lifecycle goal update. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ConfigureCampaignLifecycleGoalsResponse: - Response message for - [CampaignLifecycleGoalService.configureCampaignLifecycleGoals][]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest, - ): - request = campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.configure_campaign_lifecycle_goals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignLifecycleGoalServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignLifecycleGoalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/base.py deleted file mode 100644 index cf2690167..000000000 --- a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - campaign_lifecycle_goal_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignLifecycleGoalServiceTransport(abc.ABC): - """Abstract transport class for CampaignLifecycleGoalService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.configure_campaign_lifecycle_goals: gapic_v1.method.wrap_method( - self.configure_campaign_lifecycle_goals, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def configure_campaign_lifecycle_goals( - self, - ) -> Callable[ - [ - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest - ], - Union[ - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse, - Awaitable[ - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignLifecycleGoalServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/grpc.py deleted file mode 100644 index 9f87ae855..000000000 --- a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/grpc.py +++ /dev/null @@ -1,393 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - campaign_lifecycle_goal_service, -) -from .base import CampaignLifecycleGoalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignLifecycleGoalService", - "rpcName": str(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.ads.googleads.v19.services.CampaignLifecycleGoalService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignLifecycleGoalServiceGrpcTransport( - CampaignLifecycleGoalServiceTransport -): - """gRPC backend transport for CampaignLifecycleGoalService. - - Service to configure campaign lifecycle goals. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def configure_campaign_lifecycle_goals( - self, - ) -> Callable[ - [ - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest - ], - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse, - ]: - r"""Return a callable for the configure campaign lifecycle - goals method over gRPC. - - Process the given campaign lifecycle configurations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `CampaignLifecycleGoalConfigError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ConfigureCampaignLifecycleGoalsRequest], - ~.ConfigureCampaignLifecycleGoalsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "configure_campaign_lifecycle_goals" not in self._stubs: - self._stubs["configure_campaign_lifecycle_goals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignLifecycleGoalService/ConfigureCampaignLifecycleGoals", - request_serializer=campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest.serialize, - response_deserializer=campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse.deserialize, - ) - ) - return self._stubs["configure_campaign_lifecycle_goals"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignLifecycleGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/grpc_asyncio.py deleted file mode 100644 index 130c27ccb..000000000 --- a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,416 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - campaign_lifecycle_goal_service, -) -from .base import CampaignLifecycleGoalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignLifecycleGoalService", - "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.ads.googleads.v19.services.CampaignLifecycleGoalService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignLifecycleGoalServiceGrpcAsyncIOTransport( - CampaignLifecycleGoalServiceTransport -): - """gRPC AsyncIO backend transport for CampaignLifecycleGoalService. - - Service to configure campaign lifecycle goals. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def configure_campaign_lifecycle_goals( - self, - ) -> Callable[ - [ - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest - ], - Awaitable[ - campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse - ], - ]: - r"""Return a callable for the configure campaign lifecycle - goals method over gRPC. - - Process the given campaign lifecycle configurations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `CampaignLifecycleGoalConfigError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ConfigureCampaignLifecycleGoalsRequest], - Awaitable[~.ConfigureCampaignLifecycleGoalsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "configure_campaign_lifecycle_goals" not in self._stubs: - self._stubs["configure_campaign_lifecycle_goals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignLifecycleGoalService/ConfigureCampaignLifecycleGoals", - request_serializer=campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest.serialize, - response_deserializer=campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse.deserialize, - ) - ) - return self._stubs["configure_campaign_lifecycle_goals"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.configure_campaign_lifecycle_goals: self._wrap_method( - self.configure_campaign_lifecycle_goals, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignLifecycleGoalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_service/async_client.py deleted file mode 100644 index a0f8f4921..000000000 --- a/google/ads/googleads/v19/services/services/campaign_service/async_client.py +++ /dev/null @@ -1,579 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import campaign_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignServiceTransport, DEFAULT_CLIENT_INFO -from .client import CampaignServiceClient - -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 CampaignServiceAsyncClient: - """Service to manage campaigns.""" - - _client: CampaignServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CampaignServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignServiceClient._DEFAULT_UNIVERSE - - accessible_bidding_strategy_path = staticmethod( - CampaignServiceClient.accessible_bidding_strategy_path - ) - parse_accessible_bidding_strategy_path = staticmethod( - CampaignServiceClient.parse_accessible_bidding_strategy_path - ) - asset_set_path = staticmethod(CampaignServiceClient.asset_set_path) - parse_asset_set_path = staticmethod( - CampaignServiceClient.parse_asset_set_path - ) - bidding_strategy_path = staticmethod( - CampaignServiceClient.bidding_strategy_path - ) - parse_bidding_strategy_path = staticmethod( - CampaignServiceClient.parse_bidding_strategy_path - ) - campaign_path = staticmethod(CampaignServiceClient.campaign_path) - parse_campaign_path = staticmethod( - CampaignServiceClient.parse_campaign_path - ) - campaign_budget_path = staticmethod( - CampaignServiceClient.campaign_budget_path - ) - parse_campaign_budget_path = staticmethod( - CampaignServiceClient.parse_campaign_budget_path - ) - campaign_group_path = staticmethod( - CampaignServiceClient.campaign_group_path - ) - parse_campaign_group_path = staticmethod( - CampaignServiceClient.parse_campaign_group_path - ) - campaign_label_path = staticmethod( - CampaignServiceClient.campaign_label_path - ) - parse_campaign_label_path = staticmethod( - CampaignServiceClient.parse_campaign_label_path - ) - conversion_action_path = staticmethod( - CampaignServiceClient.conversion_action_path - ) - parse_conversion_action_path = staticmethod( - CampaignServiceClient.parse_conversion_action_path - ) - common_billing_account_path = staticmethod( - CampaignServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(CampaignServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - CampaignServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignServiceAsyncClient: The constructed client. - """ - return CampaignServiceClient.from_service_account_info.__func__(CampaignServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignServiceAsyncClient: The constructed client. - """ - return CampaignServiceClient.from_service_account_file.__func__(CampaignServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignServiceTransport, - Callable[..., CampaignServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignServiceTransport,Callable[..., CampaignServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignService", - "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.ads.googleads.v19.services.CampaignService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaigns( - self, - request: Optional[ - Union[campaign_service.MutateCampaignsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_service.CampaignOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_service.MutateCampaignsResponse: - r"""Creates, updates, or removes campaigns. Operation statuses are - returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `CampaignBudgetError <>`__ `CampaignError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DateRangeError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `ListOperationError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RegionCodeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignsRequest, dict]]): - The request object. Request message for - [CampaignService.MutateCampaigns][google.ads.googleads.v19.services.CampaignService.MutateCampaigns]. - customer_id (:class:`str`): - Required. The ID of the customer - whose campaigns are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignOperation]`): - Required. The list of operations to - perform on individual campaigns. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignsResponse: - Response message for campaign mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, campaign_service.MutateCampaignsRequest): - request = campaign_service.MutateCampaignsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaigns - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def enable_p_max_brand_guidelines( - self, - request: Optional[ - Union[campaign_service.EnablePMaxBrandGuidelinesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_service.EnableOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_service.EnablePMaxBrandGuidelinesResponse: - r"""Enables Brand Guidelines for Performance Max campaigns. - - List of thrown errors: `AuthenticationError <>`__ - `AssetError <>`__ `AssetLinkError <>`__ - `AuthorizationError <>`__ `BrandGuidelinesMigrationError <>`__ - `CampaignError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.EnablePMaxBrandGuidelinesRequest, dict]]): - The request object. Request to enable Brand Guidelines - for a Performance Max campaign. - customer_id (:class:`str`): - Required. The ID of the customer - whose campaigns are being enabled. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.EnableOperation]`): - Required. The list of individual - campaign operations. A maximum of 10 - enable operations can be executed in a - request. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.EnablePMaxBrandGuidelinesResponse: - Brand Guidelines campaign enablement - response. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_service.EnablePMaxBrandGuidelinesRequest - ): - request = campaign_service.EnablePMaxBrandGuidelinesRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.enable_p_max_brand_guidelines - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_service/client.py b/google/ads/googleads/v19/services/services/campaign_service/client.py deleted file mode 100644 index c0bc22856..000000000 --- a/google/ads/googleads/v19/services/services/campaign_service/client.py +++ /dev/null @@ -1,1132 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import campaign_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CampaignServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CampaignServiceGrpcTransport -from .transports.grpc_asyncio import CampaignServiceGrpcAsyncIOTransport - - -class CampaignServiceClientMeta(type): - """Metaclass for the CampaignService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignServiceTransport]] - _transport_registry["grpc"] = CampaignServiceGrpcTransport - _transport_registry["grpc_asyncio"] = CampaignServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignServiceClient(metaclass=CampaignServiceClientMeta): - """Service to manage campaigns.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def accessible_bidding_strategy_path( - customer_id: str, - bidding_strategy_id: str, - ) -> str: - """Returns a fully-qualified accessible_bidding_strategy string.""" - return "customers/{customer_id}/accessibleBiddingStrategies/{bidding_strategy_id}".format( - customer_id=customer_id, - bidding_strategy_id=bidding_strategy_id, - ) - - @staticmethod - def parse_accessible_bidding_strategy_path(path: str) -> Dict[str, str]: - """Parses a accessible_bidding_strategy path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/accessibleBiddingStrategies/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_set_path( - customer_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified asset_set string.""" - return "customers/{customer_id}/assetSets/{asset_set_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_asset_set_path(path: str) -> Dict[str, str]: - """Parses a asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def bidding_strategy_path( - customer_id: str, - bidding_strategy_id: str, - ) -> str: - """Returns a fully-qualified bidding_strategy string.""" - return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( - customer_id=customer_id, - bidding_strategy_id=bidding_strategy_id, - ) - - @staticmethod - def parse_bidding_strategy_path(path: str) -> Dict[str, str]: - """Parses a bidding_strategy path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_budget_path( - customer_id: str, - campaign_budget_id: str, - ) -> str: - """Returns a fully-qualified campaign_budget string.""" - return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( - customer_id=customer_id, - campaign_budget_id=campaign_budget_id, - ) - - @staticmethod - def parse_campaign_budget_path(path: str) -> Dict[str, str]: - """Parses a campaign_budget path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_group_path( - customer_id: str, - campaign_group_id: str, - ) -> str: - """Returns a fully-qualified campaign_group string.""" - return ( - "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( - customer_id=customer_id, - campaign_group_id=campaign_group_id, - ) - ) - - @staticmethod - def parse_campaign_group_path(path: str) -> Dict[str, str]: - """Parses a campaign_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_label_path( - customer_id: str, - campaign_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified campaign_label string.""" - return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - label_id=label_id, - ) - - @staticmethod - def parse_campaign_label_path(path: str) -> Dict[str, str]: - """Parses a campaign_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_action_path( - customer_id: str, - conversion_action_id: str, - ) -> str: - """Returns a fully-qualified conversion_action string.""" - return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( - customer_id=customer_id, - conversion_action_id=conversion_action_id, - ) - - @staticmethod - def parse_conversion_action_path(path: str) -> Dict[str, str]: - """Parses a conversion_action path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionActions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CampaignServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CampaignServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CampaignServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignServiceTransport, - Callable[..., CampaignServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignServiceTransport,Callable[..., CampaignServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = CampaignServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, CampaignServiceTransport) - if transport_provided: - # transport is a CampaignServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CampaignServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignServiceTransport], - Callable[..., CampaignServiceTransport], - ] = ( - CampaignServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., CampaignServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignService", - "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.ads.googleads.v19.services.CampaignService", - "credentialsType": None, - } - ), - ) - - def mutate_campaigns( - self, - request: Optional[ - Union[campaign_service.MutateCampaignsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_service.CampaignOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_service.MutateCampaignsResponse: - r"""Creates, updates, or removes campaigns. Operation statuses are - returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `CampaignBudgetError <>`__ `CampaignError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DateRangeError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `ListOperationError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RegionCodeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignsRequest, dict]): - The request object. Request message for - [CampaignService.MutateCampaigns][google.ads.googleads.v19.services.CampaignService.MutateCampaigns]. - customer_id (str): - Required. The ID of the customer - whose campaigns are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignOperation]): - Required. The list of operations to - perform on individual campaigns. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignsResponse: - Response message for campaign mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, campaign_service.MutateCampaignsRequest): - request = campaign_service.MutateCampaignsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.mutate_campaigns] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def enable_p_max_brand_guidelines( - self, - request: Optional[ - Union[campaign_service.EnablePMaxBrandGuidelinesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[campaign_service.EnableOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_service.EnablePMaxBrandGuidelinesResponse: - r"""Enables Brand Guidelines for Performance Max campaigns. - - List of thrown errors: `AuthenticationError <>`__ - `AssetError <>`__ `AssetLinkError <>`__ - `AuthorizationError <>`__ `BrandGuidelinesMigrationError <>`__ - `CampaignError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.EnablePMaxBrandGuidelinesRequest, dict]): - The request object. Request to enable Brand Guidelines - for a Performance Max campaign. - customer_id (str): - Required. The ID of the customer - whose campaigns are being enabled. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.EnableOperation]): - Required. The list of individual - campaign operations. A maximum of 10 - enable operations can be executed in a - request. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.EnablePMaxBrandGuidelinesResponse: - Brand Guidelines campaign enablement - response. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_service.EnablePMaxBrandGuidelinesRequest - ): - request = campaign_service.EnablePMaxBrandGuidelinesRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.enable_p_max_brand_guidelines - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_service/transports/base.py deleted file mode 100644 index f759ffc90..000000000 --- a/google/ads/googleads/v19/services/services/campaign_service/transports/base.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import campaign_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignServiceTransport(abc.ABC): - """Abstract transport class for CampaignService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaigns: gapic_v1.method.wrap_method( - self.mutate_campaigns, - default_timeout=None, - client_info=client_info, - ), - self.enable_p_max_brand_guidelines: gapic_v1.method.wrap_method( - self.enable_p_max_brand_guidelines, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_campaigns( - self, - ) -> Callable[ - [campaign_service.MutateCampaignsRequest], - Union[ - campaign_service.MutateCampaignsResponse, - Awaitable[campaign_service.MutateCampaignsResponse], - ], - ]: - raise NotImplementedError() - - @property - def enable_p_max_brand_guidelines( - self, - ) -> Callable[ - [campaign_service.EnablePMaxBrandGuidelinesRequest], - Union[ - campaign_service.EnablePMaxBrandGuidelinesResponse, - Awaitable[campaign_service.EnablePMaxBrandGuidelinesResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_service/transports/grpc.py deleted file mode 100644 index 1bae3aa60..000000000 --- a/google/ads/googleads/v19/services/services/campaign_service/transports/grpc.py +++ /dev/null @@ -1,435 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import campaign_service -from .base import CampaignServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignService", - "rpcName": str(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.ads.googleads.v19.services.CampaignService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignServiceGrpcTransport(CampaignServiceTransport): - """gRPC backend transport for CampaignService. - - Service to manage campaigns. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_campaigns( - self, - ) -> Callable[ - [campaign_service.MutateCampaignsRequest], - campaign_service.MutateCampaignsResponse, - ]: - r"""Return a callable for the mutate campaigns method over gRPC. - - Creates, updates, or removes campaigns. Operation statuses are - returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `CampaignBudgetError <>`__ `CampaignError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DateRangeError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `ListOperationError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RegionCodeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateCampaignsRequest], - ~.MutateCampaignsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaigns" not in self._stubs: - self._stubs["mutate_campaigns"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignService/MutateCampaigns", - request_serializer=campaign_service.MutateCampaignsRequest.serialize, - response_deserializer=campaign_service.MutateCampaignsResponse.deserialize, - ) - return self._stubs["mutate_campaigns"] - - @property - def enable_p_max_brand_guidelines( - self, - ) -> Callable[ - [campaign_service.EnablePMaxBrandGuidelinesRequest], - campaign_service.EnablePMaxBrandGuidelinesResponse, - ]: - r"""Return a callable for the enable p max brand guidelines method over gRPC. - - Enables Brand Guidelines for Performance Max campaigns. - - List of thrown errors: `AuthenticationError <>`__ - `AssetError <>`__ `AssetLinkError <>`__ - `AuthorizationError <>`__ `BrandGuidelinesMigrationError <>`__ - `CampaignError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.EnablePMaxBrandGuidelinesRequest], - ~.EnablePMaxBrandGuidelinesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "enable_p_max_brand_guidelines" not in self._stubs: - self._stubs["enable_p_max_brand_guidelines"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignService/EnablePMaxBrandGuidelines", - request_serializer=campaign_service.EnablePMaxBrandGuidelinesRequest.serialize, - response_deserializer=campaign_service.EnablePMaxBrandGuidelinesResponse.deserialize, - ) - ) - return self._stubs["enable_p_max_brand_guidelines"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_service/transports/grpc_asyncio.py deleted file mode 100644 index 3da540ab3..000000000 --- a/google/ads/googleads/v19/services/services/campaign_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,461 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import campaign_service -from .base import CampaignServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignService", - "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.ads.googleads.v19.services.CampaignService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignServiceGrpcAsyncIOTransport(CampaignServiceTransport): - """gRPC AsyncIO backend transport for CampaignService. - - Service to manage campaigns. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_campaigns( - self, - ) -> Callable[ - [campaign_service.MutateCampaignsRequest], - Awaitable[campaign_service.MutateCampaignsResponse], - ]: - r"""Return a callable for the mutate campaigns method over gRPC. - - Creates, updates, or removes campaigns. Operation statuses are - returned. - - List of thrown errors: `AdxError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `BiddingError <>`__ `BiddingStrategyError <>`__ - `CampaignBudgetError <>`__ `CampaignError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DateRangeError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ - `InternalError <>`__ `ListOperationError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RegionCodeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateCampaignsRequest], - Awaitable[~.MutateCampaignsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaigns" not in self._stubs: - self._stubs["mutate_campaigns"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignService/MutateCampaigns", - request_serializer=campaign_service.MutateCampaignsRequest.serialize, - response_deserializer=campaign_service.MutateCampaignsResponse.deserialize, - ) - return self._stubs["mutate_campaigns"] - - @property - def enable_p_max_brand_guidelines( - self, - ) -> Callable[ - [campaign_service.EnablePMaxBrandGuidelinesRequest], - Awaitable[campaign_service.EnablePMaxBrandGuidelinesResponse], - ]: - r"""Return a callable for the enable p max brand guidelines method over gRPC. - - Enables Brand Guidelines for Performance Max campaigns. - - List of thrown errors: `AuthenticationError <>`__ - `AssetError <>`__ `AssetLinkError <>`__ - `AuthorizationError <>`__ `BrandGuidelinesMigrationError <>`__ - `CampaignError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.EnablePMaxBrandGuidelinesRequest], - Awaitable[~.EnablePMaxBrandGuidelinesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "enable_p_max_brand_guidelines" not in self._stubs: - self._stubs["enable_p_max_brand_guidelines"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignService/EnablePMaxBrandGuidelines", - request_serializer=campaign_service.EnablePMaxBrandGuidelinesRequest.serialize, - response_deserializer=campaign_service.EnablePMaxBrandGuidelinesResponse.deserialize, - ) - ) - return self._stubs["enable_p_max_brand_guidelines"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaigns: self._wrap_method( - self.mutate_campaigns, - default_timeout=None, - client_info=client_info, - ), - self.enable_p_max_brand_guidelines: self._wrap_method( - self.enable_p_max_brand_guidelines, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_shared_set_service/async_client.py b/google/ads/googleads/v19/services/services/campaign_shared_set_service/async_client.py deleted file mode 100644 index 8ceb5befc..000000000 --- a/google/ads/googleads/v19/services/services/campaign_shared_set_service/async_client.py +++ /dev/null @@ -1,452 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import campaign_shared_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CampaignSharedSetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CampaignSharedSetServiceClient - -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 CampaignSharedSetServiceAsyncClient: - """Service to manage campaign shared sets.""" - - _client: CampaignSharedSetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CampaignSharedSetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CampaignSharedSetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CampaignSharedSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CampaignSharedSetServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod(CampaignSharedSetServiceClient.campaign_path) - parse_campaign_path = staticmethod( - CampaignSharedSetServiceClient.parse_campaign_path - ) - campaign_shared_set_path = staticmethod( - CampaignSharedSetServiceClient.campaign_shared_set_path - ) - parse_campaign_shared_set_path = staticmethod( - CampaignSharedSetServiceClient.parse_campaign_shared_set_path - ) - shared_set_path = staticmethod( - CampaignSharedSetServiceClient.shared_set_path - ) - parse_shared_set_path = staticmethod( - CampaignSharedSetServiceClient.parse_shared_set_path - ) - common_billing_account_path = staticmethod( - CampaignSharedSetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CampaignSharedSetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CampaignSharedSetServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CampaignSharedSetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CampaignSharedSetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CampaignSharedSetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CampaignSharedSetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CampaignSharedSetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CampaignSharedSetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CampaignSharedSetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignSharedSetServiceAsyncClient: The constructed client. - """ - return CampaignSharedSetServiceClient.from_service_account_info.__func__(CampaignSharedSetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignSharedSetServiceAsyncClient: The constructed client. - """ - return CampaignSharedSetServiceClient.from_service_account_file.__func__(CampaignSharedSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CampaignSharedSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CampaignSharedSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignSharedSetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CampaignSharedSetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignSharedSetServiceTransport, - Callable[..., CampaignSharedSetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign shared set service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignSharedSetServiceTransport,Callable[..., CampaignSharedSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignSharedSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CampaignSharedSetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CampaignSharedSetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignSharedSetService", - "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.ads.googleads.v19.services.CampaignSharedSetService", - "credentialsType": None, - } - ), - ) - - async def mutate_campaign_shared_sets( - self, - request: Optional[ - Union[ - campaign_shared_set_service.MutateCampaignSharedSetsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_shared_set_service.CampaignSharedSetOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_shared_set_service.MutateCampaignSharedSetsResponse: - r"""Creates or removes campaign shared sets. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignSharedSetError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCampaignSharedSetsRequest, dict]]): - The request object. Request message for - [CampaignSharedSetService.MutateCampaignSharedSets][google.ads.googleads.v19.services.CampaignSharedSetService.MutateCampaignSharedSets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose campaign shared sets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignSharedSetOperation]`): - Required. The list of operations to - perform on individual campaign shared - sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignSharedSetsResponse: - Response message for a campaign - shared set mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_shared_set_service.MutateCampaignSharedSetsRequest - ): - request = ( - campaign_shared_set_service.MutateCampaignSharedSetsRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_campaign_shared_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CampaignSharedSetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CampaignSharedSetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_shared_set_service/client.py b/google/ads/googleads/v19/services/services/campaign_shared_set_service/client.py deleted file mode 100644 index 676136cac..000000000 --- a/google/ads/googleads/v19/services/services/campaign_shared_set_service/client.py +++ /dev/null @@ -1,942 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import campaign_shared_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CampaignSharedSetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CampaignSharedSetServiceGrpcTransport -from .transports.grpc_asyncio import ( - CampaignSharedSetServiceGrpcAsyncIOTransport, -) - - -class CampaignSharedSetServiceClientMeta(type): - """Metaclass for the CampaignSharedSetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CampaignSharedSetServiceTransport]] - _transport_registry["grpc"] = CampaignSharedSetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CampaignSharedSetServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CampaignSharedSetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CampaignSharedSetServiceClient( - metaclass=CampaignSharedSetServiceClientMeta -): - """Service to manage campaign shared sets.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignSharedSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CampaignSharedSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CampaignSharedSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CampaignSharedSetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_shared_set_path( - customer_id: str, - campaign_id: str, - shared_set_id: str, - ) -> str: - """Returns a fully-qualified campaign_shared_set string.""" - return "customers/{customer_id}/campaignSharedSets/{campaign_id}~{shared_set_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - shared_set_id=shared_set_id, - ) - - @staticmethod - def parse_campaign_shared_set_path(path: str) -> Dict[str, str]: - """Parses a campaign_shared_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignSharedSets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def shared_set_path( - customer_id: str, - shared_set_id: str, - ) -> str: - """Returns a fully-qualified shared_set string.""" - return "customers/{customer_id}/sharedSets/{shared_set_id}".format( - customer_id=customer_id, - shared_set_id=shared_set_id, - ) - - @staticmethod - def parse_shared_set_path(path: str) -> Dict[str, str]: - """Parses a shared_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/sharedSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CampaignSharedSetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CampaignSharedSetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = CampaignSharedSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CampaignSharedSetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CampaignSharedSetServiceTransport, - Callable[..., CampaignSharedSetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the campaign shared set service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CampaignSharedSetServiceTransport,Callable[..., CampaignSharedSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CampaignSharedSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CampaignSharedSetServiceClient._read_environment_variables() - self._client_cert_source = ( - CampaignSharedSetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CampaignSharedSetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CampaignSharedSetServiceTransport - ) - if transport_provided: - # transport is a CampaignSharedSetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CampaignSharedSetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CampaignSharedSetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CampaignSharedSetServiceTransport], - Callable[..., CampaignSharedSetServiceTransport], - ] = ( - CampaignSharedSetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CampaignSharedSetServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CampaignSharedSetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CampaignSharedSetService", - "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.ads.googleads.v19.services.CampaignSharedSetService", - "credentialsType": None, - } - ), - ) - - def mutate_campaign_shared_sets( - self, - request: Optional[ - Union[ - campaign_shared_set_service.MutateCampaignSharedSetsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - campaign_shared_set_service.CampaignSharedSetOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> campaign_shared_set_service.MutateCampaignSharedSetsResponse: - r"""Creates or removes campaign shared sets. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignSharedSetError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCampaignSharedSetsRequest, dict]): - The request object. Request message for - [CampaignSharedSetService.MutateCampaignSharedSets][google.ads.googleads.v19.services.CampaignSharedSetService.MutateCampaignSharedSets]. - customer_id (str): - Required. The ID of the customer - whose campaign shared sets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignSharedSetOperation]): - Required. The list of operations to - perform on individual campaign shared - sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCampaignSharedSetsResponse: - Response message for a campaign - shared set mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, campaign_shared_set_service.MutateCampaignSharedSetsRequest - ): - request = ( - campaign_shared_set_service.MutateCampaignSharedSetsRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_campaign_shared_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CampaignSharedSetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CampaignSharedSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/base.py b/google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/base.py deleted file mode 100644 index 0cdf64075..000000000 --- a/google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import campaign_shared_set_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CampaignSharedSetServiceTransport(abc.ABC): - """Abstract transport class for CampaignSharedSetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_campaign_shared_sets: gapic_v1.method.wrap_method( - self.mutate_campaign_shared_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_campaign_shared_sets( - self, - ) -> Callable[ - [campaign_shared_set_service.MutateCampaignSharedSetsRequest], - Union[ - campaign_shared_set_service.MutateCampaignSharedSetsResponse, - Awaitable[ - campaign_shared_set_service.MutateCampaignSharedSetsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CampaignSharedSetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/grpc.py b/google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/grpc.py deleted file mode 100644 index 035330740..000000000 --- a/google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/grpc.py +++ /dev/null @@ -1,392 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import campaign_shared_set_service -from .base import CampaignSharedSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CampaignSharedSetService", - "rpcName": str(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.ads.googleads.v19.services.CampaignSharedSetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignSharedSetServiceGrpcTransport(CampaignSharedSetServiceTransport): - """gRPC backend transport for CampaignSharedSetService. - - Service to manage campaign shared sets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_campaign_shared_sets( - self, - ) -> Callable[ - [campaign_shared_set_service.MutateCampaignSharedSetsRequest], - campaign_shared_set_service.MutateCampaignSharedSetsResponse, - ]: - r"""Return a callable for the mutate campaign shared sets method over gRPC. - - Creates or removes campaign shared sets. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignSharedSetError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateCampaignSharedSetsRequest], - ~.MutateCampaignSharedSetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_shared_sets" not in self._stubs: - self._stubs["mutate_campaign_shared_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignSharedSetService/MutateCampaignSharedSets", - request_serializer=campaign_shared_set_service.MutateCampaignSharedSetsRequest.serialize, - response_deserializer=campaign_shared_set_service.MutateCampaignSharedSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_shared_sets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CampaignSharedSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/grpc_asyncio.py deleted file mode 100644 index b9c6733bb..000000000 --- a/google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,415 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import campaign_shared_set_service -from .base import CampaignSharedSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CampaignSharedSetService", - "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.ads.googleads.v19.services.CampaignSharedSetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CampaignSharedSetServiceGrpcAsyncIOTransport( - CampaignSharedSetServiceTransport -): - """gRPC AsyncIO backend transport for CampaignSharedSetService. - - Service to manage campaign shared sets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_campaign_shared_sets( - self, - ) -> Callable[ - [campaign_shared_set_service.MutateCampaignSharedSetsRequest], - Awaitable[campaign_shared_set_service.MutateCampaignSharedSetsResponse], - ]: - r"""Return a callable for the mutate campaign shared sets method over gRPC. - - Creates or removes campaign shared sets. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CampaignSharedSetError <>`__ - `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ - `IdError <>`__ `InternalError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateCampaignSharedSetsRequest], - Awaitable[~.MutateCampaignSharedSetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_campaign_shared_sets" not in self._stubs: - self._stubs["mutate_campaign_shared_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CampaignSharedSetService/MutateCampaignSharedSets", - request_serializer=campaign_shared_set_service.MutateCampaignSharedSetsRequest.serialize, - response_deserializer=campaign_shared_set_service.MutateCampaignSharedSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_campaign_shared_sets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_campaign_shared_sets: self._wrap_method( - self.mutate_campaign_shared_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CampaignSharedSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/content_creator_insights_service/async_client.py b/google/ads/googleads/v19/services/services/content_creator_insights_service/async_client.py deleted file mode 100644 index 9e9166060..000000000 --- a/google/ads/googleads/v19/services/services/content_creator_insights_service/async_client.py +++ /dev/null @@ -1,477 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - content_creator_insights_service, -) -from .transports.base import ( - ContentCreatorInsightsServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import ContentCreatorInsightsServiceClient - -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 ContentCreatorInsightsServiceAsyncClient: - """Content Creator Insights Service helps users find information - about YouTube Creators and their content and how these creators - and their audiences can be reached with Google Ads. Accessible - to allowlisted customers only. - """ - - _client: ContentCreatorInsightsServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ContentCreatorInsightsServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - ContentCreatorInsightsServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - ContentCreatorInsightsServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ContentCreatorInsightsServiceClient._DEFAULT_UNIVERSE - - common_billing_account_path = staticmethod( - ContentCreatorInsightsServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ContentCreatorInsightsServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ContentCreatorInsightsServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ContentCreatorInsightsServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ContentCreatorInsightsServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ContentCreatorInsightsServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ContentCreatorInsightsServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ContentCreatorInsightsServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ContentCreatorInsightsServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ContentCreatorInsightsServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ContentCreatorInsightsServiceAsyncClient: The constructed client. - """ - return ContentCreatorInsightsServiceClient.from_service_account_info.__func__(ContentCreatorInsightsServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ContentCreatorInsightsServiceAsyncClient: The constructed client. - """ - return ContentCreatorInsightsServiceClient.from_service_account_file.__func__(ContentCreatorInsightsServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ContentCreatorInsightsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ContentCreatorInsightsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ContentCreatorInsightsServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - ContentCreatorInsightsServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ContentCreatorInsightsServiceTransport, - Callable[..., ContentCreatorInsightsServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the content creator insights service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ContentCreatorInsightsServiceTransport,Callable[..., ContentCreatorInsightsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ContentCreatorInsightsServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ContentCreatorInsightsServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ContentCreatorInsightsServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ContentCreatorInsightsService", - "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.ads.googleads.v19.services.ContentCreatorInsightsService", - "credentialsType": None, - } - ), - ) - - async def generate_creator_insights( - self, - request: Optional[ - Union[ - content_creator_insights_service.GenerateCreatorInsightsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> content_creator_insights_service.GenerateCreatorInsightsResponse: - r"""Returns insights for a collection of YouTube Creators and - Channels. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateCreatorInsightsRequest, dict]]): - The request object. Request message for - [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v19.services.ContentCreatorInsightsService.GenerateCreatorInsights]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateCreatorInsightsResponse: - Response message for - [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v19.services.ContentCreatorInsightsService.GenerateCreatorInsights]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - content_creator_insights_service.GenerateCreatorInsightsRequest, - ): - request = ( - content_creator_insights_service.GenerateCreatorInsightsRequest( - request - ) - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_creator_insights - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def generate_trending_insights( - self, - request: Optional[ - Union[ - content_creator_insights_service.GenerateTrendingInsightsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> content_creator_insights_service.GenerateTrendingInsightsResponse: - r"""Returns insights for trending content on YouTube. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateTrendingInsightsRequest, dict]]): - The request object. Request message for - [ContentCreatorInsightsService.GenerateTrendingInsights] - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateTrendingInsightsResponse: - Response message for - [ContentCreatorInsightsService.GenerateTrendingInsights] - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - content_creator_insights_service.GenerateTrendingInsightsRequest, - ): - request = content_creator_insights_service.GenerateTrendingInsightsRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_trending_insights - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ContentCreatorInsightsServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ContentCreatorInsightsServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/content_creator_insights_service/client.py b/google/ads/googleads/v19/services/services/content_creator_insights_service/client.py deleted file mode 100644 index d7a22659f..000000000 --- a/google/ads/googleads/v19/services/services/content_creator_insights_service/client.py +++ /dev/null @@ -1,917 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - content_creator_insights_service, -) -from .transports.base import ( - ContentCreatorInsightsServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ContentCreatorInsightsServiceGrpcTransport -from .transports.grpc_asyncio import ( - ContentCreatorInsightsServiceGrpcAsyncIOTransport, -) - - -class ContentCreatorInsightsServiceClientMeta(type): - """Metaclass for the ContentCreatorInsightsService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ContentCreatorInsightsServiceTransport]] - _transport_registry["grpc"] = ContentCreatorInsightsServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - ContentCreatorInsightsServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ContentCreatorInsightsServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ContentCreatorInsightsServiceClient( - metaclass=ContentCreatorInsightsServiceClientMeta -): - """Content Creator Insights Service helps users find information - about YouTube Creators and their content and how these creators - and their audiences can be reached with Google Ads. Accessible - to allowlisted customers only. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ContentCreatorInsightsServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ContentCreatorInsightsServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ContentCreatorInsightsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ContentCreatorInsightsServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - ContentCreatorInsightsServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - ContentCreatorInsightsServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = ContentCreatorInsightsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ContentCreatorInsightsServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ContentCreatorInsightsServiceTransport, - Callable[..., ContentCreatorInsightsServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the content creator insights service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ContentCreatorInsightsServiceTransport,Callable[..., ContentCreatorInsightsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ContentCreatorInsightsServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ContentCreatorInsightsServiceClient._read_environment_variables() - self._client_cert_source = ( - ContentCreatorInsightsServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - ContentCreatorInsightsServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ContentCreatorInsightsServiceTransport - ) - if transport_provided: - # transport is a ContentCreatorInsightsServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - ContentCreatorInsightsServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ContentCreatorInsightsServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ContentCreatorInsightsServiceTransport], - Callable[..., ContentCreatorInsightsServiceTransport], - ] = ( - ContentCreatorInsightsServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ContentCreatorInsightsServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ContentCreatorInsightsServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ContentCreatorInsightsService", - "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.ads.googleads.v19.services.ContentCreatorInsightsService", - "credentialsType": None, - } - ), - ) - - def generate_creator_insights( - self, - request: Optional[ - Union[ - content_creator_insights_service.GenerateCreatorInsightsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> content_creator_insights_service.GenerateCreatorInsightsResponse: - r"""Returns insights for a collection of YouTube Creators and - Channels. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateCreatorInsightsRequest, dict]): - The request object. Request message for - [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v19.services.ContentCreatorInsightsService.GenerateCreatorInsights]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateCreatorInsightsResponse: - Response message for - [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v19.services.ContentCreatorInsightsService.GenerateCreatorInsights]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - content_creator_insights_service.GenerateCreatorInsightsRequest, - ): - request = ( - content_creator_insights_service.GenerateCreatorInsightsRequest( - request - ) - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_creator_insights - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def generate_trending_insights( - self, - request: Optional[ - Union[ - content_creator_insights_service.GenerateTrendingInsightsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> content_creator_insights_service.GenerateTrendingInsightsResponse: - r"""Returns insights for trending content on YouTube. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateTrendingInsightsRequest, dict]): - The request object. Request message for - [ContentCreatorInsightsService.GenerateTrendingInsights] - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateTrendingInsightsResponse: - Response message for - [ContentCreatorInsightsService.GenerateTrendingInsights] - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - content_creator_insights_service.GenerateTrendingInsightsRequest, - ): - request = content_creator_insights_service.GenerateTrendingInsightsRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_trending_insights - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ContentCreatorInsightsServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ContentCreatorInsightsServiceClient",) diff --git a/google/ads/googleads/v19/services/services/content_creator_insights_service/transports/base.py b/google/ads/googleads/v19/services/services/content_creator_insights_service/transports/base.py deleted file mode 100644 index 01ae12b64..000000000 --- a/google/ads/googleads/v19/services/services/content_creator_insights_service/transports/base.py +++ /dev/null @@ -1,195 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - content_creator_insights_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ContentCreatorInsightsServiceTransport(abc.ABC): - """Abstract transport class for ContentCreatorInsightsService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.generate_creator_insights: gapic_v1.method.wrap_method( - self.generate_creator_insights, - default_timeout=None, - client_info=client_info, - ), - self.generate_trending_insights: gapic_v1.method.wrap_method( - self.generate_trending_insights, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def generate_creator_insights( - self, - ) -> Callable[ - [content_creator_insights_service.GenerateCreatorInsightsRequest], - Union[ - content_creator_insights_service.GenerateCreatorInsightsResponse, - Awaitable[ - content_creator_insights_service.GenerateCreatorInsightsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def generate_trending_insights( - self, - ) -> Callable[ - [content_creator_insights_service.GenerateTrendingInsightsRequest], - Union[ - content_creator_insights_service.GenerateTrendingInsightsResponse, - Awaitable[ - content_creator_insights_service.GenerateTrendingInsightsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ContentCreatorInsightsServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/content_creator_insights_service/transports/grpc.py b/google/ads/googleads/v19/services/services/content_creator_insights_service/transports/grpc.py deleted file mode 100644 index 38796e8de..000000000 --- a/google/ads/googleads/v19/services/services/content_creator_insights_service/transports/grpc.py +++ /dev/null @@ -1,430 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - content_creator_insights_service, -) -from .base import ContentCreatorInsightsServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ContentCreatorInsightsService", - "rpcName": str(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.ads.googleads.v19.services.ContentCreatorInsightsService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ContentCreatorInsightsServiceGrpcTransport( - ContentCreatorInsightsServiceTransport -): - """gRPC backend transport for ContentCreatorInsightsService. - - Content Creator Insights Service helps users find information - about YouTube Creators and their content and how these creators - and their audiences can be reached with Google Ads. Accessible - to allowlisted customers only. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def generate_creator_insights( - self, - ) -> Callable[ - [content_creator_insights_service.GenerateCreatorInsightsRequest], - content_creator_insights_service.GenerateCreatorInsightsResponse, - ]: - r"""Return a callable for the generate creator insights method over gRPC. - - Returns insights for a collection of YouTube Creators and - Channels. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateCreatorInsightsRequest], - ~.GenerateCreatorInsightsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_creator_insights" not in self._stubs: - self._stubs["generate_creator_insights"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ContentCreatorInsightsService/GenerateCreatorInsights", - request_serializer=content_creator_insights_service.GenerateCreatorInsightsRequest.serialize, - response_deserializer=content_creator_insights_service.GenerateCreatorInsightsResponse.deserialize, - ) - ) - return self._stubs["generate_creator_insights"] - - @property - def generate_trending_insights( - self, - ) -> Callable[ - [content_creator_insights_service.GenerateTrendingInsightsRequest], - content_creator_insights_service.GenerateTrendingInsightsResponse, - ]: - r"""Return a callable for the generate trending insights method over gRPC. - - Returns insights for trending content on YouTube. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateTrendingInsightsRequest], - ~.GenerateTrendingInsightsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_trending_insights" not in self._stubs: - self._stubs["generate_trending_insights"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ContentCreatorInsightsService/GenerateTrendingInsights", - request_serializer=content_creator_insights_service.GenerateTrendingInsightsRequest.serialize, - response_deserializer=content_creator_insights_service.GenerateTrendingInsightsResponse.deserialize, - ) - ) - return self._stubs["generate_trending_insights"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ContentCreatorInsightsServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/content_creator_insights_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/content_creator_insights_service/transports/grpc_asyncio.py deleted file mode 100644 index 27a2e3395..000000000 --- a/google/ads/googleads/v19/services/services/content_creator_insights_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,460 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - content_creator_insights_service, -) -from .base import ContentCreatorInsightsServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ContentCreatorInsightsService", - "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.ads.googleads.v19.services.ContentCreatorInsightsService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ContentCreatorInsightsServiceGrpcAsyncIOTransport( - ContentCreatorInsightsServiceTransport -): - """gRPC AsyncIO backend transport for ContentCreatorInsightsService. - - Content Creator Insights Service helps users find information - about YouTube Creators and their content and how these creators - and their audiences can be reached with Google Ads. Accessible - to allowlisted customers only. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def generate_creator_insights( - self, - ) -> Callable[ - [content_creator_insights_service.GenerateCreatorInsightsRequest], - Awaitable[ - content_creator_insights_service.GenerateCreatorInsightsResponse - ], - ]: - r"""Return a callable for the generate creator insights method over gRPC. - - Returns insights for a collection of YouTube Creators and - Channels. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateCreatorInsightsRequest], - Awaitable[~.GenerateCreatorInsightsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_creator_insights" not in self._stubs: - self._stubs["generate_creator_insights"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ContentCreatorInsightsService/GenerateCreatorInsights", - request_serializer=content_creator_insights_service.GenerateCreatorInsightsRequest.serialize, - response_deserializer=content_creator_insights_service.GenerateCreatorInsightsResponse.deserialize, - ) - ) - return self._stubs["generate_creator_insights"] - - @property - def generate_trending_insights( - self, - ) -> Callable[ - [content_creator_insights_service.GenerateTrendingInsightsRequest], - Awaitable[ - content_creator_insights_service.GenerateTrendingInsightsResponse - ], - ]: - r"""Return a callable for the generate trending insights method over gRPC. - - Returns insights for trending content on YouTube. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateTrendingInsightsRequest], - Awaitable[~.GenerateTrendingInsightsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_trending_insights" not in self._stubs: - self._stubs["generate_trending_insights"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ContentCreatorInsightsService/GenerateTrendingInsights", - request_serializer=content_creator_insights_service.GenerateTrendingInsightsRequest.serialize, - response_deserializer=content_creator_insights_service.GenerateTrendingInsightsResponse.deserialize, - ) - ) - return self._stubs["generate_trending_insights"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.generate_creator_insights: self._wrap_method( - self.generate_creator_insights, - default_timeout=None, - client_info=client_info, - ), - self.generate_trending_insights: self._wrap_method( - self.generate_trending_insights, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ContentCreatorInsightsServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_action_service/async_client.py b/google/ads/googleads/v19/services/services/conversion_action_service/async_client.py deleted file mode 100644 index e2de4f2b7..000000000 --- a/google/ads/googleads/v19/services/services/conversion_action_service/async_client.py +++ /dev/null @@ -1,439 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import conversion_action_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionActionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import ConversionActionServiceClient - -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 ConversionActionServiceAsyncClient: - """Service to manage conversion actions.""" - - _client: ConversionActionServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ConversionActionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ConversionActionServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - ConversionActionServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ConversionActionServiceClient._DEFAULT_UNIVERSE - - conversion_action_path = staticmethod( - ConversionActionServiceClient.conversion_action_path - ) - parse_conversion_action_path = staticmethod( - ConversionActionServiceClient.parse_conversion_action_path - ) - customer_path = staticmethod(ConversionActionServiceClient.customer_path) - parse_customer_path = staticmethod( - ConversionActionServiceClient.parse_customer_path - ) - common_billing_account_path = staticmethod( - ConversionActionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ConversionActionServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ConversionActionServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ConversionActionServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ConversionActionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ConversionActionServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ConversionActionServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ConversionActionServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ConversionActionServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ConversionActionServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionActionServiceAsyncClient: The constructed client. - """ - return ConversionActionServiceClient.from_service_account_info.__func__(ConversionActionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionActionServiceAsyncClient: The constructed client. - """ - return ConversionActionServiceClient.from_service_account_file.__func__(ConversionActionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ConversionActionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ConversionActionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionActionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ConversionActionServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionActionServiceTransport, - Callable[..., ConversionActionServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion action service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionActionServiceTransport,Callable[..., ConversionActionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionActionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ConversionActionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ConversionActionServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionActionService", - "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.ads.googleads.v19.services.ConversionActionService", - "credentialsType": None, - } - ), - ) - - async def mutate_conversion_actions( - self, - request: Optional[ - Union[ - conversion_action_service.MutateConversionActionsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[conversion_action_service.ConversionActionOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> conversion_action_service.MutateConversionActionsResponse: - r"""Creates, updates or removes conversion actions. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionActionError <>`__ - `CurrencyCodeError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateConversionActionsRequest, dict]]): - The request object. Request message for - [ConversionActionService.MutateConversionActions][google.ads.googleads.v19.services.ConversionActionService.MutateConversionActions]. - customer_id (:class:`str`): - Required. The ID of the customer - whose conversion actions are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.ConversionActionOperation]`): - Required. The list of operations to - perform on individual conversion - actions. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateConversionActionsResponse: - Response message for - [ConversionActionService.MutateConversionActions][google.ads.googleads.v19.services.ConversionActionService.MutateConversionActions]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, conversion_action_service.MutateConversionActionsRequest - ): - request = conversion_action_service.MutateConversionActionsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_conversion_actions - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ConversionActionServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ConversionActionServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_action_service/client.py b/google/ads/googleads/v19/services/services/conversion_action_service/client.py deleted file mode 100644 index c4ea44f24..000000000 --- a/google/ads/googleads/v19/services/services/conversion_action_service/client.py +++ /dev/null @@ -1,908 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import conversion_action_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionActionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ConversionActionServiceGrpcTransport -from .transports.grpc_asyncio import ConversionActionServiceGrpcAsyncIOTransport - - -class ConversionActionServiceClientMeta(type): - """Metaclass for the ConversionActionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ConversionActionServiceTransport]] - _transport_registry["grpc"] = ConversionActionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - ConversionActionServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ConversionActionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ConversionActionServiceClient( - metaclass=ConversionActionServiceClientMeta -): - """Service to manage conversion actions.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionActionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionActionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ConversionActionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionActionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def conversion_action_path( - customer_id: str, - conversion_action_id: str, - ) -> str: - """Returns a fully-qualified conversion_action string.""" - return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( - customer_id=customer_id, - conversion_action_id=conversion_action_id, - ) - - @staticmethod - def parse_conversion_action_path(path: str) -> Dict[str, str]: - """Parses a conversion_action path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionActions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ConversionActionServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ConversionActionServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - ConversionActionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ConversionActionServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionActionServiceTransport, - Callable[..., ConversionActionServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion action service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionActionServiceTransport,Callable[..., ConversionActionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionActionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ConversionActionServiceClient._read_environment_variables() - self._client_cert_source = ( - ConversionActionServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - ConversionActionServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ConversionActionServiceTransport - ) - if transport_provided: - # transport is a ConversionActionServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(ConversionActionServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ConversionActionServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ConversionActionServiceTransport], - Callable[..., ConversionActionServiceTransport], - ] = ( - ConversionActionServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ConversionActionServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ConversionActionServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionActionService", - "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.ads.googleads.v19.services.ConversionActionService", - "credentialsType": None, - } - ), - ) - - def mutate_conversion_actions( - self, - request: Optional[ - Union[ - conversion_action_service.MutateConversionActionsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[conversion_action_service.ConversionActionOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> conversion_action_service.MutateConversionActionsResponse: - r"""Creates, updates or removes conversion actions. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionActionError <>`__ - `CurrencyCodeError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateConversionActionsRequest, dict]): - The request object. Request message for - [ConversionActionService.MutateConversionActions][google.ads.googleads.v19.services.ConversionActionService.MutateConversionActions]. - customer_id (str): - Required. The ID of the customer - whose conversion actions are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.ConversionActionOperation]): - Required. The list of operations to - perform on individual conversion - actions. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateConversionActionsResponse: - Response message for - [ConversionActionService.MutateConversionActions][google.ads.googleads.v19.services.ConversionActionService.MutateConversionActions]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, conversion_action_service.MutateConversionActionsRequest - ): - request = conversion_action_service.MutateConversionActionsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_conversion_actions - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ConversionActionServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ConversionActionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_action_service/transports/base.py b/google/ads/googleads/v19/services/services/conversion_action_service/transports/base.py deleted file mode 100644 index dca5f4e8d..000000000 --- a/google/ads/googleads/v19/services/services/conversion_action_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import conversion_action_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ConversionActionServiceTransport(abc.ABC): - """Abstract transport class for ConversionActionService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_conversion_actions: gapic_v1.method.wrap_method( - self.mutate_conversion_actions, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_conversion_actions( - self, - ) -> Callable[ - [conversion_action_service.MutateConversionActionsRequest], - Union[ - conversion_action_service.MutateConversionActionsResponse, - Awaitable[ - conversion_action_service.MutateConversionActionsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ConversionActionServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_action_service/transports/grpc.py b/google/ads/googleads/v19/services/services/conversion_action_service/transports/grpc.py deleted file mode 100644 index 1db4a8f29..000000000 --- a/google/ads/googleads/v19/services/services/conversion_action_service/transports/grpc.py +++ /dev/null @@ -1,390 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import conversion_action_service -from .base import ConversionActionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ConversionActionService", - "rpcName": str(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.ads.googleads.v19.services.ConversionActionService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionActionServiceGrpcTransport(ConversionActionServiceTransport): - """gRPC backend transport for ConversionActionService. - - Service to manage conversion actions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_conversion_actions( - self, - ) -> Callable[ - [conversion_action_service.MutateConversionActionsRequest], - conversion_action_service.MutateConversionActionsResponse, - ]: - r"""Return a callable for the mutate conversion actions method over gRPC. - - Creates, updates or removes conversion actions. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionActionError <>`__ - `CurrencyCodeError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateConversionActionsRequest], - ~.MutateConversionActionsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_conversion_actions" not in self._stubs: - self._stubs["mutate_conversion_actions"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionActionService/MutateConversionActions", - request_serializer=conversion_action_service.MutateConversionActionsRequest.serialize, - response_deserializer=conversion_action_service.MutateConversionActionsResponse.deserialize, - ) - ) - return self._stubs["mutate_conversion_actions"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ConversionActionServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_action_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/conversion_action_service/transports/grpc_asyncio.py deleted file mode 100644 index f24dcb062..000000000 --- a/google/ads/googleads/v19/services/services/conversion_action_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,413 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import conversion_action_service -from .base import ConversionActionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ConversionActionService", - "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.ads.googleads.v19.services.ConversionActionService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionActionServiceGrpcAsyncIOTransport( - ConversionActionServiceTransport -): - """gRPC AsyncIO backend transport for ConversionActionService. - - Service to manage conversion actions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_conversion_actions( - self, - ) -> Callable[ - [conversion_action_service.MutateConversionActionsRequest], - Awaitable[conversion_action_service.MutateConversionActionsResponse], - ]: - r"""Return a callable for the mutate conversion actions method over gRPC. - - Creates, updates or removes conversion actions. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionActionError <>`__ - `CurrencyCodeError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateConversionActionsRequest], - Awaitable[~.MutateConversionActionsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_conversion_actions" not in self._stubs: - self._stubs["mutate_conversion_actions"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionActionService/MutateConversionActions", - request_serializer=conversion_action_service.MutateConversionActionsRequest.serialize, - response_deserializer=conversion_action_service.MutateConversionActionsResponse.deserialize, - ) - ) - return self._stubs["mutate_conversion_actions"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_conversion_actions: self._wrap_method( - self.mutate_conversion_actions, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ConversionActionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/async_client.py b/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/async_client.py deleted file mode 100644 index 60c178c76..000000000 --- a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/async_client.py +++ /dev/null @@ -1,462 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - conversion_adjustment_upload_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionAdjustmentUploadServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import ConversionAdjustmentUploadServiceClient - -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 ConversionAdjustmentUploadServiceAsyncClient: - """Service to upload conversion adjustments.""" - - _client: ConversionAdjustmentUploadServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ConversionAdjustmentUploadServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - ConversionAdjustmentUploadServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - ConversionAdjustmentUploadServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ( - ConversionAdjustmentUploadServiceClient._DEFAULT_UNIVERSE - ) - - common_billing_account_path = staticmethod( - ConversionAdjustmentUploadServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ConversionAdjustmentUploadServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ConversionAdjustmentUploadServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ConversionAdjustmentUploadServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ConversionAdjustmentUploadServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ConversionAdjustmentUploadServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ConversionAdjustmentUploadServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ConversionAdjustmentUploadServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ConversionAdjustmentUploadServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ConversionAdjustmentUploadServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionAdjustmentUploadServiceAsyncClient: The constructed client. - """ - return ConversionAdjustmentUploadServiceClient.from_service_account_info.__func__(ConversionAdjustmentUploadServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionAdjustmentUploadServiceAsyncClient: The constructed client. - """ - return ConversionAdjustmentUploadServiceClient.from_service_account_file.__func__(ConversionAdjustmentUploadServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ConversionAdjustmentUploadServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ConversionAdjustmentUploadServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionAdjustmentUploadServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - ConversionAdjustmentUploadServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionAdjustmentUploadServiceTransport, - Callable[..., ConversionAdjustmentUploadServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion adjustment upload service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionAdjustmentUploadServiceTransport,Callable[..., ConversionAdjustmentUploadServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionAdjustmentUploadServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ConversionAdjustmentUploadServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ConversionAdjustmentUploadServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionAdjustmentUploadService", - "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.ads.googleads.v19.services.ConversionAdjustmentUploadService", - "credentialsType": None, - } - ), - ) - - async def upload_conversion_adjustments( - self, - request: Optional[ - Union[ - conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - conversion_adjustments: Optional[ - MutableSequence[ - conversion_adjustment_upload_service.ConversionAdjustment - ] - ] = None, - partial_failure: Optional[bool] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse - ): - r"""Processes the given conversion adjustments. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PartialFailureError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.UploadConversionAdjustmentsRequest, dict]]): - The request object. Request message for - [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v19.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. - customer_id (:class:`str`): - Required. The ID of the customer - performing the upload. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - conversion_adjustments (:class:`MutableSequence[google.ads.googleads.v19.services.types.ConversionAdjustment]`): - Required. The conversion adjustments - that are being uploaded. - - This corresponds to the ``conversion_adjustments`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - partial_failure (:class:`bool`): - Required. If true, successful - operations will be carried out and - invalid operations will return errors. - If false, all operations will be carried - out in one transaction if and only if - they are all valid. This should always - be set to true. - See - https://developers.google.com/google-ads/api/docs/best-practices/partial-failures - for more information about partial - failure. - - This corresponds to the ``partial_failure`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UploadConversionAdjustmentsResponse: - Response message for - [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v19.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [ - customer_id, - conversion_adjustments, - partial_failure, - ] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest, - ): - request = conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if partial_failure is not None: - request.partial_failure = partial_failure - if conversion_adjustments: - request.conversion_adjustments.extend(conversion_adjustments) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.upload_conversion_adjustments - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__( - self, - ) -> "ConversionAdjustmentUploadServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ConversionAdjustmentUploadServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/client.py b/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/client.py deleted file mode 100644 index b64489faa..000000000 --- a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/client.py +++ /dev/null @@ -1,911 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - conversion_adjustment_upload_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionAdjustmentUploadServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ConversionAdjustmentUploadServiceGrpcTransport -from .transports.grpc_asyncio import ( - ConversionAdjustmentUploadServiceGrpcAsyncIOTransport, -) - - -class ConversionAdjustmentUploadServiceClientMeta(type): - """Metaclass for the ConversionAdjustmentUploadService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ConversionAdjustmentUploadServiceTransport]] - _transport_registry["grpc"] = ConversionAdjustmentUploadServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - ConversionAdjustmentUploadServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ConversionAdjustmentUploadServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ConversionAdjustmentUploadServiceClient( - metaclass=ConversionAdjustmentUploadServiceClientMeta -): - """Service to upload conversion adjustments.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionAdjustmentUploadServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionAdjustmentUploadServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ConversionAdjustmentUploadServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionAdjustmentUploadServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - ConversionAdjustmentUploadServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - ConversionAdjustmentUploadServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = ConversionAdjustmentUploadServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - ConversionAdjustmentUploadServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionAdjustmentUploadServiceTransport, - Callable[..., ConversionAdjustmentUploadServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion adjustment upload service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionAdjustmentUploadServiceTransport,Callable[..., ConversionAdjustmentUploadServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionAdjustmentUploadServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ( - ConversionAdjustmentUploadServiceClient._read_environment_variables() - ) - self._client_cert_source = ( - ConversionAdjustmentUploadServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - ConversionAdjustmentUploadServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ConversionAdjustmentUploadServiceTransport - ) - if transport_provided: - # transport is a ConversionAdjustmentUploadServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - ConversionAdjustmentUploadServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ConversionAdjustmentUploadServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ConversionAdjustmentUploadServiceTransport], - Callable[..., ConversionAdjustmentUploadServiceTransport], - ] = ( - ConversionAdjustmentUploadServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ConversionAdjustmentUploadServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ConversionAdjustmentUploadServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionAdjustmentUploadService", - "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.ads.googleads.v19.services.ConversionAdjustmentUploadService", - "credentialsType": None, - } - ), - ) - - def upload_conversion_adjustments( - self, - request: Optional[ - Union[ - conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - conversion_adjustments: Optional[ - MutableSequence[ - conversion_adjustment_upload_service.ConversionAdjustment - ] - ] = None, - partial_failure: Optional[bool] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse - ): - r"""Processes the given conversion adjustments. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PartialFailureError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.UploadConversionAdjustmentsRequest, dict]): - The request object. Request message for - [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v19.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. - customer_id (str): - Required. The ID of the customer - performing the upload. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - conversion_adjustments (MutableSequence[google.ads.googleads.v19.services.types.ConversionAdjustment]): - Required. The conversion adjustments - that are being uploaded. - - This corresponds to the ``conversion_adjustments`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - partial_failure (bool): - Required. If true, successful - operations will be carried out and - invalid operations will return errors. - If false, all operations will be carried - out in one transaction if and only if - they are all valid. This should always - be set to true. - See - https://developers.google.com/google-ads/api/docs/best-practices/partial-failures - for more information about partial - failure. - - This corresponds to the ``partial_failure`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UploadConversionAdjustmentsResponse: - Response message for - [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v19.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [ - customer_id, - conversion_adjustments, - partial_failure, - ] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest, - ): - request = conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if conversion_adjustments is not None: - request.conversion_adjustments = conversion_adjustments - if partial_failure is not None: - request.partial_failure = partial_failure - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.upload_conversion_adjustments - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ConversionAdjustmentUploadServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ConversionAdjustmentUploadServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/base.py b/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/base.py deleted file mode 100644 index 4c6219b16..000000000 --- a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - conversion_adjustment_upload_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ConversionAdjustmentUploadServiceTransport(abc.ABC): - """Abstract transport class for ConversionAdjustmentUploadService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.upload_conversion_adjustments: gapic_v1.method.wrap_method( - self.upload_conversion_adjustments, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def upload_conversion_adjustments( - self, - ) -> Callable[ - [ - conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest - ], - Union[ - conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse, - Awaitable[ - conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ConversionAdjustmentUploadServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/grpc.py b/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/grpc.py deleted file mode 100644 index bd16c58e9..000000000 --- a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/grpc.py +++ /dev/null @@ -1,395 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - conversion_adjustment_upload_service, -) -from .base import ( - ConversionAdjustmentUploadServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ConversionAdjustmentUploadService", - "rpcName": str(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.ads.googleads.v19.services.ConversionAdjustmentUploadService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionAdjustmentUploadServiceGrpcTransport( - ConversionAdjustmentUploadServiceTransport -): - """gRPC backend transport for ConversionAdjustmentUploadService. - - Service to upload conversion adjustments. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def upload_conversion_adjustments( - self, - ) -> Callable[ - [ - conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest - ], - conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse, - ]: - r"""Return a callable for the upload conversion adjustments method over gRPC. - - Processes the given conversion adjustments. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PartialFailureError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.UploadConversionAdjustmentsRequest], - ~.UploadConversionAdjustmentsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "upload_conversion_adjustments" not in self._stubs: - self._stubs["upload_conversion_adjustments"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionAdjustmentUploadService/UploadConversionAdjustments", - request_serializer=conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest.serialize, - response_deserializer=conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse.deserialize, - ) - ) - return self._stubs["upload_conversion_adjustments"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ConversionAdjustmentUploadServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/grpc_asyncio.py deleted file mode 100644 index c1acb00b0..000000000 --- a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,418 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - conversion_adjustment_upload_service, -) -from .base import ( - ConversionAdjustmentUploadServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ConversionAdjustmentUploadService", - "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.ads.googleads.v19.services.ConversionAdjustmentUploadService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionAdjustmentUploadServiceGrpcAsyncIOTransport( - ConversionAdjustmentUploadServiceTransport -): - """gRPC AsyncIO backend transport for ConversionAdjustmentUploadService. - - Service to upload conversion adjustments. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def upload_conversion_adjustments( - self, - ) -> Callable[ - [ - conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest - ], - Awaitable[ - conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse - ], - ]: - r"""Return a callable for the upload conversion adjustments method over gRPC. - - Processes the given conversion adjustments. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PartialFailureError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.UploadConversionAdjustmentsRequest], - Awaitable[~.UploadConversionAdjustmentsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "upload_conversion_adjustments" not in self._stubs: - self._stubs["upload_conversion_adjustments"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionAdjustmentUploadService/UploadConversionAdjustments", - request_serializer=conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest.serialize, - response_deserializer=conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse.deserialize, - ) - ) - return self._stubs["upload_conversion_adjustments"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.upload_conversion_adjustments: self._wrap_method( - self.upload_conversion_adjustments, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ConversionAdjustmentUploadServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/async_client.py b/google/ads/googleads/v19/services/services/conversion_custom_variable_service/async_client.py deleted file mode 100644 index 16b42996f..000000000 --- a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/async_client.py +++ /dev/null @@ -1,450 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - conversion_custom_variable_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionCustomVariableServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import ConversionCustomVariableServiceClient - -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 ConversionCustomVariableServiceAsyncClient: - """Service to manage conversion custom variables.""" - - _client: ConversionCustomVariableServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ConversionCustomVariableServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - ConversionCustomVariableServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - ConversionCustomVariableServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ConversionCustomVariableServiceClient._DEFAULT_UNIVERSE - - conversion_custom_variable_path = staticmethod( - ConversionCustomVariableServiceClient.conversion_custom_variable_path - ) - parse_conversion_custom_variable_path = staticmethod( - ConversionCustomVariableServiceClient.parse_conversion_custom_variable_path - ) - customer_path = staticmethod( - ConversionCustomVariableServiceClient.customer_path - ) - parse_customer_path = staticmethod( - ConversionCustomVariableServiceClient.parse_customer_path - ) - common_billing_account_path = staticmethod( - ConversionCustomVariableServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ConversionCustomVariableServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ConversionCustomVariableServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ConversionCustomVariableServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ConversionCustomVariableServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ConversionCustomVariableServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ConversionCustomVariableServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ConversionCustomVariableServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ConversionCustomVariableServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ConversionCustomVariableServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionCustomVariableServiceAsyncClient: The constructed client. - """ - return ConversionCustomVariableServiceClient.from_service_account_info.__func__(ConversionCustomVariableServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionCustomVariableServiceAsyncClient: The constructed client. - """ - return ConversionCustomVariableServiceClient.from_service_account_file.__func__(ConversionCustomVariableServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ConversionCustomVariableServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ConversionCustomVariableServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionCustomVariableServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - ConversionCustomVariableServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionCustomVariableServiceTransport, - Callable[..., ConversionCustomVariableServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion custom variable service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionCustomVariableServiceTransport,Callable[..., ConversionCustomVariableServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionCustomVariableServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ConversionCustomVariableServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ConversionCustomVariableServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionCustomVariableService", - "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.ads.googleads.v19.services.ConversionCustomVariableService", - "credentialsType": None, - } - ), - ) - - async def mutate_conversion_custom_variables( - self, - request: Optional[ - Union[ - conversion_custom_variable_service.MutateConversionCustomVariablesRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - conversion_custom_variable_service.ConversionCustomVariableOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - conversion_custom_variable_service.MutateConversionCustomVariablesResponse - ): - r"""Creates or updates conversion custom variables. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionCustomVariableError <>`__ - `DatabaseError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateConversionCustomVariablesRequest, dict]]): - The request object. Request message for - [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v19.services.ConversionCustomVariableService.MutateConversionCustomVariables]. - customer_id (:class:`str`): - Required. The ID of the customer - whose conversion custom variables are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.ConversionCustomVariableOperation]`): - Required. The list of operations to - perform on individual conversion custom - variables. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateConversionCustomVariablesResponse: - Response message for - [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v19.services.ConversionCustomVariableService.MutateConversionCustomVariables]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - conversion_custom_variable_service.MutateConversionCustomVariablesRequest, - ): - request = conversion_custom_variable_service.MutateConversionCustomVariablesRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_conversion_custom_variables - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ConversionCustomVariableServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ConversionCustomVariableServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/client.py b/google/ads/googleads/v19/services/services/conversion_custom_variable_service/client.py deleted file mode 100644 index 23904a000..000000000 --- a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/client.py +++ /dev/null @@ -1,924 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - conversion_custom_variable_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionCustomVariableServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ConversionCustomVariableServiceGrpcTransport -from .transports.grpc_asyncio import ( - ConversionCustomVariableServiceGrpcAsyncIOTransport, -) - - -class ConversionCustomVariableServiceClientMeta(type): - """Metaclass for the ConversionCustomVariableService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ConversionCustomVariableServiceTransport]] - _transport_registry["grpc"] = ConversionCustomVariableServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - ConversionCustomVariableServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ConversionCustomVariableServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ConversionCustomVariableServiceClient( - metaclass=ConversionCustomVariableServiceClientMeta -): - """Service to manage conversion custom variables.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionCustomVariableServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionCustomVariableServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ConversionCustomVariableServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionCustomVariableServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def conversion_custom_variable_path( - customer_id: str, - conversion_custom_variable_id: str, - ) -> str: - """Returns a fully-qualified conversion_custom_variable string.""" - return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( - customer_id=customer_id, - conversion_custom_variable_id=conversion_custom_variable_id, - ) - - @staticmethod - def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: - """Parses a conversion_custom_variable path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - ConversionCustomVariableServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - ConversionCustomVariableServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = ConversionCustomVariableServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - ConversionCustomVariableServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionCustomVariableServiceTransport, - Callable[..., ConversionCustomVariableServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion custom variable service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionCustomVariableServiceTransport,Callable[..., ConversionCustomVariableServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionCustomVariableServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ConversionCustomVariableServiceClient._read_environment_variables() - self._client_cert_source = ( - ConversionCustomVariableServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - ConversionCustomVariableServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ConversionCustomVariableServiceTransport - ) - if transport_provided: - # transport is a ConversionCustomVariableServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - ConversionCustomVariableServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ConversionCustomVariableServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ConversionCustomVariableServiceTransport], - Callable[..., ConversionCustomVariableServiceTransport], - ] = ( - ConversionCustomVariableServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ConversionCustomVariableServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ConversionCustomVariableServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionCustomVariableService", - "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.ads.googleads.v19.services.ConversionCustomVariableService", - "credentialsType": None, - } - ), - ) - - def mutate_conversion_custom_variables( - self, - request: Optional[ - Union[ - conversion_custom_variable_service.MutateConversionCustomVariablesRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - conversion_custom_variable_service.ConversionCustomVariableOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - conversion_custom_variable_service.MutateConversionCustomVariablesResponse - ): - r"""Creates or updates conversion custom variables. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionCustomVariableError <>`__ - `DatabaseError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateConversionCustomVariablesRequest, dict]): - The request object. Request message for - [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v19.services.ConversionCustomVariableService.MutateConversionCustomVariables]. - customer_id (str): - Required. The ID of the customer - whose conversion custom variables are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.ConversionCustomVariableOperation]): - Required. The list of operations to - perform on individual conversion custom - variables. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateConversionCustomVariablesResponse: - Response message for - [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v19.services.ConversionCustomVariableService.MutateConversionCustomVariables]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - conversion_custom_variable_service.MutateConversionCustomVariablesRequest, - ): - request = conversion_custom_variable_service.MutateConversionCustomVariablesRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_conversion_custom_variables - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ConversionCustomVariableServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ConversionCustomVariableServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/base.py b/google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/base.py deleted file mode 100644 index b2992545f..000000000 --- a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - conversion_custom_variable_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ConversionCustomVariableServiceTransport(abc.ABC): - """Abstract transport class for ConversionCustomVariableService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_conversion_custom_variables: gapic_v1.method.wrap_method( - self.mutate_conversion_custom_variables, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_conversion_custom_variables( - self, - ) -> Callable[ - [ - conversion_custom_variable_service.MutateConversionCustomVariablesRequest - ], - Union[ - conversion_custom_variable_service.MutateConversionCustomVariablesResponse, - Awaitable[ - conversion_custom_variable_service.MutateConversionCustomVariablesResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ConversionCustomVariableServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/grpc.py b/google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/grpc.py deleted file mode 100644 index 44b76b053..000000000 --- a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/grpc.py +++ /dev/null @@ -1,394 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - conversion_custom_variable_service, -) -from .base import ConversionCustomVariableServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ConversionCustomVariableService", - "rpcName": str(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.ads.googleads.v19.services.ConversionCustomVariableService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionCustomVariableServiceGrpcTransport( - ConversionCustomVariableServiceTransport -): - """gRPC backend transport for ConversionCustomVariableService. - - Service to manage conversion custom variables. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_conversion_custom_variables( - self, - ) -> Callable[ - [ - conversion_custom_variable_service.MutateConversionCustomVariablesRequest - ], - conversion_custom_variable_service.MutateConversionCustomVariablesResponse, - ]: - r"""Return a callable for the mutate conversion custom - variables method over gRPC. - - Creates or updates conversion custom variables. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionCustomVariableError <>`__ - `DatabaseError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateConversionCustomVariablesRequest], - ~.MutateConversionCustomVariablesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_conversion_custom_variables" not in self._stubs: - self._stubs["mutate_conversion_custom_variables"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionCustomVariableService/MutateConversionCustomVariables", - request_serializer=conversion_custom_variable_service.MutateConversionCustomVariablesRequest.serialize, - response_deserializer=conversion_custom_variable_service.MutateConversionCustomVariablesResponse.deserialize, - ) - ) - return self._stubs["mutate_conversion_custom_variables"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ConversionCustomVariableServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/grpc_asyncio.py deleted file mode 100644 index 658ddbcb6..000000000 --- a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,417 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - conversion_custom_variable_service, -) -from .base import ConversionCustomVariableServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ConversionCustomVariableService", - "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.ads.googleads.v19.services.ConversionCustomVariableService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionCustomVariableServiceGrpcAsyncIOTransport( - ConversionCustomVariableServiceTransport -): - """gRPC AsyncIO backend transport for ConversionCustomVariableService. - - Service to manage conversion custom variables. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_conversion_custom_variables( - self, - ) -> Callable[ - [ - conversion_custom_variable_service.MutateConversionCustomVariablesRequest - ], - Awaitable[ - conversion_custom_variable_service.MutateConversionCustomVariablesResponse - ], - ]: - r"""Return a callable for the mutate conversion custom - variables method over gRPC. - - Creates or updates conversion custom variables. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionCustomVariableError <>`__ - `DatabaseError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateConversionCustomVariablesRequest], - Awaitable[~.MutateConversionCustomVariablesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_conversion_custom_variables" not in self._stubs: - self._stubs["mutate_conversion_custom_variables"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionCustomVariableService/MutateConversionCustomVariables", - request_serializer=conversion_custom_variable_service.MutateConversionCustomVariablesRequest.serialize, - response_deserializer=conversion_custom_variable_service.MutateConversionCustomVariablesResponse.deserialize, - ) - ) - return self._stubs["mutate_conversion_custom_variables"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_conversion_custom_variables: self._wrap_method( - self.mutate_conversion_custom_variables, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ConversionCustomVariableServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/async_client.py b/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/async_client.py deleted file mode 100644 index aebdb91b3..000000000 --- a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/async_client.py +++ /dev/null @@ -1,456 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - conversion_goal_campaign_config_service, -) -from .transports.base import ( - ConversionGoalCampaignConfigServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import ConversionGoalCampaignConfigServiceClient - -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 ConversionGoalCampaignConfigServiceAsyncClient: - """Service to manage conversion goal campaign config.""" - - _client: ConversionGoalCampaignConfigServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ( - ConversionGoalCampaignConfigServiceClient.DEFAULT_ENDPOINT - ) - DEFAULT_MTLS_ENDPOINT = ( - ConversionGoalCampaignConfigServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - ConversionGoalCampaignConfigServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ( - ConversionGoalCampaignConfigServiceClient._DEFAULT_UNIVERSE - ) - - campaign_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.campaign_path - ) - parse_campaign_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.parse_campaign_path - ) - conversion_goal_campaign_config_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.conversion_goal_campaign_config_path - ) - parse_conversion_goal_campaign_config_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.parse_conversion_goal_campaign_config_path - ) - custom_conversion_goal_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.custom_conversion_goal_path - ) - parse_custom_conversion_goal_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.parse_custom_conversion_goal_path - ) - common_billing_account_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ConversionGoalCampaignConfigServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionGoalCampaignConfigServiceAsyncClient: The constructed client. - """ - return ConversionGoalCampaignConfigServiceClient.from_service_account_info.__func__(ConversionGoalCampaignConfigServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionGoalCampaignConfigServiceAsyncClient: The constructed client. - """ - return ConversionGoalCampaignConfigServiceClient.from_service_account_file.__func__(ConversionGoalCampaignConfigServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ConversionGoalCampaignConfigServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ConversionGoalCampaignConfigServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionGoalCampaignConfigServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - ConversionGoalCampaignConfigServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionGoalCampaignConfigServiceTransport, - Callable[..., ConversionGoalCampaignConfigServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion goal campaign config service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionGoalCampaignConfigServiceTransport,Callable[..., ConversionGoalCampaignConfigServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionGoalCampaignConfigServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ConversionGoalCampaignConfigServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ConversionGoalCampaignConfigServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionGoalCampaignConfigService", - "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.ads.googleads.v19.services.ConversionGoalCampaignConfigService", - "credentialsType": None, - } - ), - ) - - async def mutate_conversion_goal_campaign_configs( - self, - request: Optional[ - Union[ - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - conversion_goal_campaign_config_service.ConversionGoalCampaignConfigOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse - ): - r"""Creates, updates or removes conversion goal campaign - config. Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateConversionGoalCampaignConfigsRequest, dict]]): - The request object. Request message for - [ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs][google.ads.googleads.v19.services.ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs]. - customer_id (:class:`str`): - Required. The ID of the customer - whose custom conversion goals are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.ConversionGoalCampaignConfigOperation]`): - Required. The list of operations to - perform on individual conversion goal - campaign config. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateConversionGoalCampaignConfigsResponse: - Response message for a conversion - goal campaign config mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest, - ): - request = conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_conversion_goal_campaign_configs - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__( - self, - ) -> "ConversionGoalCampaignConfigServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ConversionGoalCampaignConfigServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/client.py b/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/client.py deleted file mode 100644 index 5dfe8d750..000000000 --- a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/client.py +++ /dev/null @@ -1,947 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - conversion_goal_campaign_config_service, -) -from .transports.base import ( - ConversionGoalCampaignConfigServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ConversionGoalCampaignConfigServiceGrpcTransport -from .transports.grpc_asyncio import ( - ConversionGoalCampaignConfigServiceGrpcAsyncIOTransport, -) - - -class ConversionGoalCampaignConfigServiceClientMeta(type): - """Metaclass for the ConversionGoalCampaignConfigService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ConversionGoalCampaignConfigServiceTransport]] - _transport_registry["grpc"] = ( - ConversionGoalCampaignConfigServiceGrpcTransport - ) - _transport_registry["grpc_asyncio"] = ( - ConversionGoalCampaignConfigServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ConversionGoalCampaignConfigServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ConversionGoalCampaignConfigServiceClient( - metaclass=ConversionGoalCampaignConfigServiceClientMeta -): - """Service to manage conversion goal campaign config.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionGoalCampaignConfigServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionGoalCampaignConfigServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ConversionGoalCampaignConfigServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionGoalCampaignConfigServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_goal_campaign_config_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified conversion_goal_campaign_config string.""" - return "customers/{customer_id}/conversionGoalCampaignConfigs/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_conversion_goal_campaign_config_path(path: str) -> Dict[str, str]: - """Parses a conversion_goal_campaign_config path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionGoalCampaignConfigs/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def custom_conversion_goal_path( - customer_id: str, - goal_id: str, - ) -> str: - """Returns a fully-qualified custom_conversion_goal string.""" - return "customers/{customer_id}/customConversionGoals/{goal_id}".format( - customer_id=customer_id, - goal_id=goal_id, - ) - - @staticmethod - def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: - """Parses a custom_conversion_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - ConversionGoalCampaignConfigServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - ConversionGoalCampaignConfigServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = ConversionGoalCampaignConfigServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - ConversionGoalCampaignConfigServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionGoalCampaignConfigServiceTransport, - Callable[..., ConversionGoalCampaignConfigServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion goal campaign config service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionGoalCampaignConfigServiceTransport,Callable[..., ConversionGoalCampaignConfigServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionGoalCampaignConfigServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ( - ConversionGoalCampaignConfigServiceClient._read_environment_variables() - ) - self._client_cert_source = ( - ConversionGoalCampaignConfigServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - ConversionGoalCampaignConfigServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ConversionGoalCampaignConfigServiceTransport - ) - if transport_provided: - # transport is a ConversionGoalCampaignConfigServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - ConversionGoalCampaignConfigServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ConversionGoalCampaignConfigServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ConversionGoalCampaignConfigServiceTransport], - Callable[..., ConversionGoalCampaignConfigServiceTransport], - ] = ( - ConversionGoalCampaignConfigServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ConversionGoalCampaignConfigServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ConversionGoalCampaignConfigServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionGoalCampaignConfigService", - "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.ads.googleads.v19.services.ConversionGoalCampaignConfigService", - "credentialsType": None, - } - ), - ) - - def mutate_conversion_goal_campaign_configs( - self, - request: Optional[ - Union[ - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - conversion_goal_campaign_config_service.ConversionGoalCampaignConfigOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse - ): - r"""Creates, updates or removes conversion goal campaign - config. Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateConversionGoalCampaignConfigsRequest, dict]): - The request object. Request message for - [ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs][google.ads.googleads.v19.services.ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs]. - customer_id (str): - Required. The ID of the customer - whose custom conversion goals are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.ConversionGoalCampaignConfigOperation]): - Required. The list of operations to - perform on individual conversion goal - campaign config. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateConversionGoalCampaignConfigsResponse: - Response message for a conversion - goal campaign config mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest, - ): - request = conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_conversion_goal_campaign_configs - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ConversionGoalCampaignConfigServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ConversionGoalCampaignConfigServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/base.py b/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/base.py deleted file mode 100644 index dadbd6afa..000000000 --- a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - conversion_goal_campaign_config_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ConversionGoalCampaignConfigServiceTransport(abc.ABC): - """Abstract transport class for ConversionGoalCampaignConfigService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_conversion_goal_campaign_configs: gapic_v1.method.wrap_method( - self.mutate_conversion_goal_campaign_configs, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_conversion_goal_campaign_configs( - self, - ) -> Callable[ - [ - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest - ], - Union[ - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse, - Awaitable[ - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ConversionGoalCampaignConfigServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/grpc.py b/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/grpc.py deleted file mode 100644 index c25e6138f..000000000 --- a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/grpc.py +++ /dev/null @@ -1,392 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - conversion_goal_campaign_config_service, -) -from .base import ( - ConversionGoalCampaignConfigServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ConversionGoalCampaignConfigService", - "rpcName": str(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.ads.googleads.v19.services.ConversionGoalCampaignConfigService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionGoalCampaignConfigServiceGrpcTransport( - ConversionGoalCampaignConfigServiceTransport -): - """gRPC backend transport for ConversionGoalCampaignConfigService. - - Service to manage conversion goal campaign config. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_conversion_goal_campaign_configs( - self, - ) -> Callable[ - [ - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest - ], - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse, - ]: - r"""Return a callable for the mutate conversion goal - campaign configs method over gRPC. - - Creates, updates or removes conversion goal campaign - config. Operation statuses are returned. - - Returns: - Callable[[~.MutateConversionGoalCampaignConfigsRequest], - ~.MutateConversionGoalCampaignConfigsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_conversion_goal_campaign_configs" not in self._stubs: - self._stubs["mutate_conversion_goal_campaign_configs"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionGoalCampaignConfigService/MutateConversionGoalCampaignConfigs", - request_serializer=conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest.serialize, - response_deserializer=conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse.deserialize, - ) - ) - return self._stubs["mutate_conversion_goal_campaign_configs"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ConversionGoalCampaignConfigServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/grpc_asyncio.py deleted file mode 100644 index 3996c360e..000000000 --- a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,415 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - conversion_goal_campaign_config_service, -) -from .base import ( - ConversionGoalCampaignConfigServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ConversionGoalCampaignConfigService", - "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.ads.googleads.v19.services.ConversionGoalCampaignConfigService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionGoalCampaignConfigServiceGrpcAsyncIOTransport( - ConversionGoalCampaignConfigServiceTransport -): - """gRPC AsyncIO backend transport for ConversionGoalCampaignConfigService. - - Service to manage conversion goal campaign config. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_conversion_goal_campaign_configs( - self, - ) -> Callable[ - [ - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest - ], - Awaitable[ - conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse - ], - ]: - r"""Return a callable for the mutate conversion goal - campaign configs method over gRPC. - - Creates, updates or removes conversion goal campaign - config. Operation statuses are returned. - - Returns: - Callable[[~.MutateConversionGoalCampaignConfigsRequest], - Awaitable[~.MutateConversionGoalCampaignConfigsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_conversion_goal_campaign_configs" not in self._stubs: - self._stubs["mutate_conversion_goal_campaign_configs"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionGoalCampaignConfigService/MutateConversionGoalCampaignConfigs", - request_serializer=conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest.serialize, - response_deserializer=conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse.deserialize, - ) - ) - return self._stubs["mutate_conversion_goal_campaign_configs"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_conversion_goal_campaign_configs: self._wrap_method( - self.mutate_conversion_goal_campaign_configs, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ConversionGoalCampaignConfigServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_upload_service/async_client.py b/google/ads/googleads/v19/services/services/conversion_upload_service/async_client.py deleted file mode 100644 index 044c9e1c0..000000000 --- a/google/ads/googleads/v19/services/services/conversion_upload_service/async_client.py +++ /dev/null @@ -1,575 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import conversion_upload_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionUploadServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import ConversionUploadServiceClient - -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 ConversionUploadServiceAsyncClient: - """Service to upload conversions.""" - - _client: ConversionUploadServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ConversionUploadServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ConversionUploadServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - ConversionUploadServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ConversionUploadServiceClient._DEFAULT_UNIVERSE - - conversion_custom_variable_path = staticmethod( - ConversionUploadServiceClient.conversion_custom_variable_path - ) - parse_conversion_custom_variable_path = staticmethod( - ConversionUploadServiceClient.parse_conversion_custom_variable_path - ) - common_billing_account_path = staticmethod( - ConversionUploadServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ConversionUploadServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ConversionUploadServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ConversionUploadServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ConversionUploadServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ConversionUploadServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ConversionUploadServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ConversionUploadServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ConversionUploadServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ConversionUploadServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionUploadServiceAsyncClient: The constructed client. - """ - return ConversionUploadServiceClient.from_service_account_info.__func__(ConversionUploadServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionUploadServiceAsyncClient: The constructed client. - """ - return ConversionUploadServiceClient.from_service_account_file.__func__(ConversionUploadServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ConversionUploadServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ConversionUploadServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionUploadServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ConversionUploadServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionUploadServiceTransport, - Callable[..., ConversionUploadServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion upload service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionUploadServiceTransport,Callable[..., ConversionUploadServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionUploadServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ConversionUploadServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ConversionUploadServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionUploadService", - "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.ads.googleads.v19.services.ConversionUploadService", - "credentialsType": None, - } - ), - ) - - async def upload_click_conversions( - self, - request: Optional[ - Union[conversion_upload_service.UploadClickConversionsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - conversions: Optional[ - MutableSequence[conversion_upload_service.ClickConversion] - ] = None, - partial_failure: Optional[bool] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> conversion_upload_service.UploadClickConversionsResponse: - r"""Processes the given click conversions. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionUploadError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.UploadClickConversionsRequest, dict]]): - The request object. Request message for - [ConversionUploadService.UploadClickConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadClickConversions]. - customer_id (:class:`str`): - Required. The ID of the customer - performing the upload. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - conversions (:class:`MutableSequence[google.ads.googleads.v19.services.types.ClickConversion]`): - Required. The conversions that are - being uploaded. - - This corresponds to the ``conversions`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - partial_failure (:class:`bool`): - Required. If true, successful - operations will be carried out and - invalid operations will return errors. - If false, all operations will be carried - out in one transaction if and only if - they are all valid. This should always - be set to true. - See - https://developers.google.com/google-ads/api/docs/best-practices/partial-failures - for more information about partial - failure. - - This corresponds to the ``partial_failure`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UploadClickConversionsResponse: - Response message for - [ConversionUploadService.UploadClickConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadClickConversions]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, conversions, partial_failure] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, conversion_upload_service.UploadClickConversionsRequest - ): - request = conversion_upload_service.UploadClickConversionsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if partial_failure is not None: - request.partial_failure = partial_failure - if conversions: - request.conversions.extend(conversions) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.upload_click_conversions - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def upload_call_conversions( - self, - request: Optional[ - Union[conversion_upload_service.UploadCallConversionsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - conversions: Optional[ - MutableSequence[conversion_upload_service.CallConversion] - ] = None, - partial_failure: Optional[bool] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> conversion_upload_service.UploadCallConversionsResponse: - r"""Processes the given call conversions. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PartialFailureError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.UploadCallConversionsRequest, dict]]): - The request object. Request message for - [ConversionUploadService.UploadCallConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadCallConversions]. - customer_id (:class:`str`): - Required. The ID of the customer - performing the upload. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - conversions (:class:`MutableSequence[google.ads.googleads.v19.services.types.CallConversion]`): - Required. The conversions that are - being uploaded. - - This corresponds to the ``conversions`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - partial_failure (:class:`bool`): - Required. If true, successful - operations will be carried out and - invalid operations will return errors. - If false, all operations will be carried - out in one transaction if and only if - they are all valid. This should always - be set to true. - See - https://developers.google.com/google-ads/api/docs/best-practices/partial-failures - for more information about partial - failure. - - This corresponds to the ``partial_failure`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UploadCallConversionsResponse: - Response message for - [ConversionUploadService.UploadCallConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadCallConversions]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, conversions, partial_failure] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, conversion_upload_service.UploadCallConversionsRequest - ): - request = conversion_upload_service.UploadCallConversionsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if partial_failure is not None: - request.partial_failure = partial_failure - if conversions: - request.conversions.extend(conversions) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.upload_call_conversions - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ConversionUploadServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ConversionUploadServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_upload_service/client.py b/google/ads/googleads/v19/services/services/conversion_upload_service/client.py deleted file mode 100644 index 57ce9ead0..000000000 --- a/google/ads/googleads/v19/services/services/conversion_upload_service/client.py +++ /dev/null @@ -1,1032 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import conversion_upload_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionUploadServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ConversionUploadServiceGrpcTransport -from .transports.grpc_asyncio import ConversionUploadServiceGrpcAsyncIOTransport - - -class ConversionUploadServiceClientMeta(type): - """Metaclass for the ConversionUploadService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ConversionUploadServiceTransport]] - _transport_registry["grpc"] = ConversionUploadServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - ConversionUploadServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ConversionUploadServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ConversionUploadServiceClient( - metaclass=ConversionUploadServiceClientMeta -): - """Service to upload conversions.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionUploadServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionUploadServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ConversionUploadServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionUploadServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def conversion_custom_variable_path( - customer_id: str, - conversion_custom_variable_id: str, - ) -> str: - """Returns a fully-qualified conversion_custom_variable string.""" - return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( - customer_id=customer_id, - conversion_custom_variable_id=conversion_custom_variable_id, - ) - - @staticmethod - def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: - """Parses a conversion_custom_variable path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ConversionUploadServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ConversionUploadServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - ConversionUploadServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ConversionUploadServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionUploadServiceTransport, - Callable[..., ConversionUploadServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion upload service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionUploadServiceTransport,Callable[..., ConversionUploadServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionUploadServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ConversionUploadServiceClient._read_environment_variables() - self._client_cert_source = ( - ConversionUploadServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - ConversionUploadServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ConversionUploadServiceTransport - ) - if transport_provided: - # transport is a ConversionUploadServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(ConversionUploadServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ConversionUploadServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ConversionUploadServiceTransport], - Callable[..., ConversionUploadServiceTransport], - ] = ( - ConversionUploadServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ConversionUploadServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ConversionUploadServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionUploadService", - "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.ads.googleads.v19.services.ConversionUploadService", - "credentialsType": None, - } - ), - ) - - def upload_click_conversions( - self, - request: Optional[ - Union[conversion_upload_service.UploadClickConversionsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - conversions: Optional[ - MutableSequence[conversion_upload_service.ClickConversion] - ] = None, - partial_failure: Optional[bool] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> conversion_upload_service.UploadClickConversionsResponse: - r"""Processes the given click conversions. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionUploadError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.UploadClickConversionsRequest, dict]): - The request object. Request message for - [ConversionUploadService.UploadClickConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadClickConversions]. - customer_id (str): - Required. The ID of the customer - performing the upload. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - conversions (MutableSequence[google.ads.googleads.v19.services.types.ClickConversion]): - Required. The conversions that are - being uploaded. - - This corresponds to the ``conversions`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - partial_failure (bool): - Required. If true, successful - operations will be carried out and - invalid operations will return errors. - If false, all operations will be carried - out in one transaction if and only if - they are all valid. This should always - be set to true. - See - https://developers.google.com/google-ads/api/docs/best-practices/partial-failures - for more information about partial - failure. - - This corresponds to the ``partial_failure`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UploadClickConversionsResponse: - Response message for - [ConversionUploadService.UploadClickConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadClickConversions]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, conversions, partial_failure] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, conversion_upload_service.UploadClickConversionsRequest - ): - request = conversion_upload_service.UploadClickConversionsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if conversions is not None: - request.conversions = conversions - if partial_failure is not None: - request.partial_failure = partial_failure - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.upload_click_conversions - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def upload_call_conversions( - self, - request: Optional[ - Union[conversion_upload_service.UploadCallConversionsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - conversions: Optional[ - MutableSequence[conversion_upload_service.CallConversion] - ] = None, - partial_failure: Optional[bool] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> conversion_upload_service.UploadCallConversionsResponse: - r"""Processes the given call conversions. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PartialFailureError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.UploadCallConversionsRequest, dict]): - The request object. Request message for - [ConversionUploadService.UploadCallConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadCallConversions]. - customer_id (str): - Required. The ID of the customer - performing the upload. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - conversions (MutableSequence[google.ads.googleads.v19.services.types.CallConversion]): - Required. The conversions that are - being uploaded. - - This corresponds to the ``conversions`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - partial_failure (bool): - Required. If true, successful - operations will be carried out and - invalid operations will return errors. - If false, all operations will be carried - out in one transaction if and only if - they are all valid. This should always - be set to true. - See - https://developers.google.com/google-ads/api/docs/best-practices/partial-failures - for more information about partial - failure. - - This corresponds to the ``partial_failure`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UploadCallConversionsResponse: - Response message for - [ConversionUploadService.UploadCallConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadCallConversions]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, conversions, partial_failure] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, conversion_upload_service.UploadCallConversionsRequest - ): - request = conversion_upload_service.UploadCallConversionsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if conversions is not None: - request.conversions = conversions - if partial_failure is not None: - request.partial_failure = partial_failure - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.upload_call_conversions - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ConversionUploadServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ConversionUploadServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_upload_service/transports/base.py b/google/ads/googleads/v19/services/services/conversion_upload_service/transports/base.py deleted file mode 100644 index 26dd4d05a..000000000 --- a/google/ads/googleads/v19/services/services/conversion_upload_service/transports/base.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import conversion_upload_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ConversionUploadServiceTransport(abc.ABC): - """Abstract transport class for ConversionUploadService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.upload_click_conversions: gapic_v1.method.wrap_method( - self.upload_click_conversions, - default_timeout=None, - client_info=client_info, - ), - self.upload_call_conversions: gapic_v1.method.wrap_method( - self.upload_call_conversions, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def upload_click_conversions( - self, - ) -> Callable[ - [conversion_upload_service.UploadClickConversionsRequest], - Union[ - conversion_upload_service.UploadClickConversionsResponse, - Awaitable[conversion_upload_service.UploadClickConversionsResponse], - ], - ]: - raise NotImplementedError() - - @property - def upload_call_conversions( - self, - ) -> Callable[ - [conversion_upload_service.UploadCallConversionsRequest], - Union[ - conversion_upload_service.UploadCallConversionsResponse, - Awaitable[conversion_upload_service.UploadCallConversionsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ConversionUploadServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_upload_service/transports/grpc.py b/google/ads/googleads/v19/services/services/conversion_upload_service/transports/grpc.py deleted file mode 100644 index f11fca298..000000000 --- a/google/ads/googleads/v19/services/services/conversion_upload_service/transports/grpc.py +++ /dev/null @@ -1,422 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import conversion_upload_service -from .base import ConversionUploadServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ConversionUploadService", - "rpcName": str(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.ads.googleads.v19.services.ConversionUploadService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionUploadServiceGrpcTransport(ConversionUploadServiceTransport): - """gRPC backend transport for ConversionUploadService. - - Service to upload conversions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def upload_click_conversions( - self, - ) -> Callable[ - [conversion_upload_service.UploadClickConversionsRequest], - conversion_upload_service.UploadClickConversionsResponse, - ]: - r"""Return a callable for the upload click conversions method over gRPC. - - Processes the given click conversions. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionUploadError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.UploadClickConversionsRequest], - ~.UploadClickConversionsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "upload_click_conversions" not in self._stubs: - self._stubs["upload_click_conversions"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionUploadService/UploadClickConversions", - request_serializer=conversion_upload_service.UploadClickConversionsRequest.serialize, - response_deserializer=conversion_upload_service.UploadClickConversionsResponse.deserialize, - ) - ) - return self._stubs["upload_click_conversions"] - - @property - def upload_call_conversions( - self, - ) -> Callable[ - [conversion_upload_service.UploadCallConversionsRequest], - conversion_upload_service.UploadCallConversionsResponse, - ]: - r"""Return a callable for the upload call conversions method over gRPC. - - Processes the given call conversions. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PartialFailureError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.UploadCallConversionsRequest], - ~.UploadCallConversionsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "upload_call_conversions" not in self._stubs: - self._stubs["upload_call_conversions"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionUploadService/UploadCallConversions", - request_serializer=conversion_upload_service.UploadCallConversionsRequest.serialize, - response_deserializer=conversion_upload_service.UploadCallConversionsResponse.deserialize, - ) - ) - return self._stubs["upload_call_conversions"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ConversionUploadServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_upload_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/conversion_upload_service/transports/grpc_asyncio.py deleted file mode 100644 index 959306fd3..000000000 --- a/google/ads/googleads/v19/services/services/conversion_upload_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,450 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import conversion_upload_service -from .base import ConversionUploadServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ConversionUploadService", - "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.ads.googleads.v19.services.ConversionUploadService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionUploadServiceGrpcAsyncIOTransport( - ConversionUploadServiceTransport -): - """gRPC AsyncIO backend transport for ConversionUploadService. - - Service to upload conversions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def upload_click_conversions( - self, - ) -> Callable[ - [conversion_upload_service.UploadClickConversionsRequest], - Awaitable[conversion_upload_service.UploadClickConversionsResponse], - ]: - r"""Return a callable for the upload click conversions method over gRPC. - - Processes the given click conversions. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionUploadError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.UploadClickConversionsRequest], - Awaitable[~.UploadClickConversionsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "upload_click_conversions" not in self._stubs: - self._stubs["upload_click_conversions"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionUploadService/UploadClickConversions", - request_serializer=conversion_upload_service.UploadClickConversionsRequest.serialize, - response_deserializer=conversion_upload_service.UploadClickConversionsResponse.deserialize, - ) - ) - return self._stubs["upload_click_conversions"] - - @property - def upload_call_conversions( - self, - ) -> Callable[ - [conversion_upload_service.UploadCallConversionsRequest], - Awaitable[conversion_upload_service.UploadCallConversionsResponse], - ]: - r"""Return a callable for the upload call conversions method over gRPC. - - Processes the given call conversions. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PartialFailureError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.UploadCallConversionsRequest], - Awaitable[~.UploadCallConversionsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "upload_call_conversions" not in self._stubs: - self._stubs["upload_call_conversions"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionUploadService/UploadCallConversions", - request_serializer=conversion_upload_service.UploadCallConversionsRequest.serialize, - response_deserializer=conversion_upload_service.UploadCallConversionsResponse.deserialize, - ) - ) - return self._stubs["upload_call_conversions"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.upload_click_conversions: self._wrap_method( - self.upload_click_conversions, - default_timeout=None, - client_info=client_info, - ), - self.upload_call_conversions: self._wrap_method( - self.upload_call_conversions, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ConversionUploadServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_service/async_client.py b/google/ads/googleads/v19/services/services/conversion_value_rule_service/async_client.py deleted file mode 100644 index 62cb6fd4d..000000000 --- a/google/ads/googleads/v19/services/services/conversion_value_rule_service/async_client.py +++ /dev/null @@ -1,459 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - conversion_value_rule_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionValueRuleServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import ConversionValueRuleServiceClient - -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 ConversionValueRuleServiceAsyncClient: - """Service to manage conversion value rules.""" - - _client: ConversionValueRuleServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ConversionValueRuleServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - ConversionValueRuleServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - ConversionValueRuleServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ConversionValueRuleServiceClient._DEFAULT_UNIVERSE - - conversion_value_rule_path = staticmethod( - ConversionValueRuleServiceClient.conversion_value_rule_path - ) - parse_conversion_value_rule_path = staticmethod( - ConversionValueRuleServiceClient.parse_conversion_value_rule_path - ) - customer_path = staticmethod(ConversionValueRuleServiceClient.customer_path) - parse_customer_path = staticmethod( - ConversionValueRuleServiceClient.parse_customer_path - ) - geo_target_constant_path = staticmethod( - ConversionValueRuleServiceClient.geo_target_constant_path - ) - parse_geo_target_constant_path = staticmethod( - ConversionValueRuleServiceClient.parse_geo_target_constant_path - ) - user_interest_path = staticmethod( - ConversionValueRuleServiceClient.user_interest_path - ) - parse_user_interest_path = staticmethod( - ConversionValueRuleServiceClient.parse_user_interest_path - ) - user_list_path = staticmethod( - ConversionValueRuleServiceClient.user_list_path - ) - parse_user_list_path = staticmethod( - ConversionValueRuleServiceClient.parse_user_list_path - ) - common_billing_account_path = staticmethod( - ConversionValueRuleServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ConversionValueRuleServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ConversionValueRuleServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ConversionValueRuleServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ConversionValueRuleServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ConversionValueRuleServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ConversionValueRuleServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ConversionValueRuleServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ConversionValueRuleServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ConversionValueRuleServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionValueRuleServiceAsyncClient: The constructed client. - """ - return ConversionValueRuleServiceClient.from_service_account_info.__func__(ConversionValueRuleServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionValueRuleServiceAsyncClient: The constructed client. - """ - return ConversionValueRuleServiceClient.from_service_account_file.__func__(ConversionValueRuleServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ConversionValueRuleServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ConversionValueRuleServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionValueRuleServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ConversionValueRuleServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionValueRuleServiceTransport, - Callable[..., ConversionValueRuleServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion value rule service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionValueRuleServiceTransport,Callable[..., ConversionValueRuleServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionValueRuleServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ConversionValueRuleServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ConversionValueRuleServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionValueRuleService", - "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.ads.googleads.v19.services.ConversionValueRuleService", - "credentialsType": None, - } - ), - ) - - async def mutate_conversion_value_rules( - self, - request: Optional[ - Union[ - conversion_value_rule_service.MutateConversionValueRulesRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - conversion_value_rule_service.ConversionValueRuleOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> conversion_value_rule_service.MutateConversionValueRulesResponse: - r"""Creates, updates, or removes conversion value rules. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateConversionValueRulesRequest, dict]]): - The request object. Request message for - [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v19.services.ConversionValueRuleService.MutateConversionValueRules]. - customer_id (:class:`str`): - Required. The ID of the customer - whose conversion value rules are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.ConversionValueRuleOperation]`): - Required. The list of operations to - perform on individual conversion value - rules. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateConversionValueRulesResponse: - Response message for - [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v19.services.ConversionValueRuleService.MutateConversionValueRules]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - conversion_value_rule_service.MutateConversionValueRulesRequest, - ): - request = ( - conversion_value_rule_service.MutateConversionValueRulesRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_conversion_value_rules - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ConversionValueRuleServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ConversionValueRuleServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_service/client.py b/google/ads/googleads/v19/services/services/conversion_value_rule_service/client.py deleted file mode 100644 index b929fbfb9..000000000 --- a/google/ads/googleads/v19/services/services/conversion_value_rule_service/client.py +++ /dev/null @@ -1,972 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - conversion_value_rule_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionValueRuleServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ConversionValueRuleServiceGrpcTransport -from .transports.grpc_asyncio import ( - ConversionValueRuleServiceGrpcAsyncIOTransport, -) - - -class ConversionValueRuleServiceClientMeta(type): - """Metaclass for the ConversionValueRuleService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ConversionValueRuleServiceTransport]] - _transport_registry["grpc"] = ConversionValueRuleServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - ConversionValueRuleServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ConversionValueRuleServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ConversionValueRuleServiceClient( - metaclass=ConversionValueRuleServiceClientMeta -): - """Service to manage conversion value rules.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionValueRuleServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionValueRuleServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ConversionValueRuleServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionValueRuleServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def conversion_value_rule_path( - customer_id: str, - conversion_value_rule_id: str, - ) -> str: - """Returns a fully-qualified conversion_value_rule string.""" - return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( - customer_id=customer_id, - conversion_value_rule_id=conversion_value_rule_id, - ) - - @staticmethod - def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: - """Parses a conversion_value_rule path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def geo_target_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified geo_target_constant string.""" - return "geoTargetConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_geo_target_constant_path(path: str) -> Dict[str, str]: - """Parses a geo_target_constant path into its component segments.""" - m = re.match(r"^geoTargetConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def user_interest_path( - customer_id: str, - user_interest_id: str, - ) -> str: - """Returns a fully-qualified user_interest string.""" - return ( - "customers/{customer_id}/userInterests/{user_interest_id}".format( - customer_id=customer_id, - user_interest_id=user_interest_id, - ) - ) - - @staticmethod - def parse_user_interest_path(path: str) -> Dict[str, str]: - """Parses a user_interest path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/userInterests/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def user_list_path( - customer_id: str, - user_list_id: str, - ) -> str: - """Returns a fully-qualified user_list string.""" - return "customers/{customer_id}/userLists/{user_list_id}".format( - customer_id=customer_id, - user_list_id=user_list_id, - ) - - @staticmethod - def parse_user_list_path(path: str) -> Dict[str, str]: - """Parses a user_list path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/userLists/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - ConversionValueRuleServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - ConversionValueRuleServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = ConversionValueRuleServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ConversionValueRuleServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionValueRuleServiceTransport, - Callable[..., ConversionValueRuleServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion value rule service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionValueRuleServiceTransport,Callable[..., ConversionValueRuleServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionValueRuleServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ConversionValueRuleServiceClient._read_environment_variables() - self._client_cert_source = ( - ConversionValueRuleServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - ConversionValueRuleServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ConversionValueRuleServiceTransport - ) - if transport_provided: - # transport is a ConversionValueRuleServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - ConversionValueRuleServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ConversionValueRuleServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ConversionValueRuleServiceTransport], - Callable[..., ConversionValueRuleServiceTransport], - ] = ( - ConversionValueRuleServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ConversionValueRuleServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ConversionValueRuleServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionValueRuleService", - "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.ads.googleads.v19.services.ConversionValueRuleService", - "credentialsType": None, - } - ), - ) - - def mutate_conversion_value_rules( - self, - request: Optional[ - Union[ - conversion_value_rule_service.MutateConversionValueRulesRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - conversion_value_rule_service.ConversionValueRuleOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> conversion_value_rule_service.MutateConversionValueRulesResponse: - r"""Creates, updates, or removes conversion value rules. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateConversionValueRulesRequest, dict]): - The request object. Request message for - [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v19.services.ConversionValueRuleService.MutateConversionValueRules]. - customer_id (str): - Required. The ID of the customer - whose conversion value rules are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.ConversionValueRuleOperation]): - Required. The list of operations to - perform on individual conversion value - rules. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateConversionValueRulesResponse: - Response message for - [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v19.services.ConversionValueRuleService.MutateConversionValueRules]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - conversion_value_rule_service.MutateConversionValueRulesRequest, - ): - request = ( - conversion_value_rule_service.MutateConversionValueRulesRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_conversion_value_rules - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ConversionValueRuleServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ConversionValueRuleServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/base.py b/google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/base.py deleted file mode 100644 index 37023b6c4..000000000 --- a/google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - conversion_value_rule_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ConversionValueRuleServiceTransport(abc.ABC): - """Abstract transport class for ConversionValueRuleService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_conversion_value_rules: gapic_v1.method.wrap_method( - self.mutate_conversion_value_rules, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_conversion_value_rules( - self, - ) -> Callable[ - [conversion_value_rule_service.MutateConversionValueRulesRequest], - Union[ - conversion_value_rule_service.MutateConversionValueRulesResponse, - Awaitable[ - conversion_value_rule_service.MutateConversionValueRulesResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ConversionValueRuleServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/grpc.py b/google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/grpc.py deleted file mode 100644 index 85ba33649..000000000 --- a/google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/grpc.py +++ /dev/null @@ -1,386 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - conversion_value_rule_service, -) -from .base import ConversionValueRuleServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ConversionValueRuleService", - "rpcName": str(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.ads.googleads.v19.services.ConversionValueRuleService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionValueRuleServiceGrpcTransport( - ConversionValueRuleServiceTransport -): - """gRPC backend transport for ConversionValueRuleService. - - Service to manage conversion value rules. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_conversion_value_rules( - self, - ) -> Callable[ - [conversion_value_rule_service.MutateConversionValueRulesRequest], - conversion_value_rule_service.MutateConversionValueRulesResponse, - ]: - r"""Return a callable for the mutate conversion value rules method over gRPC. - - Creates, updates, or removes conversion value rules. - Operation statuses are returned. - - Returns: - Callable[[~.MutateConversionValueRulesRequest], - ~.MutateConversionValueRulesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_conversion_value_rules" not in self._stubs: - self._stubs["mutate_conversion_value_rules"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionValueRuleService/MutateConversionValueRules", - request_serializer=conversion_value_rule_service.MutateConversionValueRulesRequest.serialize, - response_deserializer=conversion_value_rule_service.MutateConversionValueRulesResponse.deserialize, - ) - ) - return self._stubs["mutate_conversion_value_rules"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ConversionValueRuleServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/grpc_asyncio.py deleted file mode 100644 index f8037c73a..000000000 --- a/google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - conversion_value_rule_service, -) -from .base import ConversionValueRuleServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ConversionValueRuleService", - "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.ads.googleads.v19.services.ConversionValueRuleService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionValueRuleServiceGrpcAsyncIOTransport( - ConversionValueRuleServiceTransport -): - """gRPC AsyncIO backend transport for ConversionValueRuleService. - - Service to manage conversion value rules. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_conversion_value_rules( - self, - ) -> Callable[ - [conversion_value_rule_service.MutateConversionValueRulesRequest], - Awaitable[ - conversion_value_rule_service.MutateConversionValueRulesResponse - ], - ]: - r"""Return a callable for the mutate conversion value rules method over gRPC. - - Creates, updates, or removes conversion value rules. - Operation statuses are returned. - - Returns: - Callable[[~.MutateConversionValueRulesRequest], - Awaitable[~.MutateConversionValueRulesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_conversion_value_rules" not in self._stubs: - self._stubs["mutate_conversion_value_rules"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionValueRuleService/MutateConversionValueRules", - request_serializer=conversion_value_rule_service.MutateConversionValueRulesRequest.serialize, - response_deserializer=conversion_value_rule_service.MutateConversionValueRulesResponse.deserialize, - ) - ) - return self._stubs["mutate_conversion_value_rules"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_conversion_value_rules: self._wrap_method( - self.mutate_conversion_value_rules, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ConversionValueRuleServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/async_client.py b/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/async_client.py deleted file mode 100644 index 3f7a3374b..000000000 --- a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/async_client.py +++ /dev/null @@ -1,457 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - conversion_value_rule_set_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionValueRuleSetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import ConversionValueRuleSetServiceClient - -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 ConversionValueRuleSetServiceAsyncClient: - """Service to manage conversion value rule sets.""" - - _client: ConversionValueRuleSetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ConversionValueRuleSetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - ConversionValueRuleSetServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - ConversionValueRuleSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ConversionValueRuleSetServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod( - ConversionValueRuleSetServiceClient.campaign_path - ) - parse_campaign_path = staticmethod( - ConversionValueRuleSetServiceClient.parse_campaign_path - ) - conversion_value_rule_path = staticmethod( - ConversionValueRuleSetServiceClient.conversion_value_rule_path - ) - parse_conversion_value_rule_path = staticmethod( - ConversionValueRuleSetServiceClient.parse_conversion_value_rule_path - ) - conversion_value_rule_set_path = staticmethod( - ConversionValueRuleSetServiceClient.conversion_value_rule_set_path - ) - parse_conversion_value_rule_set_path = staticmethod( - ConversionValueRuleSetServiceClient.parse_conversion_value_rule_set_path - ) - customer_path = staticmethod( - ConversionValueRuleSetServiceClient.customer_path - ) - parse_customer_path = staticmethod( - ConversionValueRuleSetServiceClient.parse_customer_path - ) - common_billing_account_path = staticmethod( - ConversionValueRuleSetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ConversionValueRuleSetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ConversionValueRuleSetServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ConversionValueRuleSetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ConversionValueRuleSetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ConversionValueRuleSetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ConversionValueRuleSetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ConversionValueRuleSetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ConversionValueRuleSetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ConversionValueRuleSetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionValueRuleSetServiceAsyncClient: The constructed client. - """ - return ConversionValueRuleSetServiceClient.from_service_account_info.__func__(ConversionValueRuleSetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionValueRuleSetServiceAsyncClient: The constructed client. - """ - return ConversionValueRuleSetServiceClient.from_service_account_file.__func__(ConversionValueRuleSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ConversionValueRuleSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ConversionValueRuleSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionValueRuleSetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - ConversionValueRuleSetServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionValueRuleSetServiceTransport, - Callable[..., ConversionValueRuleSetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion value rule set service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionValueRuleSetServiceTransport,Callable[..., ConversionValueRuleSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionValueRuleSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ConversionValueRuleSetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ConversionValueRuleSetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionValueRuleSetService", - "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.ads.googleads.v19.services.ConversionValueRuleSetService", - "credentialsType": None, - } - ), - ) - - async def mutate_conversion_value_rule_sets( - self, - request: Optional[ - Union[ - conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - conversion_value_rule_set_service.ConversionValueRuleSetOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse - ): - r"""Creates, updates or removes conversion value rule - sets. Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateConversionValueRuleSetsRequest, dict]]): - The request object. Request message for - [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v19.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose conversion value rule sets are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.ConversionValueRuleSetOperation]`): - Required. The list of operations to - perform on individual conversion value - rule sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateConversionValueRuleSetsResponse: - Response message for - [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v19.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest, - ): - request = conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_conversion_value_rule_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ConversionValueRuleSetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ConversionValueRuleSetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/client.py b/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/client.py deleted file mode 100644 index e5b2e72c3..000000000 --- a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/client.py +++ /dev/null @@ -1,957 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - conversion_value_rule_set_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - ConversionValueRuleSetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ConversionValueRuleSetServiceGrpcTransport -from .transports.grpc_asyncio import ( - ConversionValueRuleSetServiceGrpcAsyncIOTransport, -) - - -class ConversionValueRuleSetServiceClientMeta(type): - """Metaclass for the ConversionValueRuleSetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ConversionValueRuleSetServiceTransport]] - _transport_registry["grpc"] = ConversionValueRuleSetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - ConversionValueRuleSetServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ConversionValueRuleSetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ConversionValueRuleSetServiceClient( - metaclass=ConversionValueRuleSetServiceClientMeta -): - """Service to manage conversion value rule sets.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionValueRuleSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ConversionValueRuleSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ConversionValueRuleSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ConversionValueRuleSetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_value_rule_path( - customer_id: str, - conversion_value_rule_id: str, - ) -> str: - """Returns a fully-qualified conversion_value_rule string.""" - return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( - customer_id=customer_id, - conversion_value_rule_id=conversion_value_rule_id, - ) - - @staticmethod - def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: - """Parses a conversion_value_rule path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_value_rule_set_path( - customer_id: str, - conversion_value_rule_set_id: str, - ) -> str: - """Returns a fully-qualified conversion_value_rule_set string.""" - return "customers/{customer_id}/conversionValueRuleSets/{conversion_value_rule_set_id}".format( - customer_id=customer_id, - conversion_value_rule_set_id=conversion_value_rule_set_id, - ) - - @staticmethod - def parse_conversion_value_rule_set_path(path: str) -> Dict[str, str]: - """Parses a conversion_value_rule_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionValueRuleSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - ConversionValueRuleSetServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - ConversionValueRuleSetServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = ConversionValueRuleSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ConversionValueRuleSetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ConversionValueRuleSetServiceTransport, - Callable[..., ConversionValueRuleSetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the conversion value rule set service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ConversionValueRuleSetServiceTransport,Callable[..., ConversionValueRuleSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ConversionValueRuleSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ConversionValueRuleSetServiceClient._read_environment_variables() - self._client_cert_source = ( - ConversionValueRuleSetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - ConversionValueRuleSetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ConversionValueRuleSetServiceTransport - ) - if transport_provided: - # transport is a ConversionValueRuleSetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - ConversionValueRuleSetServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ConversionValueRuleSetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ConversionValueRuleSetServiceTransport], - Callable[..., ConversionValueRuleSetServiceTransport], - ] = ( - ConversionValueRuleSetServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ConversionValueRuleSetServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ConversionValueRuleSetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ConversionValueRuleSetService", - "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.ads.googleads.v19.services.ConversionValueRuleSetService", - "credentialsType": None, - } - ), - ) - - def mutate_conversion_value_rule_sets( - self, - request: Optional[ - Union[ - conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - conversion_value_rule_set_service.ConversionValueRuleSetOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse - ): - r"""Creates, updates or removes conversion value rule - sets. Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateConversionValueRuleSetsRequest, dict]): - The request object. Request message for - [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v19.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. - customer_id (str): - Required. The ID of the customer - whose conversion value rule sets are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.ConversionValueRuleSetOperation]): - Required. The list of operations to - perform on individual conversion value - rule sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateConversionValueRuleSetsResponse: - Response message for - [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v19.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest, - ): - request = conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_conversion_value_rule_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ConversionValueRuleSetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ConversionValueRuleSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/base.py b/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/base.py deleted file mode 100644 index 4247e5d44..000000000 --- a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - conversion_value_rule_set_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ConversionValueRuleSetServiceTransport(abc.ABC): - """Abstract transport class for ConversionValueRuleSetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_conversion_value_rule_sets: gapic_v1.method.wrap_method( - self.mutate_conversion_value_rule_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_conversion_value_rule_sets( - self, - ) -> Callable[ - [ - conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest - ], - Union[ - conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse, - Awaitable[ - conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ConversionValueRuleSetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/grpc.py b/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/grpc.py deleted file mode 100644 index 314627ad3..000000000 --- a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/grpc.py +++ /dev/null @@ -1,389 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - conversion_value_rule_set_service, -) -from .base import ConversionValueRuleSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ConversionValueRuleSetService", - "rpcName": str(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.ads.googleads.v19.services.ConversionValueRuleSetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionValueRuleSetServiceGrpcTransport( - ConversionValueRuleSetServiceTransport -): - """gRPC backend transport for ConversionValueRuleSetService. - - Service to manage conversion value rule sets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_conversion_value_rule_sets( - self, - ) -> Callable[ - [ - conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest - ], - conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse, - ]: - r"""Return a callable for the mutate conversion value rule - sets method over gRPC. - - Creates, updates or removes conversion value rule - sets. Operation statuses are returned. - - Returns: - Callable[[~.MutateConversionValueRuleSetsRequest], - ~.MutateConversionValueRuleSetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_conversion_value_rule_sets" not in self._stubs: - self._stubs["mutate_conversion_value_rule_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionValueRuleSetService/MutateConversionValueRuleSets", - request_serializer=conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest.serialize, - response_deserializer=conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_conversion_value_rule_sets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ConversionValueRuleSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/grpc_asyncio.py deleted file mode 100644 index 44649b2f0..000000000 --- a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,412 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - conversion_value_rule_set_service, -) -from .base import ConversionValueRuleSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ConversionValueRuleSetService", - "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.ads.googleads.v19.services.ConversionValueRuleSetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ConversionValueRuleSetServiceGrpcAsyncIOTransport( - ConversionValueRuleSetServiceTransport -): - """gRPC AsyncIO backend transport for ConversionValueRuleSetService. - - Service to manage conversion value rule sets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_conversion_value_rule_sets( - self, - ) -> Callable[ - [ - conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest - ], - Awaitable[ - conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse - ], - ]: - r"""Return a callable for the mutate conversion value rule - sets method over gRPC. - - Creates, updates or removes conversion value rule - sets. Operation statuses are returned. - - Returns: - Callable[[~.MutateConversionValueRuleSetsRequest], - Awaitable[~.MutateConversionValueRuleSetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_conversion_value_rule_sets" not in self._stubs: - self._stubs["mutate_conversion_value_rule_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ConversionValueRuleSetService/MutateConversionValueRuleSets", - request_serializer=conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest.serialize, - response_deserializer=conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_conversion_value_rule_sets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_conversion_value_rule_sets: self._wrap_method( - self.mutate_conversion_value_rule_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ConversionValueRuleSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_audience_service/async_client.py b/google/ads/googleads/v19/services/services/custom_audience_service/async_client.py deleted file mode 100644 index 5f25e68f6..000000000 --- a/google/ads/googleads/v19/services/services/custom_audience_service/async_client.py +++ /dev/null @@ -1,428 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import custom_audience_service -from .transports.base import CustomAudienceServiceTransport, DEFAULT_CLIENT_INFO -from .client import CustomAudienceServiceClient - -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 CustomAudienceServiceAsyncClient: - """Service to manage custom audiences.""" - - _client: CustomAudienceServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomAudienceServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CustomAudienceServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomAudienceServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomAudienceServiceClient._DEFAULT_UNIVERSE - - custom_audience_path = staticmethod( - CustomAudienceServiceClient.custom_audience_path - ) - parse_custom_audience_path = staticmethod( - CustomAudienceServiceClient.parse_custom_audience_path - ) - common_billing_account_path = staticmethod( - CustomAudienceServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomAudienceServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomAudienceServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomAudienceServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomAudienceServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomAudienceServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomAudienceServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomAudienceServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomAudienceServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomAudienceServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomAudienceServiceAsyncClient: The constructed client. - """ - return CustomAudienceServiceClient.from_service_account_info.__func__(CustomAudienceServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomAudienceServiceAsyncClient: The constructed client. - """ - return CustomAudienceServiceClient.from_service_account_file.__func__(CustomAudienceServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomAudienceServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomAudienceServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomAudienceServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomAudienceServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomAudienceServiceTransport, - Callable[..., CustomAudienceServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the custom audience service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomAudienceServiceTransport,Callable[..., CustomAudienceServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomAudienceServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomAudienceServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomAudienceServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomAudienceService", - "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.ads.googleads.v19.services.CustomAudienceService", - "credentialsType": None, - } - ), - ) - - async def mutate_custom_audiences( - self, - request: Optional[ - Union[custom_audience_service.MutateCustomAudiencesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[custom_audience_service.CustomAudienceOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> custom_audience_service.MutateCustomAudiencesResponse: - r"""Creates or updates custom audiences. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CustomAudienceError <>`__ - `CustomInterestError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `OperationAccessDeniedError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomAudiencesRequest, dict]]): - The request object. Request message for - [CustomAudienceService.MutateCustomAudiences][google.ads.googleads.v19.services.CustomAudienceService.MutateCustomAudiences]. - customer_id (:class:`str`): - Required. The ID of the customer - whose custom audiences are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CustomAudienceOperation]`): - Required. The list of operations to - perform on individual custom audiences. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomAudiencesResponse: - Response message for custom audience - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, custom_audience_service.MutateCustomAudiencesRequest - ): - request = custom_audience_service.MutateCustomAudiencesRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_custom_audiences - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomAudienceServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomAudienceServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/custom_audience_service/client.py b/google/ads/googleads/v19/services/services/custom_audience_service/client.py deleted file mode 100644 index 0a7f80cfa..000000000 --- a/google/ads/googleads/v19/services/services/custom_audience_service/client.py +++ /dev/null @@ -1,884 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import custom_audience_service -from .transports.base import CustomAudienceServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CustomAudienceServiceGrpcTransport -from .transports.grpc_asyncio import CustomAudienceServiceGrpcAsyncIOTransport - - -class CustomAudienceServiceClientMeta(type): - """Metaclass for the CustomAudienceService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomAudienceServiceTransport]] - _transport_registry["grpc"] = CustomAudienceServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomAudienceServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomAudienceServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomAudienceServiceClient(metaclass=CustomAudienceServiceClientMeta): - """Service to manage custom audiences.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomAudienceServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomAudienceServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomAudienceServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomAudienceServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def custom_audience_path( - customer_id: str, - custom_audience_id: str, - ) -> str: - """Returns a fully-qualified custom_audience string.""" - return "customers/{customer_id}/customAudiences/{custom_audience_id}".format( - customer_id=customer_id, - custom_audience_id=custom_audience_id, - ) - - @staticmethod - def parse_custom_audience_path(path: str) -> Dict[str, str]: - """Parses a custom_audience path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customAudiences/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CustomAudienceServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CustomAudienceServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CustomAudienceServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomAudienceServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomAudienceServiceTransport, - Callable[..., CustomAudienceServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the custom audience service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomAudienceServiceTransport,Callable[..., CustomAudienceServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomAudienceServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomAudienceServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomAudienceServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomAudienceServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomAudienceServiceTransport - ) - if transport_provided: - # transport is a CustomAudienceServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CustomAudienceServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomAudienceServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomAudienceServiceTransport], - Callable[..., CustomAudienceServiceTransport], - ] = ( - CustomAudienceServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomAudienceServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomAudienceServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomAudienceService", - "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.ads.googleads.v19.services.CustomAudienceService", - "credentialsType": None, - } - ), - ) - - def mutate_custom_audiences( - self, - request: Optional[ - Union[custom_audience_service.MutateCustomAudiencesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[custom_audience_service.CustomAudienceOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> custom_audience_service.MutateCustomAudiencesResponse: - r"""Creates or updates custom audiences. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CustomAudienceError <>`__ - `CustomInterestError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `OperationAccessDeniedError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomAudiencesRequest, dict]): - The request object. Request message for - [CustomAudienceService.MutateCustomAudiences][google.ads.googleads.v19.services.CustomAudienceService.MutateCustomAudiences]. - customer_id (str): - Required. The ID of the customer - whose custom audiences are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomAudienceOperation]): - Required. The list of operations to - perform on individual custom audiences. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomAudiencesResponse: - Response message for custom audience - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, custom_audience_service.MutateCustomAudiencesRequest - ): - request = custom_audience_service.MutateCustomAudiencesRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_custom_audiences - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomAudienceServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomAudienceServiceClient",) diff --git a/google/ads/googleads/v19/services/services/custom_audience_service/transports/base.py b/google/ads/googleads/v19/services/services/custom_audience_service/transports/base.py deleted file mode 100644 index 8e473f0b3..000000000 --- a/google/ads/googleads/v19/services/services/custom_audience_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import custom_audience_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomAudienceServiceTransport(abc.ABC): - """Abstract transport class for CustomAudienceService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_custom_audiences: gapic_v1.method.wrap_method( - self.mutate_custom_audiences, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_custom_audiences( - self, - ) -> Callable[ - [custom_audience_service.MutateCustomAudiencesRequest], - Union[ - custom_audience_service.MutateCustomAudiencesResponse, - Awaitable[custom_audience_service.MutateCustomAudiencesResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomAudienceServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_audience_service/transports/grpc.py b/google/ads/googleads/v19/services/services/custom_audience_service/transports/grpc.py deleted file mode 100644 index b081af605..000000000 --- a/google/ads/googleads/v19/services/services/custom_audience_service/transports/grpc.py +++ /dev/null @@ -1,390 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import custom_audience_service -from .base import CustomAudienceServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomAudienceService", - "rpcName": str(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.ads.googleads.v19.services.CustomAudienceService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomAudienceServiceGrpcTransport(CustomAudienceServiceTransport): - """gRPC backend transport for CustomAudienceService. - - Service to manage custom audiences. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_custom_audiences( - self, - ) -> Callable[ - [custom_audience_service.MutateCustomAudiencesRequest], - custom_audience_service.MutateCustomAudiencesResponse, - ]: - r"""Return a callable for the mutate custom audiences method over gRPC. - - Creates or updates custom audiences. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CustomAudienceError <>`__ - `CustomInterestError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `OperationAccessDeniedError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomAudiencesRequest], - ~.MutateCustomAudiencesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_custom_audiences" not in self._stubs: - self._stubs["mutate_custom_audiences"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomAudienceService/MutateCustomAudiences", - request_serializer=custom_audience_service.MutateCustomAudiencesRequest.serialize, - response_deserializer=custom_audience_service.MutateCustomAudiencesResponse.deserialize, - ) - ) - return self._stubs["mutate_custom_audiences"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomAudienceServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_audience_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/custom_audience_service/transports/grpc_asyncio.py deleted file mode 100644 index 8d1e02273..000000000 --- a/google/ads/googleads/v19/services/services/custom_audience_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,411 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import custom_audience_service -from .base import CustomAudienceServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomAudienceService", - "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.ads.googleads.v19.services.CustomAudienceService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomAudienceServiceGrpcAsyncIOTransport(CustomAudienceServiceTransport): - """gRPC AsyncIO backend transport for CustomAudienceService. - - Service to manage custom audiences. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_custom_audiences( - self, - ) -> Callable[ - [custom_audience_service.MutateCustomAudiencesRequest], - Awaitable[custom_audience_service.MutateCustomAudiencesResponse], - ]: - r"""Return a callable for the mutate custom audiences method over gRPC. - - Creates or updates custom audiences. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CustomAudienceError <>`__ - `CustomInterestError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `OperationAccessDeniedError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomAudiencesRequest], - Awaitable[~.MutateCustomAudiencesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_custom_audiences" not in self._stubs: - self._stubs["mutate_custom_audiences"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomAudienceService/MutateCustomAudiences", - request_serializer=custom_audience_service.MutateCustomAudiencesRequest.serialize, - response_deserializer=custom_audience_service.MutateCustomAudiencesResponse.deserialize, - ) - ) - return self._stubs["mutate_custom_audiences"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_custom_audiences: self._wrap_method( - self.mutate_custom_audiences, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomAudienceServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/async_client.py b/google/ads/googleads/v19/services/services/custom_conversion_goal_service/async_client.py deleted file mode 100644 index 6b7b9504c..000000000 --- a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/async_client.py +++ /dev/null @@ -1,440 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - custom_conversion_goal_service, -) -from .transports.base import ( - CustomConversionGoalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomConversionGoalServiceClient - -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 CustomConversionGoalServiceAsyncClient: - """Service to manage custom conversion goal.""" - - _client: CustomConversionGoalServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomConversionGoalServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CustomConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomConversionGoalServiceClient._DEFAULT_UNIVERSE - - conversion_action_path = staticmethod( - CustomConversionGoalServiceClient.conversion_action_path - ) - parse_conversion_action_path = staticmethod( - CustomConversionGoalServiceClient.parse_conversion_action_path - ) - custom_conversion_goal_path = staticmethod( - CustomConversionGoalServiceClient.custom_conversion_goal_path - ) - parse_custom_conversion_goal_path = staticmethod( - CustomConversionGoalServiceClient.parse_custom_conversion_goal_path - ) - common_billing_account_path = staticmethod( - CustomConversionGoalServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomConversionGoalServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomConversionGoalServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomConversionGoalServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomConversionGoalServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomConversionGoalServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomConversionGoalServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomConversionGoalServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomConversionGoalServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomConversionGoalServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomConversionGoalServiceAsyncClient: The constructed client. - """ - return CustomConversionGoalServiceClient.from_service_account_info.__func__(CustomConversionGoalServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomConversionGoalServiceAsyncClient: The constructed client. - """ - return CustomConversionGoalServiceClient.from_service_account_file.__func__(CustomConversionGoalServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomConversionGoalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomConversionGoalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomConversionGoalServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomConversionGoalServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomConversionGoalServiceTransport, - Callable[..., CustomConversionGoalServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the custom conversion goal service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomConversionGoalServiceTransport,Callable[..., CustomConversionGoalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomConversionGoalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomConversionGoalServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomConversionGoalServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomConversionGoalService", - "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.ads.googleads.v19.services.CustomConversionGoalService", - "credentialsType": None, - } - ), - ) - - async def mutate_custom_conversion_goals( - self, - request: Optional[ - Union[ - custom_conversion_goal_service.MutateCustomConversionGoalsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - custom_conversion_goal_service.CustomConversionGoalOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> custom_conversion_goal_service.MutateCustomConversionGoalsResponse: - r"""Creates, updates or removes custom conversion goals. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomConversionGoalsRequest, dict]]): - The request object. Request message for - [CustomConversionGoalService.MutateCustomConversionGoals][google.ads.googleads.v19.services.CustomConversionGoalService.MutateCustomConversionGoals]. - customer_id (:class:`str`): - Required. The ID of the customer - whose custom conversion goals are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CustomConversionGoalOperation]`): - Required. The list of operations to - perform on individual custom conversion - goal. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomConversionGoalsResponse: - Response message for a custom - conversion goal mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - custom_conversion_goal_service.MutateCustomConversionGoalsRequest, - ): - request = custom_conversion_goal_service.MutateCustomConversionGoalsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_custom_conversion_goals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomConversionGoalServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomConversionGoalServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/client.py b/google/ads/googleads/v19/services/services/custom_conversion_goal_service/client.py deleted file mode 100644 index 719f11829..000000000 --- a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/client.py +++ /dev/null @@ -1,917 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - custom_conversion_goal_service, -) -from .transports.base import ( - CustomConversionGoalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CustomConversionGoalServiceGrpcTransport -from .transports.grpc_asyncio import ( - CustomConversionGoalServiceGrpcAsyncIOTransport, -) - - -class CustomConversionGoalServiceClientMeta(type): - """Metaclass for the CustomConversionGoalService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomConversionGoalServiceTransport]] - _transport_registry["grpc"] = CustomConversionGoalServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomConversionGoalServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomConversionGoalServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomConversionGoalServiceClient( - metaclass=CustomConversionGoalServiceClientMeta -): - """Service to manage custom conversion goal.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomConversionGoalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomConversionGoalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomConversionGoalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomConversionGoalServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def conversion_action_path( - customer_id: str, - conversion_action_id: str, - ) -> str: - """Returns a fully-qualified conversion_action string.""" - return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( - customer_id=customer_id, - conversion_action_id=conversion_action_id, - ) - - @staticmethod - def parse_conversion_action_path(path: str) -> Dict[str, str]: - """Parses a conversion_action path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionActions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def custom_conversion_goal_path( - customer_id: str, - goal_id: str, - ) -> str: - """Returns a fully-qualified custom_conversion_goal string.""" - return "customers/{customer_id}/customConversionGoals/{goal_id}".format( - customer_id=customer_id, - goal_id=goal_id, - ) - - @staticmethod - def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: - """Parses a custom_conversion_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CustomConversionGoalServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - CustomConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = CustomConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomConversionGoalServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomConversionGoalServiceTransport, - Callable[..., CustomConversionGoalServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the custom conversion goal service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomConversionGoalServiceTransport,Callable[..., CustomConversionGoalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomConversionGoalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomConversionGoalServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomConversionGoalServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomConversionGoalServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomConversionGoalServiceTransport - ) - if transport_provided: - # transport is a CustomConversionGoalServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CustomConversionGoalServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomConversionGoalServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomConversionGoalServiceTransport], - Callable[..., CustomConversionGoalServiceTransport], - ] = ( - CustomConversionGoalServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomConversionGoalServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomConversionGoalServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomConversionGoalService", - "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.ads.googleads.v19.services.CustomConversionGoalService", - "credentialsType": None, - } - ), - ) - - def mutate_custom_conversion_goals( - self, - request: Optional[ - Union[ - custom_conversion_goal_service.MutateCustomConversionGoalsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - custom_conversion_goal_service.CustomConversionGoalOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> custom_conversion_goal_service.MutateCustomConversionGoalsResponse: - r"""Creates, updates or removes custom conversion goals. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomConversionGoalsRequest, dict]): - The request object. Request message for - [CustomConversionGoalService.MutateCustomConversionGoals][google.ads.googleads.v19.services.CustomConversionGoalService.MutateCustomConversionGoals]. - customer_id (str): - Required. The ID of the customer - whose custom conversion goals are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomConversionGoalOperation]): - Required. The list of operations to - perform on individual custom conversion - goal. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomConversionGoalsResponse: - Response message for a custom - conversion goal mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - custom_conversion_goal_service.MutateCustomConversionGoalsRequest, - ): - request = custom_conversion_goal_service.MutateCustomConversionGoalsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_custom_conversion_goals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomConversionGoalServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomConversionGoalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/base.py b/google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/base.py deleted file mode 100644 index e5b5b61f0..000000000 --- a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - custom_conversion_goal_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomConversionGoalServiceTransport(abc.ABC): - """Abstract transport class for CustomConversionGoalService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_custom_conversion_goals: gapic_v1.method.wrap_method( - self.mutate_custom_conversion_goals, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_custom_conversion_goals( - self, - ) -> Callable[ - [custom_conversion_goal_service.MutateCustomConversionGoalsRequest], - Union[ - custom_conversion_goal_service.MutateCustomConversionGoalsResponse, - Awaitable[ - custom_conversion_goal_service.MutateCustomConversionGoalsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomConversionGoalServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/grpc.py b/google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/grpc.py deleted file mode 100644 index e87e08ca8..000000000 --- a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/grpc.py +++ /dev/null @@ -1,386 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - custom_conversion_goal_service, -) -from .base import CustomConversionGoalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomConversionGoalService", - "rpcName": str(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.ads.googleads.v19.services.CustomConversionGoalService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomConversionGoalServiceGrpcTransport( - CustomConversionGoalServiceTransport -): - """gRPC backend transport for CustomConversionGoalService. - - Service to manage custom conversion goal. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_custom_conversion_goals( - self, - ) -> Callable[ - [custom_conversion_goal_service.MutateCustomConversionGoalsRequest], - custom_conversion_goal_service.MutateCustomConversionGoalsResponse, - ]: - r"""Return a callable for the mutate custom conversion goals method over gRPC. - - Creates, updates or removes custom conversion goals. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCustomConversionGoalsRequest], - ~.MutateCustomConversionGoalsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_custom_conversion_goals" not in self._stubs: - self._stubs["mutate_custom_conversion_goals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomConversionGoalService/MutateCustomConversionGoals", - request_serializer=custom_conversion_goal_service.MutateCustomConversionGoalsRequest.serialize, - response_deserializer=custom_conversion_goal_service.MutateCustomConversionGoalsResponse.deserialize, - ) - ) - return self._stubs["mutate_custom_conversion_goals"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomConversionGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/grpc_asyncio.py deleted file mode 100644 index 80fe1f770..000000000 --- a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - custom_conversion_goal_service, -) -from .base import CustomConversionGoalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomConversionGoalService", - "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.ads.googleads.v19.services.CustomConversionGoalService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomConversionGoalServiceGrpcAsyncIOTransport( - CustomConversionGoalServiceTransport -): - """gRPC AsyncIO backend transport for CustomConversionGoalService. - - Service to manage custom conversion goal. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_custom_conversion_goals( - self, - ) -> Callable[ - [custom_conversion_goal_service.MutateCustomConversionGoalsRequest], - Awaitable[ - custom_conversion_goal_service.MutateCustomConversionGoalsResponse - ], - ]: - r"""Return a callable for the mutate custom conversion goals method over gRPC. - - Creates, updates or removes custom conversion goals. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCustomConversionGoalsRequest], - Awaitable[~.MutateCustomConversionGoalsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_custom_conversion_goals" not in self._stubs: - self._stubs["mutate_custom_conversion_goals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomConversionGoalService/MutateCustomConversionGoals", - request_serializer=custom_conversion_goal_service.MutateCustomConversionGoalsRequest.serialize, - response_deserializer=custom_conversion_goal_service.MutateCustomConversionGoalsResponse.deserialize, - ) - ) - return self._stubs["mutate_custom_conversion_goals"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_custom_conversion_goals: self._wrap_method( - self.mutate_custom_conversion_goals, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomConversionGoalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_interest_service/async_client.py b/google/ads/googleads/v19/services/services/custom_interest_service/async_client.py deleted file mode 100644 index 642d84e28..000000000 --- a/google/ads/googleads/v19/services/services/custom_interest_service/async_client.py +++ /dev/null @@ -1,427 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import custom_interest_service -from .transports.base import CustomInterestServiceTransport, DEFAULT_CLIENT_INFO -from .client import CustomInterestServiceClient - -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 CustomInterestServiceAsyncClient: - """Service to manage custom interests.""" - - _client: CustomInterestServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomInterestServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CustomInterestServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomInterestServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomInterestServiceClient._DEFAULT_UNIVERSE - - custom_interest_path = staticmethod( - CustomInterestServiceClient.custom_interest_path - ) - parse_custom_interest_path = staticmethod( - CustomInterestServiceClient.parse_custom_interest_path - ) - common_billing_account_path = staticmethod( - CustomInterestServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomInterestServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomInterestServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomInterestServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomInterestServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomInterestServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomInterestServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomInterestServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomInterestServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomInterestServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomInterestServiceAsyncClient: The constructed client. - """ - return CustomInterestServiceClient.from_service_account_info.__func__(CustomInterestServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomInterestServiceAsyncClient: The constructed client. - """ - return CustomInterestServiceClient.from_service_account_file.__func__(CustomInterestServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomInterestServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomInterestServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomInterestServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomInterestServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomInterestServiceTransport, - Callable[..., CustomInterestServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the custom interest service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomInterestServiceTransport,Callable[..., CustomInterestServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomInterestServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomInterestServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomInterestServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomInterestService", - "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.ads.googleads.v19.services.CustomInterestService", - "credentialsType": None, - } - ), - ) - - async def mutate_custom_interests( - self, - request: Optional[ - Union[custom_interest_service.MutateCustomInterestsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[custom_interest_service.CustomInterestOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> custom_interest_service.MutateCustomInterestsResponse: - r"""Creates or updates custom interests. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `CustomInterestError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ - `RequestError <>`__ `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomInterestsRequest, dict]]): - The request object. Request message for - [CustomInterestService.MutateCustomInterests][google.ads.googleads.v19.services.CustomInterestService.MutateCustomInterests]. - customer_id (:class:`str`): - Required. The ID of the customer - whose custom interests are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CustomInterestOperation]`): - Required. The list of operations to - perform on individual custom interests. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomInterestsResponse: - Response message for custom interest - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, custom_interest_service.MutateCustomInterestsRequest - ): - request = custom_interest_service.MutateCustomInterestsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_custom_interests - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomInterestServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomInterestServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/custom_interest_service/client.py b/google/ads/googleads/v19/services/services/custom_interest_service/client.py deleted file mode 100644 index 0e2e9abce..000000000 --- a/google/ads/googleads/v19/services/services/custom_interest_service/client.py +++ /dev/null @@ -1,883 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import custom_interest_service -from .transports.base import CustomInterestServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CustomInterestServiceGrpcTransport -from .transports.grpc_asyncio import CustomInterestServiceGrpcAsyncIOTransport - - -class CustomInterestServiceClientMeta(type): - """Metaclass for the CustomInterestService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomInterestServiceTransport]] - _transport_registry["grpc"] = CustomInterestServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomInterestServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomInterestServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomInterestServiceClient(metaclass=CustomInterestServiceClientMeta): - """Service to manage custom interests.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomInterestServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomInterestServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomInterestServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomInterestServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def custom_interest_path( - customer_id: str, - custom_interest_id: str, - ) -> str: - """Returns a fully-qualified custom_interest string.""" - return "customers/{customer_id}/customInterests/{custom_interest_id}".format( - customer_id=customer_id, - custom_interest_id=custom_interest_id, - ) - - @staticmethod - def parse_custom_interest_path(path: str) -> Dict[str, str]: - """Parses a custom_interest path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customInterests/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CustomInterestServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CustomInterestServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CustomInterestServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomInterestServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomInterestServiceTransport, - Callable[..., CustomInterestServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the custom interest service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomInterestServiceTransport,Callable[..., CustomInterestServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomInterestServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomInterestServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomInterestServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomInterestServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomInterestServiceTransport - ) - if transport_provided: - # transport is a CustomInterestServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CustomInterestServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomInterestServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomInterestServiceTransport], - Callable[..., CustomInterestServiceTransport], - ] = ( - CustomInterestServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomInterestServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomInterestServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomInterestService", - "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.ads.googleads.v19.services.CustomInterestService", - "credentialsType": None, - } - ), - ) - - def mutate_custom_interests( - self, - request: Optional[ - Union[custom_interest_service.MutateCustomInterestsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[custom_interest_service.CustomInterestOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> custom_interest_service.MutateCustomInterestsResponse: - r"""Creates or updates custom interests. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `CustomInterestError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ - `RequestError <>`__ `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomInterestsRequest, dict]): - The request object. Request message for - [CustomInterestService.MutateCustomInterests][google.ads.googleads.v19.services.CustomInterestService.MutateCustomInterests]. - customer_id (str): - Required. The ID of the customer - whose custom interests are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomInterestOperation]): - Required. The list of operations to - perform on individual custom interests. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomInterestsResponse: - Response message for custom interest - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, custom_interest_service.MutateCustomInterestsRequest - ): - request = custom_interest_service.MutateCustomInterestsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_custom_interests - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomInterestServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomInterestServiceClient",) diff --git a/google/ads/googleads/v19/services/services/custom_interest_service/transports/base.py b/google/ads/googleads/v19/services/services/custom_interest_service/transports/base.py deleted file mode 100644 index 4228bd556..000000000 --- a/google/ads/googleads/v19/services/services/custom_interest_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import custom_interest_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomInterestServiceTransport(abc.ABC): - """Abstract transport class for CustomInterestService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_custom_interests: gapic_v1.method.wrap_method( - self.mutate_custom_interests, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_custom_interests( - self, - ) -> Callable[ - [custom_interest_service.MutateCustomInterestsRequest], - Union[ - custom_interest_service.MutateCustomInterestsResponse, - Awaitable[custom_interest_service.MutateCustomInterestsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomInterestServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_interest_service/transports/grpc.py b/google/ads/googleads/v19/services/services/custom_interest_service/transports/grpc.py deleted file mode 100644 index 56a679863..000000000 --- a/google/ads/googleads/v19/services/services/custom_interest_service/transports/grpc.py +++ /dev/null @@ -1,389 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import custom_interest_service -from .base import CustomInterestServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomInterestService", - "rpcName": str(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.ads.googleads.v19.services.CustomInterestService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomInterestServiceGrpcTransport(CustomInterestServiceTransport): - """gRPC backend transport for CustomInterestService. - - Service to manage custom interests. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_custom_interests( - self, - ) -> Callable[ - [custom_interest_service.MutateCustomInterestsRequest], - custom_interest_service.MutateCustomInterestsResponse, - ]: - r"""Return a callable for the mutate custom interests method over gRPC. - - Creates or updates custom interests. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `CustomInterestError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ - `RequestError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateCustomInterestsRequest], - ~.MutateCustomInterestsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_custom_interests" not in self._stubs: - self._stubs["mutate_custom_interests"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomInterestService/MutateCustomInterests", - request_serializer=custom_interest_service.MutateCustomInterestsRequest.serialize, - response_deserializer=custom_interest_service.MutateCustomInterestsResponse.deserialize, - ) - ) - return self._stubs["mutate_custom_interests"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomInterestServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_interest_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/custom_interest_service/transports/grpc_asyncio.py deleted file mode 100644 index 3e3d4175e..000000000 --- a/google/ads/googleads/v19/services/services/custom_interest_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,410 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import custom_interest_service -from .base import CustomInterestServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomInterestService", - "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.ads.googleads.v19.services.CustomInterestService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomInterestServiceGrpcAsyncIOTransport(CustomInterestServiceTransport): - """gRPC AsyncIO backend transport for CustomInterestService. - - Service to manage custom interests. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_custom_interests( - self, - ) -> Callable[ - [custom_interest_service.MutateCustomInterestsRequest], - Awaitable[custom_interest_service.MutateCustomInterestsResponse], - ]: - r"""Return a callable for the mutate custom interests method over gRPC. - - Creates or updates custom interests. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `CustomInterestError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ - `RequestError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateCustomInterestsRequest], - Awaitable[~.MutateCustomInterestsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_custom_interests" not in self._stubs: - self._stubs["mutate_custom_interests"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomInterestService/MutateCustomInterests", - request_serializer=custom_interest_service.MutateCustomInterestsRequest.serialize, - response_deserializer=custom_interest_service.MutateCustomInterestsResponse.deserialize, - ) - ) - return self._stubs["mutate_custom_interests"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_custom_interests: self._wrap_method( - self.mutate_custom_interests, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomInterestServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_service/async_client.py b/google/ads/googleads/v19/services/services/customer_asset_service/async_client.py deleted file mode 100644 index 66dedb06e..000000000 --- a/google/ads/googleads/v19/services/services/customer_asset_service/async_client.py +++ /dev/null @@ -1,428 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import customer_asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CustomerAssetServiceTransport, DEFAULT_CLIENT_INFO -from .client import CustomerAssetServiceClient - -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 CustomerAssetServiceAsyncClient: - """Service to manage customer assets.""" - - _client: CustomerAssetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomerAssetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CustomerAssetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomerAssetServiceClient._DEFAULT_UNIVERSE - - asset_path = staticmethod(CustomerAssetServiceClient.asset_path) - parse_asset_path = staticmethod(CustomerAssetServiceClient.parse_asset_path) - customer_asset_path = staticmethod( - CustomerAssetServiceClient.customer_asset_path - ) - parse_customer_asset_path = staticmethod( - CustomerAssetServiceClient.parse_customer_asset_path - ) - common_billing_account_path = staticmethod( - CustomerAssetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerAssetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerAssetServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerAssetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerAssetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerAssetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerAssetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerAssetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerAssetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerAssetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerAssetServiceAsyncClient: The constructed client. - """ - return CustomerAssetServiceClient.from_service_account_info.__func__(CustomerAssetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerAssetServiceAsyncClient: The constructed client. - """ - return CustomerAssetServiceClient.from_service_account_file.__func__(CustomerAssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerAssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerAssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerAssetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomerAssetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerAssetServiceTransport, - Callable[..., CustomerAssetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer asset service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerAssetServiceTransport,Callable[..., CustomerAssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerAssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerAssetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerAssetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerAssetService", - "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.ads.googleads.v19.services.CustomerAssetService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer_assets( - self, - request: Optional[ - Union[customer_asset_service.MutateCustomerAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[customer_asset_service.CustomerAssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_asset_service.MutateCustomerAssetsResponse: - r"""Creates, updates, or removes customer assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerAssetsRequest, dict]]): - The request object. Request message for - [CustomerAssetService.MutateCustomerAssets][google.ads.googleads.v19.services.CustomerAssetService.MutateCustomerAssets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose customer assets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CustomerAssetOperation]`): - Required. The list of operations to - perform on individual customer assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerAssetsResponse: - Response message for a customer asset - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_asset_service.MutateCustomerAssetsRequest - ): - request = customer_asset_service.MutateCustomerAssetsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomerAssetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerAssetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_service/client.py b/google/ads/googleads/v19/services/services/customer_asset_service/client.py deleted file mode 100644 index d5357ad5f..000000000 --- a/google/ads/googleads/v19/services/services/customer_asset_service/client.py +++ /dev/null @@ -1,901 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import customer_asset_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CustomerAssetServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CustomerAssetServiceGrpcTransport -from .transports.grpc_asyncio import CustomerAssetServiceGrpcAsyncIOTransport - - -class CustomerAssetServiceClientMeta(type): - """Metaclass for the CustomerAssetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerAssetServiceTransport]] - _transport_registry["grpc"] = CustomerAssetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomerAssetServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerAssetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerAssetServiceClient(metaclass=CustomerAssetServiceClientMeta): - """Service to manage customer assets.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerAssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerAssetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerAssetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerAssetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_path( - customer_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset string.""" - return "customers/{customer_id}/assets/{asset_id}".format( - customer_id=customer_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_path(path: str) -> Dict[str, str]: - """Parses a asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assets/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_asset_path( - customer_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified customer_asset string.""" - return "customers/{customer_id}/customerAssets/{asset_id}~{field_type}".format( - customer_id=customer_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_customer_asset_path(path: str) -> Dict[str, str]: - """Parses a customer_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerAssets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CustomerAssetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CustomerAssetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CustomerAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomerAssetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerAssetServiceTransport, - Callable[..., CustomerAssetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer asset service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerAssetServiceTransport,Callable[..., CustomerAssetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerAssetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomerAssetServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomerAssetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = CustomerAssetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerAssetServiceTransport - ) - if transport_provided: - # transport is a CustomerAssetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CustomerAssetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerAssetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerAssetServiceTransport], - Callable[..., CustomerAssetServiceTransport], - ] = ( - CustomerAssetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomerAssetServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerAssetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerAssetService", - "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.ads.googleads.v19.services.CustomerAssetService", - "credentialsType": None, - } - ), - ) - - def mutate_customer_assets( - self, - request: Optional[ - Union[customer_asset_service.MutateCustomerAssetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[customer_asset_service.CustomerAssetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_asset_service.MutateCustomerAssetsResponse: - r"""Creates, updates, or removes customer assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerAssetsRequest, dict]): - The request object. Request message for - [CustomerAssetService.MutateCustomerAssets][google.ads.googleads.v19.services.CustomerAssetService.MutateCustomerAssets]. - customer_id (str): - Required. The ID of the customer - whose customer assets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerAssetOperation]): - Required. The list of operations to - perform on individual customer assets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerAssetsResponse: - Response message for a customer asset - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_asset_service.MutateCustomerAssetsRequest - ): - request = customer_asset_service.MutateCustomerAssetsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customer_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerAssetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerAssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_asset_service/transports/base.py deleted file mode 100644 index 3b5ca317d..000000000 --- a/google/ads/googleads/v19/services/services/customer_asset_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import customer_asset_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerAssetServiceTransport(abc.ABC): - """Abstract transport class for CustomerAssetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer_assets: gapic_v1.method.wrap_method( - self.mutate_customer_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer_assets( - self, - ) -> Callable[ - [customer_asset_service.MutateCustomerAssetsRequest], - Union[ - customer_asset_service.MutateCustomerAssetsResponse, - Awaitable[customer_asset_service.MutateCustomerAssetsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerAssetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_asset_service/transports/grpc.py deleted file mode 100644 index dc9459d10..000000000 --- a/google/ads/googleads/v19/services/services/customer_asset_service/transports/grpc.py +++ /dev/null @@ -1,387 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import customer_asset_service -from .base import CustomerAssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerAssetService", - "rpcName": str(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.ads.googleads.v19.services.CustomerAssetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerAssetServiceGrpcTransport(CustomerAssetServiceTransport): - """gRPC backend transport for CustomerAssetService. - - Service to manage customer assets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer_assets( - self, - ) -> Callable[ - [customer_asset_service.MutateCustomerAssetsRequest], - customer_asset_service.MutateCustomerAssetsResponse, - ]: - r"""Return a callable for the mutate customer assets method over gRPC. - - Creates, updates, or removes customer assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerAssetsRequest], - ~.MutateCustomerAssetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_assets" not in self._stubs: - self._stubs["mutate_customer_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerAssetService/MutateCustomerAssets", - request_serializer=customer_asset_service.MutateCustomerAssetsRequest.serialize, - response_deserializer=customer_asset_service.MutateCustomerAssetsResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_assets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_asset_service/transports/grpc_asyncio.py deleted file mode 100644 index a22252e07..000000000 --- a/google/ads/googleads/v19/services/services/customer_asset_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,408 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import customer_asset_service -from .base import CustomerAssetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerAssetService", - "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.ads.googleads.v19.services.CustomerAssetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerAssetServiceGrpcAsyncIOTransport(CustomerAssetServiceTransport): - """gRPC AsyncIO backend transport for CustomerAssetService. - - Service to manage customer assets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer_assets( - self, - ) -> Callable[ - [customer_asset_service.MutateCustomerAssetsRequest], - Awaitable[customer_asset_service.MutateCustomerAssetsResponse], - ]: - r"""Return a callable for the mutate customer assets method over gRPC. - - Creates, updates, or removes customer assets. Operation statuses - are returned. - - List of thrown errors: `AssetLinkError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerAssetsRequest], - Awaitable[~.MutateCustomerAssetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_assets" not in self._stubs: - self._stubs["mutate_customer_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerAssetService/MutateCustomerAssets", - request_serializer=customer_asset_service.MutateCustomerAssetsRequest.serialize, - response_deserializer=customer_asset_service.MutateCustomerAssetsResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_assets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer_assets: self._wrap_method( - self.mutate_customer_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerAssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_set_service/async_client.py b/google/ads/googleads/v19/services/services/customer_asset_set_service/async_client.py deleted file mode 100644 index e1e45400e..000000000 --- a/google/ads/googleads/v19/services/services/customer_asset_set_service/async_client.py +++ /dev/null @@ -1,437 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import customer_asset_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CustomerAssetSetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomerAssetSetServiceClient - -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 CustomerAssetSetServiceAsyncClient: - """Service to manage customer asset set""" - - _client: CustomerAssetSetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomerAssetSetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CustomerAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomerAssetSetServiceClient._DEFAULT_UNIVERSE - - asset_set_path = staticmethod(CustomerAssetSetServiceClient.asset_set_path) - parse_asset_set_path = staticmethod( - CustomerAssetSetServiceClient.parse_asset_set_path - ) - customer_path = staticmethod(CustomerAssetSetServiceClient.customer_path) - parse_customer_path = staticmethod( - CustomerAssetSetServiceClient.parse_customer_path - ) - customer_asset_set_path = staticmethod( - CustomerAssetSetServiceClient.customer_asset_set_path - ) - parse_customer_asset_set_path = staticmethod( - CustomerAssetSetServiceClient.parse_customer_asset_set_path - ) - common_billing_account_path = staticmethod( - CustomerAssetSetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerAssetSetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerAssetSetServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerAssetSetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerAssetSetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerAssetSetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerAssetSetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerAssetSetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerAssetSetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerAssetSetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerAssetSetServiceAsyncClient: The constructed client. - """ - return CustomerAssetSetServiceClient.from_service_account_info.__func__(CustomerAssetSetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerAssetSetServiceAsyncClient: The constructed client. - """ - return CustomerAssetSetServiceClient.from_service_account_file.__func__(CustomerAssetSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerAssetSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerAssetSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerAssetSetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomerAssetSetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerAssetSetServiceTransport, - Callable[..., CustomerAssetSetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer asset set service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerAssetSetServiceTransport,Callable[..., CustomerAssetSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerAssetSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerAssetSetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerAssetSetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerAssetSetService", - "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.ads.googleads.v19.services.CustomerAssetSetService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer_asset_sets( - self, - request: Optional[ - Union[ - customer_asset_set_service.MutateCustomerAssetSetsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customer_asset_set_service.CustomerAssetSetOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_asset_set_service.MutateCustomerAssetSetsResponse: - r"""Creates, or removes customer asset sets. Operation - statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerAssetSetsRequest, dict]]): - The request object. Request message for - [CustomerAssetSetService.MutateCustomerAssetSets][google.ads.googleads.v19.services.CustomerAssetSetService.MutateCustomerAssetSets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose customer asset sets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CustomerAssetSetOperation]`): - Required. The list of operations to - perform on individual customer asset - sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerAssetSetsResponse: - Response message for a customer asset - set mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_asset_set_service.MutateCustomerAssetSetsRequest - ): - request = customer_asset_set_service.MutateCustomerAssetSetsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer_asset_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomerAssetSetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerAssetSetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_set_service/client.py b/google/ads/googleads/v19/services/services/customer_asset_set_service/client.py deleted file mode 100644 index ca31496f9..000000000 --- a/google/ads/googleads/v19/services/services/customer_asset_set_service/client.py +++ /dev/null @@ -1,924 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import customer_asset_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CustomerAssetSetServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CustomerAssetSetServiceGrpcTransport -from .transports.grpc_asyncio import CustomerAssetSetServiceGrpcAsyncIOTransport - - -class CustomerAssetSetServiceClientMeta(type): - """Metaclass for the CustomerAssetSetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerAssetSetServiceTransport]] - _transport_registry["grpc"] = CustomerAssetSetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomerAssetSetServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerAssetSetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerAssetSetServiceClient( - metaclass=CustomerAssetSetServiceClientMeta -): - """Service to manage customer asset set""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerAssetSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerAssetSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerAssetSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerAssetSetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def asset_set_path( - customer_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified asset_set string.""" - return "customers/{customer_id}/assetSets/{asset_set_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_asset_set_path(path: str) -> Dict[str, str]: - """Parses a asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def customer_asset_set_path( - customer_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified customer_asset_set string.""" - return ( - "customers/{customer_id}/customerAssetSets/{asset_set_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - ) - ) - - @staticmethod - def parse_customer_asset_set_path(path: str) -> Dict[str, str]: - """Parses a customer_asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerAssetSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CustomerAssetSetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CustomerAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CustomerAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomerAssetSetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerAssetSetServiceTransport, - Callable[..., CustomerAssetSetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer asset set service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerAssetSetServiceTransport,Callable[..., CustomerAssetSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerAssetSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomerAssetSetServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomerAssetSetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomerAssetSetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerAssetSetServiceTransport - ) - if transport_provided: - # transport is a CustomerAssetSetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CustomerAssetSetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerAssetSetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerAssetSetServiceTransport], - Callable[..., CustomerAssetSetServiceTransport], - ] = ( - CustomerAssetSetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomerAssetSetServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerAssetSetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerAssetSetService", - "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.ads.googleads.v19.services.CustomerAssetSetService", - "credentialsType": None, - } - ), - ) - - def mutate_customer_asset_sets( - self, - request: Optional[ - Union[ - customer_asset_set_service.MutateCustomerAssetSetsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customer_asset_set_service.CustomerAssetSetOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_asset_set_service.MutateCustomerAssetSetsResponse: - r"""Creates, or removes customer asset sets. Operation - statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerAssetSetsRequest, dict]): - The request object. Request message for - [CustomerAssetSetService.MutateCustomerAssetSets][google.ads.googleads.v19.services.CustomerAssetSetService.MutateCustomerAssetSets]. - customer_id (str): - Required. The ID of the customer - whose customer asset sets are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerAssetSetOperation]): - Required. The list of operations to - perform on individual customer asset - sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerAssetSetsResponse: - Response message for a customer asset - set mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_asset_set_service.MutateCustomerAssetSetsRequest - ): - request = customer_asset_set_service.MutateCustomerAssetSetsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customer_asset_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerAssetSetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerAssetSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_set_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_asset_set_service/transports/base.py deleted file mode 100644 index df151ed43..000000000 --- a/google/ads/googleads/v19/services/services/customer_asset_set_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import customer_asset_set_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerAssetSetServiceTransport(abc.ABC): - """Abstract transport class for CustomerAssetSetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer_asset_sets: gapic_v1.method.wrap_method( - self.mutate_customer_asset_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer_asset_sets( - self, - ) -> Callable[ - [customer_asset_set_service.MutateCustomerAssetSetsRequest], - Union[ - customer_asset_set_service.MutateCustomerAssetSetsResponse, - Awaitable[ - customer_asset_set_service.MutateCustomerAssetSetsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerAssetSetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_set_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_asset_set_service/transports/grpc.py deleted file mode 100644 index cd4ce9802..000000000 --- a/google/ads/googleads/v19/services/services/customer_asset_set_service/transports/grpc.py +++ /dev/null @@ -1,382 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import customer_asset_set_service -from .base import CustomerAssetSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerAssetSetService", - "rpcName": str(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.ads.googleads.v19.services.CustomerAssetSetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerAssetSetServiceGrpcTransport(CustomerAssetSetServiceTransport): - """gRPC backend transport for CustomerAssetSetService. - - Service to manage customer asset set - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer_asset_sets( - self, - ) -> Callable[ - [customer_asset_set_service.MutateCustomerAssetSetsRequest], - customer_asset_set_service.MutateCustomerAssetSetsResponse, - ]: - r"""Return a callable for the mutate customer asset sets method over gRPC. - - Creates, or removes customer asset sets. Operation - statuses are returned. - - Returns: - Callable[[~.MutateCustomerAssetSetsRequest], - ~.MutateCustomerAssetSetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_asset_sets" not in self._stubs: - self._stubs["mutate_customer_asset_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerAssetSetService/MutateCustomerAssetSets", - request_serializer=customer_asset_set_service.MutateCustomerAssetSetsRequest.serialize, - response_deserializer=customer_asset_set_service.MutateCustomerAssetSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_asset_sets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerAssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_asset_set_service/transports/grpc_asyncio.py deleted file mode 100644 index 1e1881545..000000000 --- a/google/ads/googleads/v19/services/services/customer_asset_set_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,405 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import customer_asset_set_service -from .base import CustomerAssetSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerAssetSetService", - "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.ads.googleads.v19.services.CustomerAssetSetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerAssetSetServiceGrpcAsyncIOTransport( - CustomerAssetSetServiceTransport -): - """gRPC AsyncIO backend transport for CustomerAssetSetService. - - Service to manage customer asset set - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer_asset_sets( - self, - ) -> Callable[ - [customer_asset_set_service.MutateCustomerAssetSetsRequest], - Awaitable[customer_asset_set_service.MutateCustomerAssetSetsResponse], - ]: - r"""Return a callable for the mutate customer asset sets method over gRPC. - - Creates, or removes customer asset sets. Operation - statuses are returned. - - Returns: - Callable[[~.MutateCustomerAssetSetsRequest], - Awaitable[~.MutateCustomerAssetSetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_asset_sets" not in self._stubs: - self._stubs["mutate_customer_asset_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerAssetSetService/MutateCustomerAssetSets", - request_serializer=customer_asset_set_service.MutateCustomerAssetSetsRequest.serialize, - response_deserializer=customer_asset_set_service.MutateCustomerAssetSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_asset_sets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer_asset_sets: self._wrap_method( - self.mutate_customer_asset_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerAssetSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_client_link_service/async_client.py b/google/ads/googleads/v19/services/services/customer_client_link_service/async_client.py deleted file mode 100644 index 0edeea016..000000000 --- a/google/ads/googleads/v19/services/services/customer_client_link_service/async_client.py +++ /dev/null @@ -1,441 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import customer_client_link_service -from .transports.base import ( - CustomerClientLinkServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomerClientLinkServiceClient - -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 CustomerClientLinkServiceAsyncClient: - """Service to manage customer client links.""" - - _client: CustomerClientLinkServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomerClientLinkServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CustomerClientLinkServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerClientLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomerClientLinkServiceClient._DEFAULT_UNIVERSE - - customer_path = staticmethod(CustomerClientLinkServiceClient.customer_path) - parse_customer_path = staticmethod( - CustomerClientLinkServiceClient.parse_customer_path - ) - customer_client_link_path = staticmethod( - CustomerClientLinkServiceClient.customer_client_link_path - ) - parse_customer_client_link_path = staticmethod( - CustomerClientLinkServiceClient.parse_customer_client_link_path - ) - common_billing_account_path = staticmethod( - CustomerClientLinkServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerClientLinkServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerClientLinkServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerClientLinkServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerClientLinkServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerClientLinkServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerClientLinkServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerClientLinkServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerClientLinkServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerClientLinkServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerClientLinkServiceAsyncClient: The constructed client. - """ - return CustomerClientLinkServiceClient.from_service_account_info.__func__(CustomerClientLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerClientLinkServiceAsyncClient: The constructed client. - """ - return CustomerClientLinkServiceClient.from_service_account_file.__func__(CustomerClientLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerClientLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerClientLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerClientLinkServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomerClientLinkServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerClientLinkServiceTransport, - Callable[..., CustomerClientLinkServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer client link service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerClientLinkServiceTransport,Callable[..., CustomerClientLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerClientLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerClientLinkServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerClientLinkServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerClientLinkService", - "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.ads.googleads.v19.services.CustomerClientLinkService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer_client_link( - self, - request: Optional[ - Union[ - customer_client_link_service.MutateCustomerClientLinkRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - customer_client_link_service.CustomerClientLinkOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_client_link_service.MutateCustomerClientLinkResponse: - r"""Creates or updates a customer client link. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerClientLinkRequest, dict]]): - The request object. Request message for - [CustomerClientLinkService.MutateCustomerClientLink][google.ads.googleads.v19.services.CustomerClientLinkService.MutateCustomerClientLink]. - customer_id (:class:`str`): - Required. The ID of the customer - whose customer link are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (:class:`google.ads.googleads.v19.services.types.CustomerClientLinkOperation`): - Required. The operation to perform on - the individual CustomerClientLink. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerClientLinkResponse: - Response message for a - CustomerClientLink mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_client_link_service.MutateCustomerClientLinkRequest, - ): - request = ( - customer_client_link_service.MutateCustomerClientLinkRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer_client_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomerClientLinkServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerClientLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_client_link_service/client.py b/google/ads/googleads/v19/services/services/customer_client_link_service/client.py deleted file mode 100644 index 0014c4cca..000000000 --- a/google/ads/googleads/v19/services/services/customer_client_link_service/client.py +++ /dev/null @@ -1,904 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import customer_client_link_service -from .transports.base import ( - CustomerClientLinkServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CustomerClientLinkServiceGrpcTransport -from .transports.grpc_asyncio import ( - CustomerClientLinkServiceGrpcAsyncIOTransport, -) - - -class CustomerClientLinkServiceClientMeta(type): - """Metaclass for the CustomerClientLinkService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerClientLinkServiceTransport]] - _transport_registry["grpc"] = CustomerClientLinkServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomerClientLinkServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerClientLinkServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerClientLinkServiceClient( - metaclass=CustomerClientLinkServiceClientMeta -): - """Service to manage customer client links.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerClientLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerClientLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerClientLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerClientLinkServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def customer_client_link_path( - customer_id: str, - client_customer_id: str, - manager_link_id: str, - ) -> str: - """Returns a fully-qualified customer_client_link string.""" - return "customers/{customer_id}/customerClientLinks/{client_customer_id}~{manager_link_id}".format( - customer_id=customer_id, - client_customer_id=client_customer_id, - manager_link_id=manager_link_id, - ) - - @staticmethod - def parse_customer_client_link_path(path: str) -> Dict[str, str]: - """Parses a customer_client_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerClientLinks/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CustomerClientLinkServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CustomerClientLinkServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = CustomerClientLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomerClientLinkServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerClientLinkServiceTransport, - Callable[..., CustomerClientLinkServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer client link service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerClientLinkServiceTransport,Callable[..., CustomerClientLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerClientLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomerClientLinkServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomerClientLinkServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomerClientLinkServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerClientLinkServiceTransport - ) - if transport_provided: - # transport is a CustomerClientLinkServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CustomerClientLinkServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerClientLinkServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerClientLinkServiceTransport], - Callable[..., CustomerClientLinkServiceTransport], - ] = ( - CustomerClientLinkServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomerClientLinkServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerClientLinkServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerClientLinkService", - "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.ads.googleads.v19.services.CustomerClientLinkService", - "credentialsType": None, - } - ), - ) - - def mutate_customer_client_link( - self, - request: Optional[ - Union[ - customer_client_link_service.MutateCustomerClientLinkRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - customer_client_link_service.CustomerClientLinkOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_client_link_service.MutateCustomerClientLinkResponse: - r"""Creates or updates a customer client link. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerClientLinkRequest, dict]): - The request object. Request message for - [CustomerClientLinkService.MutateCustomerClientLink][google.ads.googleads.v19.services.CustomerClientLinkService.MutateCustomerClientLink]. - customer_id (str): - Required. The ID of the customer - whose customer link are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (google.ads.googleads.v19.services.types.CustomerClientLinkOperation): - Required. The operation to perform on - the individual CustomerClientLink. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerClientLinkResponse: - Response message for a - CustomerClientLink mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_client_link_service.MutateCustomerClientLinkRequest, - ): - request = ( - customer_client_link_service.MutateCustomerClientLinkRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customer_client_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerClientLinkServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerClientLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_client_link_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_client_link_service/transports/base.py deleted file mode 100644 index b672c4037..000000000 --- a/google/ads/googleads/v19/services/services/customer_client_link_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import customer_client_link_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerClientLinkServiceTransport(abc.ABC): - """Abstract transport class for CustomerClientLinkService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer_client_link: gapic_v1.method.wrap_method( - self.mutate_customer_client_link, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer_client_link( - self, - ) -> Callable[ - [customer_client_link_service.MutateCustomerClientLinkRequest], - Union[ - customer_client_link_service.MutateCustomerClientLinkResponse, - Awaitable[ - customer_client_link_service.MutateCustomerClientLinkResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerClientLinkServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_client_link_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_client_link_service/transports/grpc.py deleted file mode 100644 index 21d0c0b59..000000000 --- a/google/ads/googleads/v19/services/services/customer_client_link_service/transports/grpc.py +++ /dev/null @@ -1,391 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import customer_client_link_service -from .base import CustomerClientLinkServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerClientLinkService", - "rpcName": str(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.ads.googleads.v19.services.CustomerClientLinkService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerClientLinkServiceGrpcTransport( - CustomerClientLinkServiceTransport -): - """gRPC backend transport for CustomerClientLinkService. - - Service to manage customer client links. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer_client_link( - self, - ) -> Callable[ - [customer_client_link_service.MutateCustomerClientLinkRequest], - customer_client_link_service.MutateCustomerClientLinkResponse, - ]: - r"""Return a callable for the mutate customer client link method over gRPC. - - Creates or updates a customer client link. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerClientLinkRequest], - ~.MutateCustomerClientLinkResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_client_link" not in self._stubs: - self._stubs["mutate_customer_client_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerClientLinkService/MutateCustomerClientLink", - request_serializer=customer_client_link_service.MutateCustomerClientLinkRequest.serialize, - response_deserializer=customer_client_link_service.MutateCustomerClientLinkResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_client_link"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerClientLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_client_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_client_link_service/transports/grpc_asyncio.py deleted file mode 100644 index a2c044182..000000000 --- a/google/ads/googleads/v19/services/services/customer_client_link_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,414 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import customer_client_link_service -from .base import CustomerClientLinkServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerClientLinkService", - "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.ads.googleads.v19.services.CustomerClientLinkService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerClientLinkServiceGrpcAsyncIOTransport( - CustomerClientLinkServiceTransport -): - """gRPC AsyncIO backend transport for CustomerClientLinkService. - - Service to manage customer client links. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer_client_link( - self, - ) -> Callable[ - [customer_client_link_service.MutateCustomerClientLinkRequest], - Awaitable[ - customer_client_link_service.MutateCustomerClientLinkResponse - ], - ]: - r"""Return a callable for the mutate customer client link method over gRPC. - - Creates or updates a customer client link. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerClientLinkRequest], - Awaitable[~.MutateCustomerClientLinkResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_client_link" not in self._stubs: - self._stubs["mutate_customer_client_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerClientLinkService/MutateCustomerClientLink", - request_serializer=customer_client_link_service.MutateCustomerClientLinkRequest.serialize, - response_deserializer=customer_client_link_service.MutateCustomerClientLinkResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_client_link"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer_client_link: self._wrap_method( - self.mutate_customer_client_link, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerClientLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/async_client.py b/google/ads/googleads/v19/services/services/customer_conversion_goal_service/async_client.py deleted file mode 100644 index 27d012f84..000000000 --- a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/async_client.py +++ /dev/null @@ -1,436 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_conversion_goal_service, -) -from .transports.base import ( - CustomerConversionGoalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomerConversionGoalServiceClient - -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 CustomerConversionGoalServiceAsyncClient: - """Service to manage customer conversion goal.""" - - _client: CustomerConversionGoalServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomerConversionGoalServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CustomerConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomerConversionGoalServiceClient._DEFAULT_UNIVERSE - - customer_conversion_goal_path = staticmethod( - CustomerConversionGoalServiceClient.customer_conversion_goal_path - ) - parse_customer_conversion_goal_path = staticmethod( - CustomerConversionGoalServiceClient.parse_customer_conversion_goal_path - ) - common_billing_account_path = staticmethod( - CustomerConversionGoalServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerConversionGoalServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerConversionGoalServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerConversionGoalServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerConversionGoalServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerConversionGoalServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerConversionGoalServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerConversionGoalServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerConversionGoalServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerConversionGoalServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerConversionGoalServiceAsyncClient: The constructed client. - """ - return CustomerConversionGoalServiceClient.from_service_account_info.__func__(CustomerConversionGoalServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerConversionGoalServiceAsyncClient: The constructed client. - """ - return CustomerConversionGoalServiceClient.from_service_account_file.__func__(CustomerConversionGoalServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerConversionGoalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerConversionGoalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerConversionGoalServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - CustomerConversionGoalServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerConversionGoalServiceTransport, - Callable[..., CustomerConversionGoalServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer conversion goal service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerConversionGoalServiceTransport,Callable[..., CustomerConversionGoalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerConversionGoalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerConversionGoalServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerConversionGoalServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerConversionGoalService", - "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.ads.googleads.v19.services.CustomerConversionGoalService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer_conversion_goals( - self, - request: Optional[ - Union[ - customer_conversion_goal_service.MutateCustomerConversionGoalsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customer_conversion_goal_service.CustomerConversionGoalOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_conversion_goal_service.MutateCustomerConversionGoalsResponse: - r"""Creates, updates or removes customer conversion - goals. Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerConversionGoalsRequest, dict]]): - The request object. Request message for - [CustomerConversionGoalService.MutateCustomerConversionGoals][google.ads.googleads.v19.services.CustomerConversionGoalService.MutateCustomerConversionGoals]. - customer_id (:class:`str`): - Required. The ID of the customer - whose customer conversion goals are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CustomerConversionGoalOperation]`): - Required. The list of operations to - perform on individual customer - conversion goal. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerConversionGoalsResponse: - Response message for a customer - conversion goal mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_conversion_goal_service.MutateCustomerConversionGoalsRequest, - ): - request = customer_conversion_goal_service.MutateCustomerConversionGoalsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer_conversion_goals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomerConversionGoalServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerConversionGoalServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/client.py b/google/ads/googleads/v19/services/services/customer_conversion_goal_service/client.py deleted file mode 100644 index 30449d133..000000000 --- a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/client.py +++ /dev/null @@ -1,901 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - customer_conversion_goal_service, -) -from .transports.base import ( - CustomerConversionGoalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CustomerConversionGoalServiceGrpcTransport -from .transports.grpc_asyncio import ( - CustomerConversionGoalServiceGrpcAsyncIOTransport, -) - - -class CustomerConversionGoalServiceClientMeta(type): - """Metaclass for the CustomerConversionGoalService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerConversionGoalServiceTransport]] - _transport_registry["grpc"] = CustomerConversionGoalServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomerConversionGoalServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerConversionGoalServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerConversionGoalServiceClient( - metaclass=CustomerConversionGoalServiceClientMeta -): - """Service to manage customer conversion goal.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerConversionGoalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerConversionGoalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerConversionGoalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerConversionGoalServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_conversion_goal_path( - customer_id: str, - category: str, - source: str, - ) -> str: - """Returns a fully-qualified customer_conversion_goal string.""" - return "customers/{customer_id}/customerConversionGoals/{category}~{source}".format( - customer_id=customer_id, - category=category, - source=source, - ) - - @staticmethod - def parse_customer_conversion_goal_path(path: str) -> Dict[str, str]: - """Parses a customer_conversion_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerConversionGoals/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CustomerConversionGoalServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - CustomerConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = CustomerConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomerConversionGoalServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerConversionGoalServiceTransport, - Callable[..., CustomerConversionGoalServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer conversion goal service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerConversionGoalServiceTransport,Callable[..., CustomerConversionGoalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerConversionGoalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomerConversionGoalServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomerConversionGoalServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomerConversionGoalServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerConversionGoalServiceTransport - ) - if transport_provided: - # transport is a CustomerConversionGoalServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CustomerConversionGoalServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerConversionGoalServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerConversionGoalServiceTransport], - Callable[..., CustomerConversionGoalServiceTransport], - ] = ( - CustomerConversionGoalServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomerConversionGoalServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerConversionGoalServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerConversionGoalService", - "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.ads.googleads.v19.services.CustomerConversionGoalService", - "credentialsType": None, - } - ), - ) - - def mutate_customer_conversion_goals( - self, - request: Optional[ - Union[ - customer_conversion_goal_service.MutateCustomerConversionGoalsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customer_conversion_goal_service.CustomerConversionGoalOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_conversion_goal_service.MutateCustomerConversionGoalsResponse: - r"""Creates, updates or removes customer conversion - goals. Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerConversionGoalsRequest, dict]): - The request object. Request message for - [CustomerConversionGoalService.MutateCustomerConversionGoals][google.ads.googleads.v19.services.CustomerConversionGoalService.MutateCustomerConversionGoals]. - customer_id (str): - Required. The ID of the customer - whose customer conversion goals are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerConversionGoalOperation]): - Required. The list of operations to - perform on individual customer - conversion goal. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerConversionGoalsResponse: - Response message for a customer - conversion goal mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_conversion_goal_service.MutateCustomerConversionGoalsRequest, - ): - request = customer_conversion_goal_service.MutateCustomerConversionGoalsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customer_conversion_goals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerConversionGoalServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerConversionGoalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/base.py deleted file mode 100644 index 0e10d119f..000000000 --- a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - customer_conversion_goal_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerConversionGoalServiceTransport(abc.ABC): - """Abstract transport class for CustomerConversionGoalService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer_conversion_goals: gapic_v1.method.wrap_method( - self.mutate_customer_conversion_goals, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer_conversion_goals( - self, - ) -> Callable[ - [customer_conversion_goal_service.MutateCustomerConversionGoalsRequest], - Union[ - customer_conversion_goal_service.MutateCustomerConversionGoalsResponse, - Awaitable[ - customer_conversion_goal_service.MutateCustomerConversionGoalsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerConversionGoalServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/grpc.py deleted file mode 100644 index 685da2bfe..000000000 --- a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/grpc.py +++ /dev/null @@ -1,387 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - customer_conversion_goal_service, -) -from .base import CustomerConversionGoalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerConversionGoalService", - "rpcName": str(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.ads.googleads.v19.services.CustomerConversionGoalService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerConversionGoalServiceGrpcTransport( - CustomerConversionGoalServiceTransport -): - """gRPC backend transport for CustomerConversionGoalService. - - Service to manage customer conversion goal. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer_conversion_goals( - self, - ) -> Callable[ - [customer_conversion_goal_service.MutateCustomerConversionGoalsRequest], - customer_conversion_goal_service.MutateCustomerConversionGoalsResponse, - ]: - r"""Return a callable for the mutate customer conversion - goals method over gRPC. - - Creates, updates or removes customer conversion - goals. Operation statuses are returned. - - Returns: - Callable[[~.MutateCustomerConversionGoalsRequest], - ~.MutateCustomerConversionGoalsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_conversion_goals" not in self._stubs: - self._stubs["mutate_customer_conversion_goals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerConversionGoalService/MutateCustomerConversionGoals", - request_serializer=customer_conversion_goal_service.MutateCustomerConversionGoalsRequest.serialize, - response_deserializer=customer_conversion_goal_service.MutateCustomerConversionGoalsResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_conversion_goals"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerConversionGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/grpc_asyncio.py deleted file mode 100644 index 1adafbf7d..000000000 --- a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,410 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_conversion_goal_service, -) -from .base import CustomerConversionGoalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerConversionGoalService", - "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.ads.googleads.v19.services.CustomerConversionGoalService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerConversionGoalServiceGrpcAsyncIOTransport( - CustomerConversionGoalServiceTransport -): - """gRPC AsyncIO backend transport for CustomerConversionGoalService. - - Service to manage customer conversion goal. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer_conversion_goals( - self, - ) -> Callable[ - [customer_conversion_goal_service.MutateCustomerConversionGoalsRequest], - Awaitable[ - customer_conversion_goal_service.MutateCustomerConversionGoalsResponse - ], - ]: - r"""Return a callable for the mutate customer conversion - goals method over gRPC. - - Creates, updates or removes customer conversion - goals. Operation statuses are returned. - - Returns: - Callable[[~.MutateCustomerConversionGoalsRequest], - Awaitable[~.MutateCustomerConversionGoalsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_conversion_goals" not in self._stubs: - self._stubs["mutate_customer_conversion_goals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerConversionGoalService/MutateCustomerConversionGoals", - request_serializer=customer_conversion_goal_service.MutateCustomerConversionGoalsRequest.serialize, - response_deserializer=customer_conversion_goal_service.MutateCustomerConversionGoalsResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_conversion_goals"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer_conversion_goals: self._wrap_method( - self.mutate_customer_conversion_goals, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerConversionGoalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_customizer_service/async_client.py b/google/ads/googleads/v19/services/services/customer_customizer_service/async_client.py deleted file mode 100644 index 891eb6618..000000000 --- a/google/ads/googleads/v19/services/services/customer_customizer_service/async_client.py +++ /dev/null @@ -1,441 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import customer_customizer_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CustomerCustomizerServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomerCustomizerServiceClient - -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 CustomerCustomizerServiceAsyncClient: - """Service to manage customer customizer""" - - _client: CustomerCustomizerServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomerCustomizerServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CustomerCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomerCustomizerServiceClient._DEFAULT_UNIVERSE - - customer_customizer_path = staticmethod( - CustomerCustomizerServiceClient.customer_customizer_path - ) - parse_customer_customizer_path = staticmethod( - CustomerCustomizerServiceClient.parse_customer_customizer_path - ) - customizer_attribute_path = staticmethod( - CustomerCustomizerServiceClient.customizer_attribute_path - ) - parse_customizer_attribute_path = staticmethod( - CustomerCustomizerServiceClient.parse_customizer_attribute_path - ) - common_billing_account_path = staticmethod( - CustomerCustomizerServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerCustomizerServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerCustomizerServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerCustomizerServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerCustomizerServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerCustomizerServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerCustomizerServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerCustomizerServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerCustomizerServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerCustomizerServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerCustomizerServiceAsyncClient: The constructed client. - """ - return CustomerCustomizerServiceClient.from_service_account_info.__func__(CustomerCustomizerServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerCustomizerServiceAsyncClient: The constructed client. - """ - return CustomerCustomizerServiceClient.from_service_account_file.__func__(CustomerCustomizerServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerCustomizerServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerCustomizerServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerCustomizerServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomerCustomizerServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerCustomizerServiceTransport, - Callable[..., CustomerCustomizerServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer customizer service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerCustomizerServiceTransport,Callable[..., CustomerCustomizerServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerCustomizerServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerCustomizerServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerCustomizerServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerCustomizerService", - "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.ads.googleads.v19.services.CustomerCustomizerService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer_customizers( - self, - request: Optional[ - Union[ - customer_customizer_service.MutateCustomerCustomizersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customer_customizer_service.CustomerCustomizerOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_customizer_service.MutateCustomerCustomizersResponse: - r"""Creates, updates or removes customer customizers. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerCustomizersRequest, dict]]): - The request object. Request message for - [CustomerCustomizerService.MutateCustomerCustomizers][google.ads.googleads.v19.services.CustomerCustomizerService.MutateCustomerCustomizers]. - customer_id (:class:`str`): - Required. The ID of the customer - whose customer customizers are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CustomerCustomizerOperation]`): - Required. The list of operations to - perform on individual customer - customizers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerCustomizersResponse: - Response message for a customizer - attribute mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_customizer_service.MutateCustomerCustomizersRequest, - ): - request = ( - customer_customizer_service.MutateCustomerCustomizersRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer_customizers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomerCustomizerServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerCustomizerServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_customizer_service/client.py b/google/ads/googleads/v19/services/services/customer_customizer_service/client.py deleted file mode 100644 index 120855c30..000000000 --- a/google/ads/googleads/v19/services/services/customer_customizer_service/client.py +++ /dev/null @@ -1,915 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import customer_customizer_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CustomerCustomizerServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CustomerCustomizerServiceGrpcTransport -from .transports.grpc_asyncio import ( - CustomerCustomizerServiceGrpcAsyncIOTransport, -) - - -class CustomerCustomizerServiceClientMeta(type): - """Metaclass for the CustomerCustomizerService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerCustomizerServiceTransport]] - _transport_registry["grpc"] = CustomerCustomizerServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomerCustomizerServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerCustomizerServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerCustomizerServiceClient( - metaclass=CustomerCustomizerServiceClientMeta -): - """Service to manage customer customizer""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerCustomizerServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerCustomizerServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerCustomizerServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerCustomizerServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_customizer_path( - customer_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified customer_customizer string.""" - return "customers/{customer_id}/customerCustomizers/{customizer_attribute_id}".format( - customer_id=customer_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_customer_customizer_path(path: str) -> Dict[str, str]: - """Parses a customer_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerCustomizers/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customizer_attribute_path( - customer_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified customizer_attribute string.""" - return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( - customer_id=customer_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_customizer_attribute_path(path: str) -> Dict[str, str]: - """Parses a customizer_attribute path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CustomerCustomizerServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CustomerCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = CustomerCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomerCustomizerServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerCustomizerServiceTransport, - Callable[..., CustomerCustomizerServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer customizer service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerCustomizerServiceTransport,Callable[..., CustomerCustomizerServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerCustomizerServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomerCustomizerServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomerCustomizerServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomerCustomizerServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerCustomizerServiceTransport - ) - if transport_provided: - # transport is a CustomerCustomizerServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CustomerCustomizerServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerCustomizerServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerCustomizerServiceTransport], - Callable[..., CustomerCustomizerServiceTransport], - ] = ( - CustomerCustomizerServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomerCustomizerServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerCustomizerServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerCustomizerService", - "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.ads.googleads.v19.services.CustomerCustomizerService", - "credentialsType": None, - } - ), - ) - - def mutate_customer_customizers( - self, - request: Optional[ - Union[ - customer_customizer_service.MutateCustomerCustomizersRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customer_customizer_service.CustomerCustomizerOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_customizer_service.MutateCustomerCustomizersResponse: - r"""Creates, updates or removes customer customizers. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerCustomizersRequest, dict]): - The request object. Request message for - [CustomerCustomizerService.MutateCustomerCustomizers][google.ads.googleads.v19.services.CustomerCustomizerService.MutateCustomerCustomizers]. - customer_id (str): - Required. The ID of the customer - whose customer customizers are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerCustomizerOperation]): - Required. The list of operations to - perform on individual customer - customizers. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerCustomizersResponse: - Response message for a customizer - attribute mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_customizer_service.MutateCustomerCustomizersRequest, - ): - request = ( - customer_customizer_service.MutateCustomerCustomizersRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customer_customizers - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerCustomizerServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerCustomizerServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_customizer_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_customizer_service/transports/base.py deleted file mode 100644 index fc4188142..000000000 --- a/google/ads/googleads/v19/services/services/customer_customizer_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import customer_customizer_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerCustomizerServiceTransport(abc.ABC): - """Abstract transport class for CustomerCustomizerService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer_customizers: gapic_v1.method.wrap_method( - self.mutate_customer_customizers, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer_customizers( - self, - ) -> Callable[ - [customer_customizer_service.MutateCustomerCustomizersRequest], - Union[ - customer_customizer_service.MutateCustomerCustomizersResponse, - Awaitable[ - customer_customizer_service.MutateCustomerCustomizersResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerCustomizerServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_customizer_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_customizer_service/transports/grpc.py deleted file mode 100644 index 0d5a7bfb1..000000000 --- a/google/ads/googleads/v19/services/services/customer_customizer_service/transports/grpc.py +++ /dev/null @@ -1,384 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import customer_customizer_service -from .base import CustomerCustomizerServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerCustomizerService", - "rpcName": str(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.ads.googleads.v19.services.CustomerCustomizerService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerCustomizerServiceGrpcTransport( - CustomerCustomizerServiceTransport -): - """gRPC backend transport for CustomerCustomizerService. - - Service to manage customer customizer - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer_customizers( - self, - ) -> Callable[ - [customer_customizer_service.MutateCustomerCustomizersRequest], - customer_customizer_service.MutateCustomerCustomizersResponse, - ]: - r"""Return a callable for the mutate customer customizers method over gRPC. - - Creates, updates or removes customer customizers. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCustomerCustomizersRequest], - ~.MutateCustomerCustomizersResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_customizers" not in self._stubs: - self._stubs["mutate_customer_customizers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerCustomizerService/MutateCustomerCustomizers", - request_serializer=customer_customizer_service.MutateCustomerCustomizersRequest.serialize, - response_deserializer=customer_customizer_service.MutateCustomerCustomizersResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_customizers"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_customizer_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_customizer_service/transports/grpc_asyncio.py deleted file mode 100644 index f7b06b83f..000000000 --- a/google/ads/googleads/v19/services/services/customer_customizer_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,407 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import customer_customizer_service -from .base import CustomerCustomizerServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerCustomizerService", - "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.ads.googleads.v19.services.CustomerCustomizerService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerCustomizerServiceGrpcAsyncIOTransport( - CustomerCustomizerServiceTransport -): - """gRPC AsyncIO backend transport for CustomerCustomizerService. - - Service to manage customer customizer - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer_customizers( - self, - ) -> Callable[ - [customer_customizer_service.MutateCustomerCustomizersRequest], - Awaitable[ - customer_customizer_service.MutateCustomerCustomizersResponse - ], - ]: - r"""Return a callable for the mutate customer customizers method over gRPC. - - Creates, updates or removes customer customizers. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCustomerCustomizersRequest], - Awaitable[~.MutateCustomerCustomizersResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_customizers" not in self._stubs: - self._stubs["mutate_customer_customizers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerCustomizerService/MutateCustomerCustomizers", - request_serializer=customer_customizer_service.MutateCustomerCustomizersRequest.serialize, - response_deserializer=customer_customizer_service.MutateCustomerCustomizersResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_customizers"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer_customizers: self._wrap_method( - self.mutate_customer_customizers, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerCustomizerServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_label_service/async_client.py b/google/ads/googleads/v19/services/services/customer_label_service/async_client.py deleted file mode 100644 index 7f7634d61..000000000 --- a/google/ads/googleads/v19/services/services/customer_label_service/async_client.py +++ /dev/null @@ -1,432 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import customer_label_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CustomerLabelServiceTransport, DEFAULT_CLIENT_INFO -from .client import CustomerLabelServiceClient - -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 CustomerLabelServiceAsyncClient: - """Service to manage labels on customers.""" - - _client: CustomerLabelServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomerLabelServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CustomerLabelServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomerLabelServiceClient._DEFAULT_UNIVERSE - - customer_path = staticmethod(CustomerLabelServiceClient.customer_path) - parse_customer_path = staticmethod( - CustomerLabelServiceClient.parse_customer_path - ) - customer_label_path = staticmethod( - CustomerLabelServiceClient.customer_label_path - ) - parse_customer_label_path = staticmethod( - CustomerLabelServiceClient.parse_customer_label_path - ) - label_path = staticmethod(CustomerLabelServiceClient.label_path) - parse_label_path = staticmethod(CustomerLabelServiceClient.parse_label_path) - common_billing_account_path = staticmethod( - CustomerLabelServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerLabelServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerLabelServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerLabelServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerLabelServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerLabelServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerLabelServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerLabelServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerLabelServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerLabelServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerLabelServiceAsyncClient: The constructed client. - """ - return CustomerLabelServiceClient.from_service_account_info.__func__(CustomerLabelServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerLabelServiceAsyncClient: The constructed client. - """ - return CustomerLabelServiceClient.from_service_account_file.__func__(CustomerLabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerLabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerLabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerLabelServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomerLabelServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerLabelServiceTransport, - Callable[..., CustomerLabelServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer label service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerLabelServiceTransport,Callable[..., CustomerLabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerLabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerLabelServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerLabelServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerLabelService", - "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.ads.googleads.v19.services.CustomerLabelService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer_labels( - self, - request: Optional[ - Union[customer_label_service.MutateCustomerLabelsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[customer_label_service.CustomerLabelOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_label_service.MutateCustomerLabelsResponse: - r"""Creates and removes customer-label relationships. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerLabelsRequest, dict]]): - The request object. Request message for - [CustomerLabelService.MutateCustomerLabels][google.ads.googleads.v19.services.CustomerLabelService.MutateCustomerLabels]. - customer_id (:class:`str`): - Required. ID of the customer whose - customer-label relationships are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CustomerLabelOperation]`): - Required. The list of operations to - perform on customer-label relationships. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerLabelsResponse: - Response message for a customer - labels mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_label_service.MutateCustomerLabelsRequest - ): - request = customer_label_service.MutateCustomerLabelsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer_labels - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomerLabelServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerLabelServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_label_service/client.py b/google/ads/googleads/v19/services/services/customer_label_service/client.py deleted file mode 100644 index 1e9aaa82a..000000000 --- a/google/ads/googleads/v19/services/services/customer_label_service/client.py +++ /dev/null @@ -1,914 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import customer_label_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import CustomerLabelServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CustomerLabelServiceGrpcTransport -from .transports.grpc_asyncio import CustomerLabelServiceGrpcAsyncIOTransport - - -class CustomerLabelServiceClientMeta(type): - """Metaclass for the CustomerLabelService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerLabelServiceTransport]] - _transport_registry["grpc"] = CustomerLabelServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomerLabelServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerLabelServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerLabelServiceClient(metaclass=CustomerLabelServiceClientMeta): - """Service to manage labels on customers.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerLabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerLabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerLabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerLabelServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def customer_label_path( - customer_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified customer_label string.""" - return "customers/{customer_id}/customerLabels/{label_id}".format( - customer_id=customer_id, - label_id=label_id, - ) - - @staticmethod - def parse_customer_label_path(path: str) -> Dict[str, str]: - """Parses a customer_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerLabels/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def label_path( - customer_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified label string.""" - return "customers/{customer_id}/labels/{label_id}".format( - customer_id=customer_id, - label_id=label_id, - ) - - @staticmethod - def parse_label_path(path: str) -> Dict[str, str]: - """Parses a label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/labels/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CustomerLabelServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CustomerLabelServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CustomerLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomerLabelServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerLabelServiceTransport, - Callable[..., CustomerLabelServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer label service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerLabelServiceTransport,Callable[..., CustomerLabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerLabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomerLabelServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomerLabelServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = CustomerLabelServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerLabelServiceTransport - ) - if transport_provided: - # transport is a CustomerLabelServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CustomerLabelServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerLabelServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerLabelServiceTransport], - Callable[..., CustomerLabelServiceTransport], - ] = ( - CustomerLabelServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomerLabelServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerLabelServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerLabelService", - "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.ads.googleads.v19.services.CustomerLabelService", - "credentialsType": None, - } - ), - ) - - def mutate_customer_labels( - self, - request: Optional[ - Union[customer_label_service.MutateCustomerLabelsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[customer_label_service.CustomerLabelOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_label_service.MutateCustomerLabelsResponse: - r"""Creates and removes customer-label relationships. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerLabelsRequest, dict]): - The request object. Request message for - [CustomerLabelService.MutateCustomerLabels][google.ads.googleads.v19.services.CustomerLabelService.MutateCustomerLabels]. - customer_id (str): - Required. ID of the customer whose - customer-label relationships are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerLabelOperation]): - Required. The list of operations to - perform on customer-label relationships. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerLabelsResponse: - Response message for a customer - labels mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_label_service.MutateCustomerLabelsRequest - ): - request = customer_label_service.MutateCustomerLabelsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customer_labels - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerLabelServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerLabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_label_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_label_service/transports/base.py deleted file mode 100644 index 919654324..000000000 --- a/google/ads/googleads/v19/services/services/customer_label_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import customer_label_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerLabelServiceTransport(abc.ABC): - """Abstract transport class for CustomerLabelService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer_labels: gapic_v1.method.wrap_method( - self.mutate_customer_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer_labels( - self, - ) -> Callable[ - [customer_label_service.MutateCustomerLabelsRequest], - Union[ - customer_label_service.MutateCustomerLabelsResponse, - Awaitable[customer_label_service.MutateCustomerLabelsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerLabelServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_label_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_label_service/transports/grpc.py deleted file mode 100644 index 901fffb37..000000000 --- a/google/ads/googleads/v19/services/services/customer_label_service/transports/grpc.py +++ /dev/null @@ -1,387 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import customer_label_service -from .base import CustomerLabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerLabelService", - "rpcName": str(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.ads.googleads.v19.services.CustomerLabelService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerLabelServiceGrpcTransport(CustomerLabelServiceTransport): - """gRPC backend transport for CustomerLabelService. - - Service to manage labels on customers. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer_labels( - self, - ) -> Callable[ - [customer_label_service.MutateCustomerLabelsRequest], - customer_label_service.MutateCustomerLabelsResponse, - ]: - r"""Return a callable for the mutate customer labels method over gRPC. - - Creates and removes customer-label relationships. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerLabelsRequest], - ~.MutateCustomerLabelsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_labels" not in self._stubs: - self._stubs["mutate_customer_labels"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerLabelService/MutateCustomerLabels", - request_serializer=customer_label_service.MutateCustomerLabelsRequest.serialize, - response_deserializer=customer_label_service.MutateCustomerLabelsResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_labels"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_label_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_label_service/transports/grpc_asyncio.py deleted file mode 100644 index 134b7288b..000000000 --- a/google/ads/googleads/v19/services/services/customer_label_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,408 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import customer_label_service -from .base import CustomerLabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerLabelService", - "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.ads.googleads.v19.services.CustomerLabelService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerLabelServiceGrpcAsyncIOTransport(CustomerLabelServiceTransport): - """gRPC AsyncIO backend transport for CustomerLabelService. - - Service to manage labels on customers. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer_labels( - self, - ) -> Callable[ - [customer_label_service.MutateCustomerLabelsRequest], - Awaitable[customer_label_service.MutateCustomerLabelsResponse], - ]: - r"""Return a callable for the mutate customer labels method over gRPC. - - Creates and removes customer-label relationships. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerLabelsRequest], - Awaitable[~.MutateCustomerLabelsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_labels" not in self._stubs: - self._stubs["mutate_customer_labels"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerLabelService/MutateCustomerLabels", - request_serializer=customer_label_service.MutateCustomerLabelsRequest.serialize, - response_deserializer=customer_label_service.MutateCustomerLabelsResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_labels"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer_labels: self._wrap_method( - self.mutate_customer_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerLabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/async_client.py b/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/async_client.py deleted file mode 100644 index b26be58c7..000000000 --- a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/async_client.py +++ /dev/null @@ -1,442 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_lifecycle_goal_service, -) -from .transports.base import ( - CustomerLifecycleGoalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomerLifecycleGoalServiceClient - -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 CustomerLifecycleGoalServiceAsyncClient: - """Service to configure customer lifecycle goals.""" - - _client: CustomerLifecycleGoalServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomerLifecycleGoalServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CustomerLifecycleGoalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerLifecycleGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomerLifecycleGoalServiceClient._DEFAULT_UNIVERSE - - customer_path = staticmethod( - CustomerLifecycleGoalServiceClient.customer_path - ) - parse_customer_path = staticmethod( - CustomerLifecycleGoalServiceClient.parse_customer_path - ) - customer_lifecycle_goal_path = staticmethod( - CustomerLifecycleGoalServiceClient.customer_lifecycle_goal_path - ) - parse_customer_lifecycle_goal_path = staticmethod( - CustomerLifecycleGoalServiceClient.parse_customer_lifecycle_goal_path - ) - common_billing_account_path = staticmethod( - CustomerLifecycleGoalServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerLifecycleGoalServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerLifecycleGoalServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerLifecycleGoalServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerLifecycleGoalServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerLifecycleGoalServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerLifecycleGoalServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerLifecycleGoalServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerLifecycleGoalServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerLifecycleGoalServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerLifecycleGoalServiceAsyncClient: The constructed client. - """ - return CustomerLifecycleGoalServiceClient.from_service_account_info.__func__(CustomerLifecycleGoalServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerLifecycleGoalServiceAsyncClient: The constructed client. - """ - return CustomerLifecycleGoalServiceClient.from_service_account_file.__func__(CustomerLifecycleGoalServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerLifecycleGoalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerLifecycleGoalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerLifecycleGoalServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomerLifecycleGoalServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerLifecycleGoalServiceTransport, - Callable[..., CustomerLifecycleGoalServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer lifecycle goal service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerLifecycleGoalServiceTransport,Callable[..., CustomerLifecycleGoalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerLifecycleGoalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerLifecycleGoalServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerLifecycleGoalServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerLifecycleGoalService", - "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.ads.googleads.v19.services.CustomerLifecycleGoalService", - "credentialsType": None, - } - ), - ) - - async def configure_customer_lifecycle_goals( - self, - request: Optional[ - Union[ - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - customer_lifecycle_goal_service.CustomerLifecycleGoalOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse - ): - r"""Process the given customer lifecycle configurations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `CustomerLifecycleGoalConfigError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ConfigureCustomerLifecycleGoalsRequest, dict]]): - The request object. Request message for - [CustomerLifecycleGoalService.configureCustomerLifecycleGoals][]. - customer_id (:class:`str`): - Required. The ID of the customer - performing the upload. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (:class:`google.ads.googleads.v19.services.types.CustomerLifecycleGoalOperation`): - Required. The operation to perform - customer lifecycle goal update. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ConfigureCustomerLifecycleGoalsResponse: - Response message for - [CustomerLifecycleGoalService.configureCustomerLifecycleGoals][]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest, - ): - request = customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.configure_customer_lifecycle_goals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomerLifecycleGoalServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerLifecycleGoalServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/client.py b/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/client.py deleted file mode 100644 index 2f64b68c6..000000000 --- a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/client.py +++ /dev/null @@ -1,903 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - customer_lifecycle_goal_service, -) -from .transports.base import ( - CustomerLifecycleGoalServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CustomerLifecycleGoalServiceGrpcTransport -from .transports.grpc_asyncio import ( - CustomerLifecycleGoalServiceGrpcAsyncIOTransport, -) - - -class CustomerLifecycleGoalServiceClientMeta(type): - """Metaclass for the CustomerLifecycleGoalService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerLifecycleGoalServiceTransport]] - _transport_registry["grpc"] = CustomerLifecycleGoalServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomerLifecycleGoalServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerLifecycleGoalServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerLifecycleGoalServiceClient( - metaclass=CustomerLifecycleGoalServiceClientMeta -): - """Service to configure customer lifecycle goals.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerLifecycleGoalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerLifecycleGoalServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerLifecycleGoalServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerLifecycleGoalServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def customer_lifecycle_goal_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer_lifecycle_goal string.""" - return "customers/{customer_id}/customerLifecycleGoals".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_lifecycle_goal_path(path: str) -> Dict[str, str]: - """Parses a customer_lifecycle_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerLifecycleGoals$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CustomerLifecycleGoalServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - CustomerLifecycleGoalServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = CustomerLifecycleGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomerLifecycleGoalServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerLifecycleGoalServiceTransport, - Callable[..., CustomerLifecycleGoalServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer lifecycle goal service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerLifecycleGoalServiceTransport,Callable[..., CustomerLifecycleGoalServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerLifecycleGoalServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomerLifecycleGoalServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomerLifecycleGoalServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomerLifecycleGoalServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerLifecycleGoalServiceTransport - ) - if transport_provided: - # transport is a CustomerLifecycleGoalServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CustomerLifecycleGoalServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerLifecycleGoalServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerLifecycleGoalServiceTransport], - Callable[..., CustomerLifecycleGoalServiceTransport], - ] = ( - CustomerLifecycleGoalServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomerLifecycleGoalServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerLifecycleGoalServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerLifecycleGoalService", - "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.ads.googleads.v19.services.CustomerLifecycleGoalService", - "credentialsType": None, - } - ), - ) - - def configure_customer_lifecycle_goals( - self, - request: Optional[ - Union[ - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - customer_lifecycle_goal_service.CustomerLifecycleGoalOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse - ): - r"""Process the given customer lifecycle configurations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `CustomerLifecycleGoalConfigError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ConfigureCustomerLifecycleGoalsRequest, dict]): - The request object. Request message for - [CustomerLifecycleGoalService.configureCustomerLifecycleGoals][]. - customer_id (str): - Required. The ID of the customer - performing the upload. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (google.ads.googleads.v19.services.types.CustomerLifecycleGoalOperation): - Required. The operation to perform - customer lifecycle goal update. - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ConfigureCustomerLifecycleGoalsResponse: - Response message for - [CustomerLifecycleGoalService.configureCustomerLifecycleGoals][]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest, - ): - request = customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.configure_customer_lifecycle_goals - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerLifecycleGoalServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerLifecycleGoalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/base.py deleted file mode 100644 index 27202b3e3..000000000 --- a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - customer_lifecycle_goal_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerLifecycleGoalServiceTransport(abc.ABC): - """Abstract transport class for CustomerLifecycleGoalService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.configure_customer_lifecycle_goals: gapic_v1.method.wrap_method( - self.configure_customer_lifecycle_goals, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def configure_customer_lifecycle_goals( - self, - ) -> Callable[ - [ - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest - ], - Union[ - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse, - Awaitable[ - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerLifecycleGoalServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/grpc.py deleted file mode 100644 index a440d5e8a..000000000 --- a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/grpc.py +++ /dev/null @@ -1,393 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - customer_lifecycle_goal_service, -) -from .base import CustomerLifecycleGoalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerLifecycleGoalService", - "rpcName": str(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.ads.googleads.v19.services.CustomerLifecycleGoalService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerLifecycleGoalServiceGrpcTransport( - CustomerLifecycleGoalServiceTransport -): - """gRPC backend transport for CustomerLifecycleGoalService. - - Service to configure customer lifecycle goals. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def configure_customer_lifecycle_goals( - self, - ) -> Callable[ - [ - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest - ], - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse, - ]: - r"""Return a callable for the configure customer lifecycle - goals method over gRPC. - - Process the given customer lifecycle configurations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `CustomerLifecycleGoalConfigError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ConfigureCustomerLifecycleGoalsRequest], - ~.ConfigureCustomerLifecycleGoalsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "configure_customer_lifecycle_goals" not in self._stubs: - self._stubs["configure_customer_lifecycle_goals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerLifecycleGoalService/ConfigureCustomerLifecycleGoals", - request_serializer=customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest.serialize, - response_deserializer=customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse.deserialize, - ) - ) - return self._stubs["configure_customer_lifecycle_goals"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerLifecycleGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/grpc_asyncio.py deleted file mode 100644 index fcc402ac6..000000000 --- a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,416 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_lifecycle_goal_service, -) -from .base import CustomerLifecycleGoalServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerLifecycleGoalService", - "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.ads.googleads.v19.services.CustomerLifecycleGoalService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerLifecycleGoalServiceGrpcAsyncIOTransport( - CustomerLifecycleGoalServiceTransport -): - """gRPC AsyncIO backend transport for CustomerLifecycleGoalService. - - Service to configure customer lifecycle goals. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def configure_customer_lifecycle_goals( - self, - ) -> Callable[ - [ - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest - ], - Awaitable[ - customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse - ], - ]: - r"""Return a callable for the configure customer lifecycle - goals method over gRPC. - - Process the given customer lifecycle configurations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `CustomerLifecycleGoalConfigError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ConfigureCustomerLifecycleGoalsRequest], - Awaitable[~.ConfigureCustomerLifecycleGoalsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "configure_customer_lifecycle_goals" not in self._stubs: - self._stubs["configure_customer_lifecycle_goals"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerLifecycleGoalService/ConfigureCustomerLifecycleGoals", - request_serializer=customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest.serialize, - response_deserializer=customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse.deserialize, - ) - ) - return self._stubs["configure_customer_lifecycle_goals"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.configure_customer_lifecycle_goals: self._wrap_method( - self.configure_customer_lifecycle_goals, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerLifecycleGoalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_manager_link_service/async_client.py b/google/ads/googleads/v19/services/services/customer_manager_link_service/async_client.py deleted file mode 100644 index 4cd1a3ca0..000000000 --- a/google/ads/googleads/v19/services/services/customer_manager_link_service/async_client.py +++ /dev/null @@ -1,576 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_manager_link_service, -) -from .transports.base import ( - CustomerManagerLinkServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomerManagerLinkServiceClient - -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 CustomerManagerLinkServiceAsyncClient: - """Service to manage customer-manager links.""" - - _client: CustomerManagerLinkServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomerManagerLinkServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CustomerManagerLinkServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerManagerLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomerManagerLinkServiceClient._DEFAULT_UNIVERSE - - customer_path = staticmethod(CustomerManagerLinkServiceClient.customer_path) - parse_customer_path = staticmethod( - CustomerManagerLinkServiceClient.parse_customer_path - ) - customer_manager_link_path = staticmethod( - CustomerManagerLinkServiceClient.customer_manager_link_path - ) - parse_customer_manager_link_path = staticmethod( - CustomerManagerLinkServiceClient.parse_customer_manager_link_path - ) - common_billing_account_path = staticmethod( - CustomerManagerLinkServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerManagerLinkServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerManagerLinkServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerManagerLinkServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerManagerLinkServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerManagerLinkServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerManagerLinkServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerManagerLinkServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerManagerLinkServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerManagerLinkServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerManagerLinkServiceAsyncClient: The constructed client. - """ - return CustomerManagerLinkServiceClient.from_service_account_info.__func__(CustomerManagerLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerManagerLinkServiceAsyncClient: The constructed client. - """ - return CustomerManagerLinkServiceClient.from_service_account_file.__func__(CustomerManagerLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerManagerLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerManagerLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerManagerLinkServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomerManagerLinkServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerManagerLinkServiceTransport, - Callable[..., CustomerManagerLinkServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer manager link service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerManagerLinkServiceTransport,Callable[..., CustomerManagerLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerManagerLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerManagerLinkServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerManagerLinkServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerManagerLinkService", - "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.ads.googleads.v19.services.CustomerManagerLinkService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer_manager_link( - self, - request: Optional[ - Union[ - customer_manager_link_service.MutateCustomerManagerLinkRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customer_manager_link_service.CustomerManagerLinkOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_manager_link_service.MutateCustomerManagerLinkResponse: - r"""Updates customer manager links. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerManagerLinkRequest, dict]]): - The request object. Request message for - [CustomerManagerLinkService.MutateCustomerManagerLink][google.ads.googleads.v19.services.CustomerManagerLinkService.MutateCustomerManagerLink]. - customer_id (:class:`str`): - Required. The ID of the customer - whose customer manager links are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CustomerManagerLinkOperation]`): - Required. The list of operations to - perform on individual customer manager - links. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerManagerLinkResponse: - Response message for a - CustomerManagerLink mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_manager_link_service.MutateCustomerManagerLinkRequest, - ): - request = ( - customer_manager_link_service.MutateCustomerManagerLinkRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer_manager_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def move_manager_link( - self, - request: Optional[ - Union[customer_manager_link_service.MoveManagerLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - previous_customer_manager_link: Optional[str] = None, - new_manager: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_manager_link_service.MoveManagerLinkResponse: - r"""Moves a client customer to a new manager customer. This - simplifies the complex request that requires two operations to - move a client customer to a new manager, for example: - - 1. Update operation with Status INACTIVE (previous manager) and, - 2. Update operation with Status ACTIVE (new manager). - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MoveManagerLinkRequest, dict]]): - The request object. Request message for - [CustomerManagerLinkService.MoveManagerLink][google.ads.googleads.v19.services.CustomerManagerLinkService.MoveManagerLink]. - customer_id (:class:`str`): - Required. The ID of the client - customer that is being moved. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - previous_customer_manager_link (:class:`str`): - Required. The resource name of the previous - CustomerManagerLink. The resource name has the form: - ``customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}`` - - This corresponds to the ``previous_customer_manager_link`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - new_manager (:class:`str`): - Required. The resource name of the new manager customer - that the client wants to move to. Customer resource - names have the format: "customers/{customer_id}" - - This corresponds to the ``new_manager`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MoveManagerLinkResponse: - Response message for a - CustomerManagerLink moveManagerLink. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [ - customer_id, - previous_customer_manager_link, - new_manager, - ] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_manager_link_service.MoveManagerLinkRequest - ): - request = customer_manager_link_service.MoveManagerLinkRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if previous_customer_manager_link is not None: - request.previous_customer_manager_link = ( - previous_customer_manager_link - ) - if new_manager is not None: - request.new_manager = new_manager - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.move_manager_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomerManagerLinkServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerManagerLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_manager_link_service/client.py b/google/ads/googleads/v19/services/services/customer_manager_link_service/client.py deleted file mode 100644 index 785177b75..000000000 --- a/google/ads/googleads/v19/services/services/customer_manager_link_service/client.py +++ /dev/null @@ -1,1051 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - customer_manager_link_service, -) -from .transports.base import ( - CustomerManagerLinkServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CustomerManagerLinkServiceGrpcTransport -from .transports.grpc_asyncio import ( - CustomerManagerLinkServiceGrpcAsyncIOTransport, -) - - -class CustomerManagerLinkServiceClientMeta(type): - """Metaclass for the CustomerManagerLinkService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerManagerLinkServiceTransport]] - _transport_registry["grpc"] = CustomerManagerLinkServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomerManagerLinkServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerManagerLinkServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerManagerLinkServiceClient( - metaclass=CustomerManagerLinkServiceClientMeta -): - """Service to manage customer-manager links.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerManagerLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerManagerLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerManagerLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerManagerLinkServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def customer_manager_link_path( - customer_id: str, - manager_customer_id: str, - manager_link_id: str, - ) -> str: - """Returns a fully-qualified customer_manager_link string.""" - return "customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}".format( - customer_id=customer_id, - manager_customer_id=manager_customer_id, - manager_link_id=manager_link_id, - ) - - @staticmethod - def parse_customer_manager_link_path(path: str) -> Dict[str, str]: - """Parses a customer_manager_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerManagerLinks/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CustomerManagerLinkServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - CustomerManagerLinkServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = CustomerManagerLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomerManagerLinkServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerManagerLinkServiceTransport, - Callable[..., CustomerManagerLinkServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer manager link service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerManagerLinkServiceTransport,Callable[..., CustomerManagerLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerManagerLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomerManagerLinkServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomerManagerLinkServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomerManagerLinkServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerManagerLinkServiceTransport - ) - if transport_provided: - # transport is a CustomerManagerLinkServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CustomerManagerLinkServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerManagerLinkServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerManagerLinkServiceTransport], - Callable[..., CustomerManagerLinkServiceTransport], - ] = ( - CustomerManagerLinkServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomerManagerLinkServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerManagerLinkServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerManagerLinkService", - "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.ads.googleads.v19.services.CustomerManagerLinkService", - "credentialsType": None, - } - ), - ) - - def mutate_customer_manager_link( - self, - request: Optional[ - Union[ - customer_manager_link_service.MutateCustomerManagerLinkRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customer_manager_link_service.CustomerManagerLinkOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_manager_link_service.MutateCustomerManagerLinkResponse: - r"""Updates customer manager links. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerManagerLinkRequest, dict]): - The request object. Request message for - [CustomerManagerLinkService.MutateCustomerManagerLink][google.ads.googleads.v19.services.CustomerManagerLinkService.MutateCustomerManagerLink]. - customer_id (str): - Required. The ID of the customer - whose customer manager links are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerManagerLinkOperation]): - Required. The list of operations to - perform on individual customer manager - links. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerManagerLinkResponse: - Response message for a - CustomerManagerLink mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_manager_link_service.MutateCustomerManagerLinkRequest, - ): - request = ( - customer_manager_link_service.MutateCustomerManagerLinkRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customer_manager_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def move_manager_link( - self, - request: Optional[ - Union[customer_manager_link_service.MoveManagerLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - previous_customer_manager_link: Optional[str] = None, - new_manager: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_manager_link_service.MoveManagerLinkResponse: - r"""Moves a client customer to a new manager customer. This - simplifies the complex request that requires two operations to - move a client customer to a new manager, for example: - - 1. Update operation with Status INACTIVE (previous manager) and, - 2. Update operation with Status ACTIVE (new manager). - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MoveManagerLinkRequest, dict]): - The request object. Request message for - [CustomerManagerLinkService.MoveManagerLink][google.ads.googleads.v19.services.CustomerManagerLinkService.MoveManagerLink]. - customer_id (str): - Required. The ID of the client - customer that is being moved. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - previous_customer_manager_link (str): - Required. The resource name of the previous - CustomerManagerLink. The resource name has the form: - ``customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}`` - - This corresponds to the ``previous_customer_manager_link`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - new_manager (str): - Required. The resource name of the new manager customer - that the client wants to move to. Customer resource - names have the format: "customers/{customer_id}" - - This corresponds to the ``new_manager`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MoveManagerLinkResponse: - Response message for a - CustomerManagerLink moveManagerLink. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [ - customer_id, - previous_customer_manager_link, - new_manager, - ] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_manager_link_service.MoveManagerLinkRequest - ): - request = customer_manager_link_service.MoveManagerLinkRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if previous_customer_manager_link is not None: - request.previous_customer_manager_link = ( - previous_customer_manager_link - ) - if new_manager is not None: - request.new_manager = new_manager - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.move_manager_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerManagerLinkServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerManagerLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_manager_link_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_manager_link_service/transports/base.py deleted file mode 100644 index b3f3e3869..000000000 --- a/google/ads/googleads/v19/services/services/customer_manager_link_service/transports/base.py +++ /dev/null @@ -1,193 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - customer_manager_link_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerManagerLinkServiceTransport(abc.ABC): - """Abstract transport class for CustomerManagerLinkService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer_manager_link: gapic_v1.method.wrap_method( - self.mutate_customer_manager_link, - default_timeout=None, - client_info=client_info, - ), - self.move_manager_link: gapic_v1.method.wrap_method( - self.move_manager_link, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer_manager_link( - self, - ) -> Callable[ - [customer_manager_link_service.MutateCustomerManagerLinkRequest], - Union[ - customer_manager_link_service.MutateCustomerManagerLinkResponse, - Awaitable[ - customer_manager_link_service.MutateCustomerManagerLinkResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def move_manager_link( - self, - ) -> Callable[ - [customer_manager_link_service.MoveManagerLinkRequest], - Union[ - customer_manager_link_service.MoveManagerLinkResponse, - Awaitable[customer_manager_link_service.MoveManagerLinkResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerManagerLinkServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_manager_link_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_manager_link_service/transports/grpc.py deleted file mode 100644 index 727b828a6..000000000 --- a/google/ads/googleads/v19/services/services/customer_manager_link_service/transports/grpc.py +++ /dev/null @@ -1,430 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - customer_manager_link_service, -) -from .base import CustomerManagerLinkServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerManagerLinkService", - "rpcName": str(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.ads.googleads.v19.services.CustomerManagerLinkService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerManagerLinkServiceGrpcTransport( - CustomerManagerLinkServiceTransport -): - """gRPC backend transport for CustomerManagerLinkService. - - Service to manage customer-manager links. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer_manager_link( - self, - ) -> Callable[ - [customer_manager_link_service.MutateCustomerManagerLinkRequest], - customer_manager_link_service.MutateCustomerManagerLinkResponse, - ]: - r"""Return a callable for the mutate customer manager link method over gRPC. - - Updates customer manager links. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerManagerLinkRequest], - ~.MutateCustomerManagerLinkResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_manager_link" not in self._stubs: - self._stubs["mutate_customer_manager_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerManagerLinkService/MutateCustomerManagerLink", - request_serializer=customer_manager_link_service.MutateCustomerManagerLinkRequest.serialize, - response_deserializer=customer_manager_link_service.MutateCustomerManagerLinkResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_manager_link"] - - @property - def move_manager_link( - self, - ) -> Callable[ - [customer_manager_link_service.MoveManagerLinkRequest], - customer_manager_link_service.MoveManagerLinkResponse, - ]: - r"""Return a callable for the move manager link method over gRPC. - - Moves a client customer to a new manager customer. This - simplifies the complex request that requires two operations to - move a client customer to a new manager, for example: - - 1. Update operation with Status INACTIVE (previous manager) and, - 2. Update operation with Status ACTIVE (new manager). - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MoveManagerLinkRequest], - ~.MoveManagerLinkResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "move_manager_link" not in self._stubs: - self._stubs["move_manager_link"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerManagerLinkService/MoveManagerLink", - request_serializer=customer_manager_link_service.MoveManagerLinkRequest.serialize, - response_deserializer=customer_manager_link_service.MoveManagerLinkResponse.deserialize, - ) - return self._stubs["move_manager_link"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerManagerLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_manager_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_manager_link_service/transports/grpc_asyncio.py deleted file mode 100644 index 3534888b4..000000000 --- a/google/ads/googleads/v19/services/services/customer_manager_link_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,458 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_manager_link_service, -) -from .base import CustomerManagerLinkServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerManagerLinkService", - "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.ads.googleads.v19.services.CustomerManagerLinkService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerManagerLinkServiceGrpcAsyncIOTransport( - CustomerManagerLinkServiceTransport -): - """gRPC AsyncIO backend transport for CustomerManagerLinkService. - - Service to manage customer-manager links. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer_manager_link( - self, - ) -> Callable[ - [customer_manager_link_service.MutateCustomerManagerLinkRequest], - Awaitable[ - customer_manager_link_service.MutateCustomerManagerLinkResponse - ], - ]: - r"""Return a callable for the mutate customer manager link method over gRPC. - - Updates customer manager links. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerManagerLinkRequest], - Awaitable[~.MutateCustomerManagerLinkResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_manager_link" not in self._stubs: - self._stubs["mutate_customer_manager_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerManagerLinkService/MutateCustomerManagerLink", - request_serializer=customer_manager_link_service.MutateCustomerManagerLinkRequest.serialize, - response_deserializer=customer_manager_link_service.MutateCustomerManagerLinkResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_manager_link"] - - @property - def move_manager_link( - self, - ) -> Callable[ - [customer_manager_link_service.MoveManagerLinkRequest], - Awaitable[customer_manager_link_service.MoveManagerLinkResponse], - ]: - r"""Return a callable for the move manager link method over gRPC. - - Moves a client customer to a new manager customer. This - simplifies the complex request that requires two operations to - move a client customer to a new manager, for example: - - 1. Update operation with Status INACTIVE (previous manager) and, - 2. Update operation with Status ACTIVE (new manager). - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MoveManagerLinkRequest], - Awaitable[~.MoveManagerLinkResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "move_manager_link" not in self._stubs: - self._stubs["move_manager_link"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerManagerLinkService/MoveManagerLink", - request_serializer=customer_manager_link_service.MoveManagerLinkRequest.serialize, - response_deserializer=customer_manager_link_service.MoveManagerLinkResponse.deserialize, - ) - return self._stubs["move_manager_link"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer_manager_link: self._wrap_method( - self.mutate_customer_manager_link, - default_timeout=None, - client_info=client_info, - ), - self.move_manager_link: self._wrap_method( - self.move_manager_link, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerManagerLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/async_client.py b/google/ads/googleads/v19/services/services/customer_negative_criterion_service/async_client.py deleted file mode 100644 index 8b1657ae6..000000000 --- a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/async_client.py +++ /dev/null @@ -1,448 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_negative_criterion_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CustomerNegativeCriterionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomerNegativeCriterionServiceClient - -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 CustomerNegativeCriterionServiceAsyncClient: - """Service to manage customer negative criteria.""" - - _client: CustomerNegativeCriterionServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomerNegativeCriterionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CustomerNegativeCriterionServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerNegativeCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomerNegativeCriterionServiceClient._DEFAULT_UNIVERSE - - customer_negative_criterion_path = staticmethod( - CustomerNegativeCriterionServiceClient.customer_negative_criterion_path - ) - parse_customer_negative_criterion_path = staticmethod( - CustomerNegativeCriterionServiceClient.parse_customer_negative_criterion_path - ) - mobile_app_category_constant_path = staticmethod( - CustomerNegativeCriterionServiceClient.mobile_app_category_constant_path - ) - parse_mobile_app_category_constant_path = staticmethod( - CustomerNegativeCriterionServiceClient.parse_mobile_app_category_constant_path - ) - common_billing_account_path = staticmethod( - CustomerNegativeCriterionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerNegativeCriterionServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerNegativeCriterionServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerNegativeCriterionServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerNegativeCriterionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerNegativeCriterionServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerNegativeCriterionServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerNegativeCriterionServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerNegativeCriterionServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerNegativeCriterionServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerNegativeCriterionServiceAsyncClient: The constructed client. - """ - return CustomerNegativeCriterionServiceClient.from_service_account_info.__func__(CustomerNegativeCriterionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerNegativeCriterionServiceAsyncClient: The constructed client. - """ - return CustomerNegativeCriterionServiceClient.from_service_account_file.__func__(CustomerNegativeCriterionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerNegativeCriterionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerNegativeCriterionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerNegativeCriterionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - CustomerNegativeCriterionServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerNegativeCriterionServiceTransport, - Callable[..., CustomerNegativeCriterionServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer negative criterion service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerNegativeCriterionServiceTransport,Callable[..., CustomerNegativeCriterionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerNegativeCriterionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerNegativeCriterionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerNegativeCriterionServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerNegativeCriterionService", - "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.ads.googleads.v19.services.CustomerNegativeCriterionService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer_negative_criteria( - self, - request: Optional[ - Union[ - customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customer_negative_criterion_service.CustomerNegativeCriterionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse - ): - r"""Creates or removes criteria. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerNegativeCriteriaRequest, dict]]): - The request object. Request message for - [CustomerNegativeCriterionService.MutateCustomerNegativeCriteria][google.ads.googleads.v19.services.CustomerNegativeCriterionService.MutateCustomerNegativeCriteria]. - customer_id (:class:`str`): - Required. The ID of the customer - whose criteria are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CustomerNegativeCriterionOperation]`): - Required. The list of operations to - perform on individual criteria. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerNegativeCriteriaResponse: - Response message for customer - negative criterion mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest, - ): - request = customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer_negative_criteria - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomerNegativeCriterionServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerNegativeCriterionServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/client.py b/google/ads/googleads/v19/services/services/customer_negative_criterion_service/client.py deleted file mode 100644 index 73be0edaf..000000000 --- a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/client.py +++ /dev/null @@ -1,925 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - customer_negative_criterion_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CustomerNegativeCriterionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CustomerNegativeCriterionServiceGrpcTransport -from .transports.grpc_asyncio import ( - CustomerNegativeCriterionServiceGrpcAsyncIOTransport, -) - - -class CustomerNegativeCriterionServiceClientMeta(type): - """Metaclass for the CustomerNegativeCriterionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerNegativeCriterionServiceTransport]] - _transport_registry["grpc"] = CustomerNegativeCriterionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomerNegativeCriterionServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerNegativeCriterionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerNegativeCriterionServiceClient( - metaclass=CustomerNegativeCriterionServiceClientMeta -): - """Service to manage customer negative criteria.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerNegativeCriterionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerNegativeCriterionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerNegativeCriterionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerNegativeCriterionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_negative_criterion_path( - customer_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified customer_negative_criterion string.""" - return "customers/{customer_id}/customerNegativeCriteria/{criterion_id}".format( - customer_id=customer_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_customer_negative_criterion_path(path: str) -> Dict[str, str]: - """Parses a customer_negative_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerNegativeCriteria/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def mobile_app_category_constant_path( - mobile_app_category_id: str, - ) -> str: - """Returns a fully-qualified mobile_app_category_constant string.""" - return "mobileAppCategoryConstants/{mobile_app_category_id}".format( - mobile_app_category_id=mobile_app_category_id, - ) - - @staticmethod - def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: - """Parses a mobile_app_category_constant path into its component segments.""" - m = re.match( - r"^mobileAppCategoryConstants/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CustomerNegativeCriterionServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - CustomerNegativeCriterionServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = CustomerNegativeCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - CustomerNegativeCriterionServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerNegativeCriterionServiceTransport, - Callable[..., CustomerNegativeCriterionServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer negative criterion service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerNegativeCriterionServiceTransport,Callable[..., CustomerNegativeCriterionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerNegativeCriterionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomerNegativeCriterionServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomerNegativeCriterionServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomerNegativeCriterionServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerNegativeCriterionServiceTransport - ) - if transport_provided: - # transport is a CustomerNegativeCriterionServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CustomerNegativeCriterionServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerNegativeCriterionServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerNegativeCriterionServiceTransport], - Callable[..., CustomerNegativeCriterionServiceTransport], - ] = ( - CustomerNegativeCriterionServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomerNegativeCriterionServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerNegativeCriterionServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerNegativeCriterionService", - "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.ads.googleads.v19.services.CustomerNegativeCriterionService", - "credentialsType": None, - } - ), - ) - - def mutate_customer_negative_criteria( - self, - request: Optional[ - Union[ - customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customer_negative_criterion_service.CustomerNegativeCriterionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse - ): - r"""Creates or removes criteria. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerNegativeCriteriaRequest, dict]): - The request object. Request message for - [CustomerNegativeCriterionService.MutateCustomerNegativeCriteria][google.ads.googleads.v19.services.CustomerNegativeCriterionService.MutateCustomerNegativeCriteria]. - customer_id (str): - Required. The ID of the customer - whose criteria are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerNegativeCriterionOperation]): - Required. The list of operations to - perform on individual criteria. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerNegativeCriteriaResponse: - Response message for customer - negative criterion mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest, - ): - request = customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customer_negative_criteria - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerNegativeCriterionServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerNegativeCriterionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/base.py deleted file mode 100644 index 6366314d2..000000000 --- a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - customer_negative_criterion_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerNegativeCriterionServiceTransport(abc.ABC): - """Abstract transport class for CustomerNegativeCriterionService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer_negative_criteria: gapic_v1.method.wrap_method( - self.mutate_customer_negative_criteria, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer_negative_criteria( - self, - ) -> Callable[ - [ - customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest - ], - Union[ - customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse, - Awaitable[ - customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerNegativeCriterionServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/grpc.py deleted file mode 100644 index ffb116587..000000000 --- a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/grpc.py +++ /dev/null @@ -1,394 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - customer_negative_criterion_service, -) -from .base import CustomerNegativeCriterionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerNegativeCriterionService", - "rpcName": str(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.ads.googleads.v19.services.CustomerNegativeCriterionService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerNegativeCriterionServiceGrpcTransport( - CustomerNegativeCriterionServiceTransport -): - """gRPC backend transport for CustomerNegativeCriterionService. - - Service to manage customer negative criteria. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer_negative_criteria( - self, - ) -> Callable[ - [ - customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest - ], - customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse, - ]: - r"""Return a callable for the mutate customer negative - criteria method over gRPC. - - Creates or removes criteria. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerNegativeCriteriaRequest], - ~.MutateCustomerNegativeCriteriaResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_negative_criteria" not in self._stubs: - self._stubs["mutate_customer_negative_criteria"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerNegativeCriterionService/MutateCustomerNegativeCriteria", - request_serializer=customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest.serialize, - response_deserializer=customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_negative_criteria"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerNegativeCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/grpc_asyncio.py deleted file mode 100644 index 4d7b38570..000000000 --- a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,417 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_negative_criterion_service, -) -from .base import CustomerNegativeCriterionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerNegativeCriterionService", - "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.ads.googleads.v19.services.CustomerNegativeCriterionService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerNegativeCriterionServiceGrpcAsyncIOTransport( - CustomerNegativeCriterionServiceTransport -): - """gRPC AsyncIO backend transport for CustomerNegativeCriterionService. - - Service to manage customer negative criteria. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer_negative_criteria( - self, - ) -> Callable[ - [ - customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest - ], - Awaitable[ - customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse - ], - ]: - r"""Return a callable for the mutate customer negative - criteria method over gRPC. - - Creates or removes criteria. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerNegativeCriteriaRequest], - Awaitable[~.MutateCustomerNegativeCriteriaResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_negative_criteria" not in self._stubs: - self._stubs["mutate_customer_negative_criteria"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerNegativeCriterionService/MutateCustomerNegativeCriteria", - request_serializer=customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest.serialize, - response_deserializer=customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_negative_criteria"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer_negative_criteria: self._wrap_method( - self.mutate_customer_negative_criteria, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerNegativeCriterionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_service/async_client.py b/google/ads/googleads/v19/services/services/customer_service/async_client.py deleted file mode 100644 index f4a52e632..000000000 --- a/google/ads/googleads/v19/services/services/customer_service/async_client.py +++ /dev/null @@ -1,590 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.resources.types import customer -from google.ads.googleads.v19.services.types import customer_service -from .transports.base import CustomerServiceTransport, DEFAULT_CLIENT_INFO -from .client import CustomerServiceClient - -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 CustomerServiceAsyncClient: - """Service to manage customers.""" - - _client: CustomerServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomerServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = CustomerServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomerServiceClient._DEFAULT_UNIVERSE - - conversion_action_path = staticmethod( - CustomerServiceClient.conversion_action_path - ) - parse_conversion_action_path = staticmethod( - CustomerServiceClient.parse_conversion_action_path - ) - customer_path = staticmethod(CustomerServiceClient.customer_path) - parse_customer_path = staticmethod( - CustomerServiceClient.parse_customer_path - ) - common_billing_account_path = staticmethod( - CustomerServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(CustomerServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - CustomerServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerServiceAsyncClient: The constructed client. - """ - return CustomerServiceClient.from_service_account_info.__func__(CustomerServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerServiceAsyncClient: The constructed client. - """ - return CustomerServiceClient.from_service_account_file.__func__(CustomerServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomerServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerServiceTransport, - Callable[..., CustomerServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerServiceTransport,Callable[..., CustomerServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerService", - "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.ads.googleads.v19.services.CustomerService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer( - self, - request: Optional[ - Union[customer_service.MutateCustomerRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[customer_service.CustomerOperation] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_service.MutateCustomerResponse: - r"""Updates a customer. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RequestError <>`__ `UrlFieldError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerRequest, dict]]): - The request object. Request message for - [CustomerService.MutateCustomer][google.ads.googleads.v19.services.CustomerService.MutateCustomer]. - customer_id (:class:`str`): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (:class:`google.ads.googleads.v19.services.types.CustomerOperation`): - Required. The operation to perform on - the customer - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerResponse: - Response message for customer mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, customer_service.MutateCustomerRequest): - request = customer_service.MutateCustomerRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_accessible_customers( - self, - request: Optional[ - Union[customer_service.ListAccessibleCustomersRequest, dict] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_service.ListAccessibleCustomersResponse: - r"""Returns resource names of customers directly accessible by the - user authenticating the call. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ListAccessibleCustomersRequest, dict]]): - The request object. Request message for - [CustomerService.ListAccessibleCustomers][google.ads.googleads.v19.services.CustomerService.ListAccessibleCustomers]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListAccessibleCustomersResponse: - Response message for - [CustomerService.ListAccessibleCustomers][google.ads.googleads.v19.services.CustomerService.ListAccessibleCustomers]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_service.ListAccessibleCustomersRequest - ): - request = customer_service.ListAccessibleCustomersRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_accessible_customers - ] - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def create_customer_client( - self, - request: Optional[ - Union[customer_service.CreateCustomerClientRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - customer_client: Optional[customer.Customer] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_service.CreateCustomerClientResponse: - r"""Creates a new client under manager. The new client customer is - returned. - - List of thrown errors: `AccessInvitationError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CurrencyCodeError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `QuotaError <>`__ `RequestError <>`__ - `StringLengthError <>`__ `TimeZoneError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.CreateCustomerClientRequest, dict]]): - The request object. Request message for - [CustomerService.CreateCustomerClient][google.ads.googleads.v19.services.CustomerService.CreateCustomerClient]. - customer_id (:class:`str`): - Required. The ID of the Manager under - whom client customer is being created. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - customer_client (:class:`google.ads.googleads.v19.resources.types.Customer`): - Required. The new client customer to - create. The resource name on this - customer will be ignored. - - This corresponds to the ``customer_client`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateCustomerClientResponse: - Response message for - CreateCustomerClient mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, customer_client] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_service.CreateCustomerClientRequest - ): - request = customer_service.CreateCustomerClientRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if customer_client is not None: - request.customer_client = customer_client - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.create_customer_client - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomerServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_service/client.py b/google/ads/googleads/v19/services/services/customer_service/client.py deleted file mode 100644 index 3ddf0f018..000000000 --- a/google/ads/googleads/v19/services/services/customer_service/client.py +++ /dev/null @@ -1,1038 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.resources.types import customer -from google.ads.googleads.v19.services.types import customer_service -from .transports.base import CustomerServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import CustomerServiceGrpcTransport -from .transports.grpc_asyncio import CustomerServiceGrpcAsyncIOTransport - - -class CustomerServiceClientMeta(type): - """Metaclass for the CustomerService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerServiceTransport]] - _transport_registry["grpc"] = CustomerServiceGrpcTransport - _transport_registry["grpc_asyncio"] = CustomerServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerServiceClient(metaclass=CustomerServiceClientMeta): - """Service to manage customers.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def conversion_action_path( - customer_id: str, - conversion_action_id: str, - ) -> str: - """Returns a fully-qualified conversion_action string.""" - return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( - customer_id=customer_id, - conversion_action_id=conversion_action_id, - ) - - @staticmethod - def parse_conversion_action_path(path: str) -> Dict[str, str]: - """Parses a conversion_action path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionActions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = CustomerServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CustomerServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - CustomerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomerServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerServiceTransport, - Callable[..., CustomerServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerServiceTransport,Callable[..., CustomerServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomerServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomerServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = CustomerServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, CustomerServiceTransport) - if transport_provided: - # transport is a CustomerServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(CustomerServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerServiceTransport], - Callable[..., CustomerServiceTransport], - ] = ( - CustomerServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., CustomerServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerService", - "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.ads.googleads.v19.services.CustomerService", - "credentialsType": None, - } - ), - ) - - def mutate_customer( - self, - request: Optional[ - Union[customer_service.MutateCustomerRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[customer_service.CustomerOperation] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_service.MutateCustomerResponse: - r"""Updates a customer. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RequestError <>`__ `UrlFieldError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerRequest, dict]): - The request object. Request message for - [CustomerService.MutateCustomer][google.ads.googleads.v19.services.CustomerService.MutateCustomer]. - customer_id (str): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (google.ads.googleads.v19.services.types.CustomerOperation): - Required. The operation to perform on - the customer - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerResponse: - Response message for customer mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, customer_service.MutateCustomerRequest): - request = customer_service.MutateCustomerRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.mutate_customer] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_accessible_customers( - self, - request: Optional[ - Union[customer_service.ListAccessibleCustomersRequest, dict] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_service.ListAccessibleCustomersResponse: - r"""Returns resource names of customers directly accessible by the - user authenticating the call. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ListAccessibleCustomersRequest, dict]): - The request object. Request message for - [CustomerService.ListAccessibleCustomers][google.ads.googleads.v19.services.CustomerService.ListAccessibleCustomers]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListAccessibleCustomersResponse: - Response message for - [CustomerService.ListAccessibleCustomers][google.ads.googleads.v19.services.CustomerService.ListAccessibleCustomers]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_service.ListAccessibleCustomersRequest - ): - request = customer_service.ListAccessibleCustomersRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.list_accessible_customers - ] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def create_customer_client( - self, - request: Optional[ - Union[customer_service.CreateCustomerClientRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - customer_client: Optional[customer.Customer] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_service.CreateCustomerClientResponse: - r"""Creates a new client under manager. The new client customer is - returned. - - List of thrown errors: `AccessInvitationError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CurrencyCodeError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `QuotaError <>`__ `RequestError <>`__ - `StringLengthError <>`__ `TimeZoneError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.CreateCustomerClientRequest, dict]): - The request object. Request message for - [CustomerService.CreateCustomerClient][google.ads.googleads.v19.services.CustomerService.CreateCustomerClient]. - customer_id (str): - Required. The ID of the Manager under - whom client customer is being created. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - customer_client (google.ads.googleads.v19.resources.types.Customer): - Required. The new client customer to - create. The resource name on this - customer will be ignored. - - This corresponds to the ``customer_client`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateCustomerClientResponse: - Response message for - CreateCustomerClient mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, customer_client] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, customer_service.CreateCustomerClientRequest - ): - request = customer_service.CreateCustomerClientRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if customer_client is not None: - request.customer_client = customer_client - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.create_customer_client - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_service/transports/base.py deleted file mode 100644 index ce694ffc3..000000000 --- a/google/ads/googleads/v19/services/services/customer_service/transports/base.py +++ /dev/null @@ -1,206 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import customer_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerServiceTransport(abc.ABC): - """Abstract transport class for CustomerService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer: gapic_v1.method.wrap_method( - self.mutate_customer, - default_timeout=None, - client_info=client_info, - ), - self.list_accessible_customers: gapic_v1.method.wrap_method( - self.list_accessible_customers, - default_timeout=None, - client_info=client_info, - ), - self.create_customer_client: gapic_v1.method.wrap_method( - self.create_customer_client, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer( - self, - ) -> Callable[ - [customer_service.MutateCustomerRequest], - Union[ - customer_service.MutateCustomerResponse, - Awaitable[customer_service.MutateCustomerResponse], - ], - ]: - raise NotImplementedError() - - @property - def list_accessible_customers( - self, - ) -> Callable[ - [customer_service.ListAccessibleCustomersRequest], - Union[ - customer_service.ListAccessibleCustomersResponse, - Awaitable[customer_service.ListAccessibleCustomersResponse], - ], - ]: - raise NotImplementedError() - - @property - def create_customer_client( - self, - ) -> Callable[ - [customer_service.CreateCustomerClientRequest], - Union[ - customer_service.CreateCustomerClientResponse, - Awaitable[customer_service.CreateCustomerClientResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_service/transports/grpc.py deleted file mode 100644 index b1640f46b..000000000 --- a/google/ads/googleads/v19/services/services/customer_service/transports/grpc.py +++ /dev/null @@ -1,458 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import customer_service -from .base import CustomerServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerService", - "rpcName": str(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.ads.googleads.v19.services.CustomerService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerServiceGrpcTransport(CustomerServiceTransport): - """gRPC backend transport for CustomerService. - - Service to manage customers. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer( - self, - ) -> Callable[ - [customer_service.MutateCustomerRequest], - customer_service.MutateCustomerResponse, - ]: - r"""Return a callable for the mutate customer method over gRPC. - - Updates a customer. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RequestError <>`__ `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateCustomerRequest], - ~.MutateCustomerResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer" not in self._stubs: - self._stubs["mutate_customer"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerService/MutateCustomer", - request_serializer=customer_service.MutateCustomerRequest.serialize, - response_deserializer=customer_service.MutateCustomerResponse.deserialize, - ) - return self._stubs["mutate_customer"] - - @property - def list_accessible_customers( - self, - ) -> Callable[ - [customer_service.ListAccessibleCustomersRequest], - customer_service.ListAccessibleCustomersResponse, - ]: - r"""Return a callable for the list accessible customers method over gRPC. - - Returns resource names of customers directly accessible by the - user authenticating the call. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListAccessibleCustomersRequest], - ~.ListAccessibleCustomersResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_accessible_customers" not in self._stubs: - self._stubs["list_accessible_customers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerService/ListAccessibleCustomers", - request_serializer=customer_service.ListAccessibleCustomersRequest.serialize, - response_deserializer=customer_service.ListAccessibleCustomersResponse.deserialize, - ) - ) - return self._stubs["list_accessible_customers"] - - @property - def create_customer_client( - self, - ) -> Callable[ - [customer_service.CreateCustomerClientRequest], - customer_service.CreateCustomerClientResponse, - ]: - r"""Return a callable for the create customer client method over gRPC. - - Creates a new client under manager. The new client customer is - returned. - - List of thrown errors: `AccessInvitationError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CurrencyCodeError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `QuotaError <>`__ `RequestError <>`__ - `StringLengthError <>`__ `TimeZoneError <>`__ - - Returns: - Callable[[~.CreateCustomerClientRequest], - ~.CreateCustomerClientResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_customer_client" not in self._stubs: - self._stubs["create_customer_client"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerService/CreateCustomerClient", - request_serializer=customer_service.CreateCustomerClientRequest.serialize, - response_deserializer=customer_service.CreateCustomerClientResponse.deserialize, - ) - ) - return self._stubs["create_customer_client"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_service/transports/grpc_asyncio.py deleted file mode 100644 index a49652eb0..000000000 --- a/google/ads/googleads/v19/services/services/customer_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,489 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import customer_service -from .base import CustomerServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerService", - "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.ads.googleads.v19.services.CustomerService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerServiceGrpcAsyncIOTransport(CustomerServiceTransport): - """gRPC AsyncIO backend transport for CustomerService. - - Service to manage customers. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer( - self, - ) -> Callable[ - [customer_service.MutateCustomerRequest], - Awaitable[customer_service.MutateCustomerResponse], - ]: - r"""Return a callable for the mutate customer method over gRPC. - - Updates a customer. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RequestError <>`__ `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateCustomerRequest], - Awaitable[~.MutateCustomerResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer" not in self._stubs: - self._stubs["mutate_customer"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerService/MutateCustomer", - request_serializer=customer_service.MutateCustomerRequest.serialize, - response_deserializer=customer_service.MutateCustomerResponse.deserialize, - ) - return self._stubs["mutate_customer"] - - @property - def list_accessible_customers( - self, - ) -> Callable[ - [customer_service.ListAccessibleCustomersRequest], - Awaitable[customer_service.ListAccessibleCustomersResponse], - ]: - r"""Return a callable for the list accessible customers method over gRPC. - - Returns resource names of customers directly accessible by the - user authenticating the call. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListAccessibleCustomersRequest], - Awaitable[~.ListAccessibleCustomersResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_accessible_customers" not in self._stubs: - self._stubs["list_accessible_customers"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerService/ListAccessibleCustomers", - request_serializer=customer_service.ListAccessibleCustomersRequest.serialize, - response_deserializer=customer_service.ListAccessibleCustomersResponse.deserialize, - ) - ) - return self._stubs["list_accessible_customers"] - - @property - def create_customer_client( - self, - ) -> Callable[ - [customer_service.CreateCustomerClientRequest], - Awaitable[customer_service.CreateCustomerClientResponse], - ]: - r"""Return a callable for the create customer client method over gRPC. - - Creates a new client under manager. The new client customer is - returned. - - List of thrown errors: `AccessInvitationError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `CurrencyCodeError <>`__ `HeaderError <>`__ `InternalError <>`__ - `ManagerLinkError <>`__ `QuotaError <>`__ `RequestError <>`__ - `StringLengthError <>`__ `TimeZoneError <>`__ - - Returns: - Callable[[~.CreateCustomerClientRequest], - Awaitable[~.CreateCustomerClientResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_customer_client" not in self._stubs: - self._stubs["create_customer_client"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerService/CreateCustomerClient", - request_serializer=customer_service.CreateCustomerClientRequest.serialize, - response_deserializer=customer_service.CreateCustomerClientResponse.deserialize, - ) - ) - return self._stubs["create_customer_client"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer: self._wrap_method( - self.mutate_customer, - default_timeout=None, - client_info=client_info, - ), - self.list_accessible_customers: self._wrap_method( - self.list_accessible_customers, - default_timeout=None, - client_info=client_info, - ), - self.create_customer_client: self._wrap_method( - self.create_customer_client, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/async_client.py b/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/async_client.py deleted file mode 100644 index e0a013625..000000000 --- a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/async_client.py +++ /dev/null @@ -1,412 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_sk_ad_network_conversion_value_schema_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CustomerSkAdNetworkConversionValueSchemaServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomerSkAdNetworkConversionValueSchemaServiceClient - -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 CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient: - """Service to manage CustomerSkAdNetworkConversionValueSchema.""" - - _client: CustomerSkAdNetworkConversionValueSchemaServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ( - CustomerSkAdNetworkConversionValueSchemaServiceClient.DEFAULT_ENDPOINT - ) - DEFAULT_MTLS_ENDPOINT = ( - CustomerSkAdNetworkConversionValueSchemaServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerSkAdNetworkConversionValueSchemaServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ( - CustomerSkAdNetworkConversionValueSchemaServiceClient._DEFAULT_UNIVERSE - ) - - customer_sk_ad_network_conversion_value_schema_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.customer_sk_ad_network_conversion_value_schema_path - ) - parse_customer_sk_ad_network_conversion_value_schema_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_customer_sk_ad_network_conversion_value_schema_path - ) - common_billing_account_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient: The constructed client. - """ - return CustomerSkAdNetworkConversionValueSchemaServiceClient.from_service_account_info.__func__(CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient: The constructed client. - """ - return CustomerSkAdNetworkConversionValueSchemaServiceClient.from_service_account_file.__func__(CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerSkAdNetworkConversionValueSchemaServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport( - self, - ) -> CustomerSkAdNetworkConversionValueSchemaServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerSkAdNetworkConversionValueSchemaServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - CustomerSkAdNetworkConversionValueSchemaServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerSkAdNetworkConversionValueSchemaServiceTransport, - Callable[ - ..., - CustomerSkAdNetworkConversionValueSchemaServiceTransport, - ], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer sk ad network conversion value schema service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerSkAdNetworkConversionValueSchemaServiceTransport,Callable[..., CustomerSkAdNetworkConversionValueSchemaServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerSkAdNetworkConversionValueSchemaServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerSkAdNetworkConversionValueSchemaServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService", - "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.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer_sk_ad_network_conversion_value_schema( - self, - request: Optional[ - Union[ - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse - ): - r"""Creates or updates the CustomerSkAdNetworkConversionValueSchema. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `InternalError <>`__ - `MutateError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerSkAdNetworkConversionValueSchemaRequest, dict]]): - The request object. Request message for - [CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema][google.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerSkAdNetworkConversionValueSchemaResponse: - Response message for - MutateCustomerSkAdNetworkConversionValueSchema. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest, - ): - request = customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer_sk_ad_network_conversion_value_schema - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__( - self, - ) -> "CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/client.py b/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/client.py deleted file mode 100644 index ca6fb6b1c..000000000 --- a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/client.py +++ /dev/null @@ -1,875 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - customer_sk_ad_network_conversion_value_schema_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CustomerSkAdNetworkConversionValueSchemaServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ( - CustomerSkAdNetworkConversionValueSchemaServiceGrpcTransport, -) -from .transports.grpc_asyncio import ( - CustomerSkAdNetworkConversionValueSchemaServiceGrpcAsyncIOTransport, -) - - -class CustomerSkAdNetworkConversionValueSchemaServiceClientMeta(type): - """Metaclass for the CustomerSkAdNetworkConversionValueSchemaService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerSkAdNetworkConversionValueSchemaServiceTransport]] - _transport_registry["grpc"] = ( - CustomerSkAdNetworkConversionValueSchemaServiceGrpcTransport - ) - _transport_registry["grpc_asyncio"] = ( - CustomerSkAdNetworkConversionValueSchemaServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerSkAdNetworkConversionValueSchemaServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerSkAdNetworkConversionValueSchemaServiceClient( - metaclass=CustomerSkAdNetworkConversionValueSchemaServiceClientMeta -): - """Service to manage CustomerSkAdNetworkConversionValueSchema.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerSkAdNetworkConversionValueSchemaServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerSkAdNetworkConversionValueSchemaServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport( - self, - ) -> CustomerSkAdNetworkConversionValueSchemaServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerSkAdNetworkConversionValueSchemaServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_sk_ad_network_conversion_value_schema_path( - customer_id: str, - account_link_id: str, - ) -> str: - """Returns a fully-qualified customer_sk_ad_network_conversion_value_schema string.""" - return "customers/{customer_id}/customerSkAdNetworkConversionValueSchemas/{account_link_id}".format( - customer_id=customer_id, - account_link_id=account_link_id, - ) - - @staticmethod - def parse_customer_sk_ad_network_conversion_value_schema_path( - path: str, - ) -> Dict[str, str]: - """Parses a customer_sk_ad_network_conversion_value_schema path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerSkAdNetworkConversionValueSchemas/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CustomerSkAdNetworkConversionValueSchemaServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - CustomerSkAdNetworkConversionValueSchemaServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = CustomerSkAdNetworkConversionValueSchemaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - CustomerSkAdNetworkConversionValueSchemaServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerSkAdNetworkConversionValueSchemaServiceTransport, - Callable[ - ..., - CustomerSkAdNetworkConversionValueSchemaServiceTransport, - ], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer sk ad network conversion value schema service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerSkAdNetworkConversionValueSchemaServiceTransport,Callable[..., CustomerSkAdNetworkConversionValueSchemaServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerSkAdNetworkConversionValueSchemaServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ( - CustomerSkAdNetworkConversionValueSchemaServiceClient._read_environment_variables() - ) - self._client_cert_source = CustomerSkAdNetworkConversionValueSchemaServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - self._universe_domain = CustomerSkAdNetworkConversionValueSchemaServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerSkAdNetworkConversionValueSchemaServiceTransport - ) - if transport_provided: - # transport is a CustomerSkAdNetworkConversionValueSchemaServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CustomerSkAdNetworkConversionValueSchemaServiceTransport, - transport, - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerSkAdNetworkConversionValueSchemaServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerSkAdNetworkConversionValueSchemaServiceTransport], - Callable[ - ..., - CustomerSkAdNetworkConversionValueSchemaServiceTransport, - ], - ] = ( - CustomerSkAdNetworkConversionValueSchemaServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[ - ..., - CustomerSkAdNetworkConversionValueSchemaServiceTransport, - ], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService", - "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.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService", - "credentialsType": None, - } - ), - ) - - def mutate_customer_sk_ad_network_conversion_value_schema( - self, - request: Optional[ - Union[ - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse - ): - r"""Creates or updates the CustomerSkAdNetworkConversionValueSchema. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `InternalError <>`__ - `MutateError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerSkAdNetworkConversionValueSchemaRequest, dict]): - The request object. Request message for - [CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema][google.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerSkAdNetworkConversionValueSchemaResponse: - Response message for - MutateCustomerSkAdNetworkConversionValueSchema. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest, - ): - request = customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customer_sk_ad_network_conversion_value_schema - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__( - self, - ) -> "CustomerSkAdNetworkConversionValueSchemaServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerSkAdNetworkConversionValueSchemaServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/base.py deleted file mode 100644 index b5bba80e6..000000000 --- a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - customer_sk_ad_network_conversion_value_schema_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerSkAdNetworkConversionValueSchemaServiceTransport(abc.ABC): - """Abstract transport class for CustomerSkAdNetworkConversionValueSchemaService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer_sk_ad_network_conversion_value_schema: gapic_v1.method.wrap_method( - self.mutate_customer_sk_ad_network_conversion_value_schema, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer_sk_ad_network_conversion_value_schema( - self, - ) -> Callable[ - [ - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest - ], - Union[ - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse, - Awaitable[ - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerSkAdNetworkConversionValueSchemaServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc.py deleted file mode 100644 index 6da660607..000000000 --- a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc.py +++ /dev/null @@ -1,400 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - customer_sk_ad_network_conversion_value_schema_service, -) -from .base import ( - CustomerSkAdNetworkConversionValueSchemaServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService", - "rpcName": str(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.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerSkAdNetworkConversionValueSchemaServiceGrpcTransport( - CustomerSkAdNetworkConversionValueSchemaServiceTransport -): - """gRPC backend transport for CustomerSkAdNetworkConversionValueSchemaService. - - Service to manage CustomerSkAdNetworkConversionValueSchema. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer_sk_ad_network_conversion_value_schema( - self, - ) -> Callable[ - [ - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest - ], - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse, - ]: - r"""Return a callable for the mutate customer sk ad network - conversion value schema method over gRPC. - - Creates or updates the CustomerSkAdNetworkConversionValueSchema. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `InternalError <>`__ - `MutateError <>`__ - - Returns: - Callable[[~.MutateCustomerSkAdNetworkConversionValueSchemaRequest], - ~.MutateCustomerSkAdNetworkConversionValueSchemaResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if ( - "mutate_customer_sk_ad_network_conversion_value_schema" - not in self._stubs - ): - self._stubs[ - "mutate_customer_sk_ad_network_conversion_value_schema" - ] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService/MutateCustomerSkAdNetworkConversionValueSchema", - request_serializer=customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest.serialize, - response_deserializer=customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse.deserialize, - ) - return self._stubs[ - "mutate_customer_sk_ad_network_conversion_value_schema" - ] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerSkAdNetworkConversionValueSchemaServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc_asyncio.py deleted file mode 100644 index fe2e5837e..000000000 --- a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,425 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_sk_ad_network_conversion_value_schema_service, -) -from .base import ( - CustomerSkAdNetworkConversionValueSchemaServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService", - "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.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerSkAdNetworkConversionValueSchemaServiceGrpcAsyncIOTransport( - CustomerSkAdNetworkConversionValueSchemaServiceTransport -): - """gRPC AsyncIO backend transport for CustomerSkAdNetworkConversionValueSchemaService. - - Service to manage CustomerSkAdNetworkConversionValueSchema. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer_sk_ad_network_conversion_value_schema( - self, - ) -> Callable[ - [ - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest - ], - Awaitable[ - customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse - ], - ]: - r"""Return a callable for the mutate customer sk ad network - conversion value schema method over gRPC. - - Creates or updates the CustomerSkAdNetworkConversionValueSchema. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `InternalError <>`__ - `MutateError <>`__ - - Returns: - Callable[[~.MutateCustomerSkAdNetworkConversionValueSchemaRequest], - Awaitable[~.MutateCustomerSkAdNetworkConversionValueSchemaResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if ( - "mutate_customer_sk_ad_network_conversion_value_schema" - not in self._stubs - ): - self._stubs[ - "mutate_customer_sk_ad_network_conversion_value_schema" - ] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService/MutateCustomerSkAdNetworkConversionValueSchema", - request_serializer=customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest.serialize, - response_deserializer=customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse.deserialize, - ) - return self._stubs[ - "mutate_customer_sk_ad_network_conversion_value_schema" - ] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer_sk_ad_network_conversion_value_schema: self._wrap_method( - self.mutate_customer_sk_ad_network_conversion_value_schema, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ( - "CustomerSkAdNetworkConversionValueSchemaServiceGrpcAsyncIOTransport", -) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/async_client.py b/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/async_client.py deleted file mode 100644 index 9505d6c5c..000000000 --- a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/async_client.py +++ /dev/null @@ -1,447 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_user_access_invitation_service, -) -from .transports.base import ( - CustomerUserAccessInvitationServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomerUserAccessInvitationServiceClient - -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 CustomerUserAccessInvitationServiceAsyncClient: - """This service manages the access invitation extended to users - for a given customer. - """ - - _client: CustomerUserAccessInvitationServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ( - CustomerUserAccessInvitationServiceClient.DEFAULT_ENDPOINT - ) - DEFAULT_MTLS_ENDPOINT = ( - CustomerUserAccessInvitationServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerUserAccessInvitationServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ( - CustomerUserAccessInvitationServiceClient._DEFAULT_UNIVERSE - ) - - customer_user_access_invitation_path = staticmethod( - CustomerUserAccessInvitationServiceClient.customer_user_access_invitation_path - ) - parse_customer_user_access_invitation_path = staticmethod( - CustomerUserAccessInvitationServiceClient.parse_customer_user_access_invitation_path - ) - common_billing_account_path = staticmethod( - CustomerUserAccessInvitationServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerUserAccessInvitationServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerUserAccessInvitationServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerUserAccessInvitationServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerUserAccessInvitationServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerUserAccessInvitationServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerUserAccessInvitationServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerUserAccessInvitationServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerUserAccessInvitationServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerUserAccessInvitationServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerUserAccessInvitationServiceAsyncClient: The constructed client. - """ - return CustomerUserAccessInvitationServiceClient.from_service_account_info.__func__(CustomerUserAccessInvitationServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerUserAccessInvitationServiceAsyncClient: The constructed client. - """ - return CustomerUserAccessInvitationServiceClient.from_service_account_file.__func__(CustomerUserAccessInvitationServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerUserAccessInvitationServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerUserAccessInvitationServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerUserAccessInvitationServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - CustomerUserAccessInvitationServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerUserAccessInvitationServiceTransport, - Callable[..., CustomerUserAccessInvitationServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer user access invitation service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerUserAccessInvitationServiceTransport,Callable[..., CustomerUserAccessInvitationServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerUserAccessInvitationServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerUserAccessInvitationServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerUserAccessInvitationServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerUserAccessInvitationService", - "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.ads.googleads.v19.services.CustomerUserAccessInvitationService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer_user_access_invitation( - self, - request: Optional[ - Union[ - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - customer_user_access_invitation_service.CustomerUserAccessInvitationOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse - ): - r"""Creates or removes an access invitation. - - List of thrown errors: `AccessInvitationError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerUserAccessInvitationRequest, dict]]): - The request object. Request message for - [CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation][google.ads.googleads.v19.services.CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation] - customer_id (:class:`str`): - Required. The ID of the customer - whose access invitation is being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (:class:`google.ads.googleads.v19.services.types.CustomerUserAccessInvitationOperation`): - Required. The operation to perform on - the access invitation - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerUserAccessInvitationResponse: - Response message for access - invitation mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest, - ): - request = customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer_user_access_invitation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__( - self, - ) -> "CustomerUserAccessInvitationServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerUserAccessInvitationServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/client.py b/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/client.py deleted file mode 100644 index c0ddb9755..000000000 --- a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/client.py +++ /dev/null @@ -1,900 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - customer_user_access_invitation_service, -) -from .transports.base import ( - CustomerUserAccessInvitationServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CustomerUserAccessInvitationServiceGrpcTransport -from .transports.grpc_asyncio import ( - CustomerUserAccessInvitationServiceGrpcAsyncIOTransport, -) - - -class CustomerUserAccessInvitationServiceClientMeta(type): - """Metaclass for the CustomerUserAccessInvitationService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerUserAccessInvitationServiceTransport]] - _transport_registry["grpc"] = ( - CustomerUserAccessInvitationServiceGrpcTransport - ) - _transport_registry["grpc_asyncio"] = ( - CustomerUserAccessInvitationServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerUserAccessInvitationServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerUserAccessInvitationServiceClient( - metaclass=CustomerUserAccessInvitationServiceClientMeta -): - """This service manages the access invitation extended to users - for a given customer. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerUserAccessInvitationServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerUserAccessInvitationServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerUserAccessInvitationServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerUserAccessInvitationServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_user_access_invitation_path( - customer_id: str, - invitation_id: str, - ) -> str: - """Returns a fully-qualified customer_user_access_invitation string.""" - return "customers/{customer_id}/customerUserAccessInvitations/{invitation_id}".format( - customer_id=customer_id, - invitation_id=invitation_id, - ) - - @staticmethod - def parse_customer_user_access_invitation_path(path: str) -> Dict[str, str]: - """Parses a customer_user_access_invitation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerUserAccessInvitations/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CustomerUserAccessInvitationServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - CustomerUserAccessInvitationServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = CustomerUserAccessInvitationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - CustomerUserAccessInvitationServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerUserAccessInvitationServiceTransport, - Callable[..., CustomerUserAccessInvitationServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer user access invitation service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerUserAccessInvitationServiceTransport,Callable[..., CustomerUserAccessInvitationServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerUserAccessInvitationServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ( - CustomerUserAccessInvitationServiceClient._read_environment_variables() - ) - self._client_cert_source = ( - CustomerUserAccessInvitationServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomerUserAccessInvitationServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerUserAccessInvitationServiceTransport - ) - if transport_provided: - # transport is a CustomerUserAccessInvitationServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CustomerUserAccessInvitationServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerUserAccessInvitationServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerUserAccessInvitationServiceTransport], - Callable[..., CustomerUserAccessInvitationServiceTransport], - ] = ( - CustomerUserAccessInvitationServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomerUserAccessInvitationServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerUserAccessInvitationServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerUserAccessInvitationService", - "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.ads.googleads.v19.services.CustomerUserAccessInvitationService", - "credentialsType": None, - } - ), - ) - - def mutate_customer_user_access_invitation( - self, - request: Optional[ - Union[ - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - customer_user_access_invitation_service.CustomerUserAccessInvitationOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse - ): - r"""Creates or removes an access invitation. - - List of thrown errors: `AccessInvitationError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerUserAccessInvitationRequest, dict]): - The request object. Request message for - [CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation][google.ads.googleads.v19.services.CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation] - customer_id (str): - Required. The ID of the customer - whose access invitation is being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (google.ads.googleads.v19.services.types.CustomerUserAccessInvitationOperation): - Required. The operation to perform on - the access invitation - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerUserAccessInvitationResponse: - Response message for access - invitation mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest, - ): - request = customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customer_user_access_invitation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerUserAccessInvitationServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerUserAccessInvitationServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/base.py deleted file mode 100644 index 921b057d3..000000000 --- a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - customer_user_access_invitation_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerUserAccessInvitationServiceTransport(abc.ABC): - """Abstract transport class for CustomerUserAccessInvitationService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer_user_access_invitation: gapic_v1.method.wrap_method( - self.mutate_customer_user_access_invitation, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer_user_access_invitation( - self, - ) -> Callable[ - [ - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest - ], - Union[ - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse, - Awaitable[ - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerUserAccessInvitationServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/grpc.py deleted file mode 100644 index db1e2a592..000000000 --- a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/grpc.py +++ /dev/null @@ -1,397 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - customer_user_access_invitation_service, -) -from .base import ( - CustomerUserAccessInvitationServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerUserAccessInvitationService", - "rpcName": str(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.ads.googleads.v19.services.CustomerUserAccessInvitationService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerUserAccessInvitationServiceGrpcTransport( - CustomerUserAccessInvitationServiceTransport -): - """gRPC backend transport for CustomerUserAccessInvitationService. - - This service manages the access invitation extended to users - for a given customer. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer_user_access_invitation( - self, - ) -> Callable[ - [ - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest - ], - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse, - ]: - r"""Return a callable for the mutate customer user access - invitation method over gRPC. - - Creates or removes an access invitation. - - List of thrown errors: `AccessInvitationError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerUserAccessInvitationRequest], - ~.MutateCustomerUserAccessInvitationResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_user_access_invitation" not in self._stubs: - self._stubs["mutate_customer_user_access_invitation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerUserAccessInvitationService/MutateCustomerUserAccessInvitation", - request_serializer=customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest.serialize, - response_deserializer=customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_user_access_invitation"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerUserAccessInvitationServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/grpc_asyncio.py deleted file mode 100644 index cca74c596..000000000 --- a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,420 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - customer_user_access_invitation_service, -) -from .base import ( - CustomerUserAccessInvitationServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerUserAccessInvitationService", - "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.ads.googleads.v19.services.CustomerUserAccessInvitationService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerUserAccessInvitationServiceGrpcAsyncIOTransport( - CustomerUserAccessInvitationServiceTransport -): - """gRPC AsyncIO backend transport for CustomerUserAccessInvitationService. - - This service manages the access invitation extended to users - for a given customer. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer_user_access_invitation( - self, - ) -> Callable[ - [ - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest - ], - Awaitable[ - customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse - ], - ]: - r"""Return a callable for the mutate customer user access - invitation method over gRPC. - - Creates or removes an access invitation. - - List of thrown errors: `AccessInvitationError <>`__ - `AuthenticationError <>`__ `AuthorizationError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerUserAccessInvitationRequest], - Awaitable[~.MutateCustomerUserAccessInvitationResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_user_access_invitation" not in self._stubs: - self._stubs["mutate_customer_user_access_invitation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerUserAccessInvitationService/MutateCustomerUserAccessInvitation", - request_serializer=customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest.serialize, - response_deserializer=customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_user_access_invitation"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer_user_access_invitation: self._wrap_method( - self.mutate_customer_user_access_invitation, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerUserAccessInvitationServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_service/async_client.py b/google/ads/googleads/v19/services/services/customer_user_access_service/async_client.py deleted file mode 100644 index 487009ecf..000000000 --- a/google/ads/googleads/v19/services/services/customer_user_access_service/async_client.py +++ /dev/null @@ -1,437 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import customer_user_access_service -from .transports.base import ( - CustomerUserAccessServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomerUserAccessServiceClient - -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 CustomerUserAccessServiceAsyncClient: - """This service manages the permissions of a user on a given - customer. - """ - - _client: CustomerUserAccessServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomerUserAccessServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CustomerUserAccessServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomerUserAccessServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomerUserAccessServiceClient._DEFAULT_UNIVERSE - - customer_user_access_path = staticmethod( - CustomerUserAccessServiceClient.customer_user_access_path - ) - parse_customer_user_access_path = staticmethod( - CustomerUserAccessServiceClient.parse_customer_user_access_path - ) - common_billing_account_path = staticmethod( - CustomerUserAccessServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomerUserAccessServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomerUserAccessServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomerUserAccessServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomerUserAccessServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomerUserAccessServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomerUserAccessServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomerUserAccessServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomerUserAccessServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomerUserAccessServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerUserAccessServiceAsyncClient: The constructed client. - """ - return CustomerUserAccessServiceClient.from_service_account_info.__func__(CustomerUserAccessServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerUserAccessServiceAsyncClient: The constructed client. - """ - return CustomerUserAccessServiceClient.from_service_account_file.__func__(CustomerUserAccessServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomerUserAccessServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomerUserAccessServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerUserAccessServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomerUserAccessServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerUserAccessServiceTransport, - Callable[..., CustomerUserAccessServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer user access service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerUserAccessServiceTransport,Callable[..., CustomerUserAccessServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerUserAccessServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomerUserAccessServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomerUserAccessServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerUserAccessService", - "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.ads.googleads.v19.services.CustomerUserAccessService", - "credentialsType": None, - } - ), - ) - - async def mutate_customer_user_access( - self, - request: Optional[ - Union[ - customer_user_access_service.MutateCustomerUserAccessRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - customer_user_access_service.CustomerUserAccessOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_user_access_service.MutateCustomerUserAccessResponse: - r"""Updates, removes permission of a user on a given customer. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CustomerUserAccessError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomerUserAccessRequest, dict]]): - The request object. Mutate Request for - [CustomerUserAccessService.MutateCustomerUserAccess][google.ads.googleads.v19.services.CustomerUserAccessService.MutateCustomerUserAccess]. - customer_id (:class:`str`): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (:class:`google.ads.googleads.v19.services.types.CustomerUserAccessOperation`): - Required. The operation to perform on - the customer - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerUserAccessResponse: - Response message for customer user - access mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_user_access_service.MutateCustomerUserAccessRequest, - ): - request = ( - customer_user_access_service.MutateCustomerUserAccessRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customer_user_access - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomerUserAccessServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomerUserAccessServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_service/client.py b/google/ads/googleads/v19/services/services/customer_user_access_service/client.py deleted file mode 100644 index fa5c3aefd..000000000 --- a/google/ads/googleads/v19/services/services/customer_user_access_service/client.py +++ /dev/null @@ -1,887 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import customer_user_access_service -from .transports.base import ( - CustomerUserAccessServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CustomerUserAccessServiceGrpcTransport -from .transports.grpc_asyncio import ( - CustomerUserAccessServiceGrpcAsyncIOTransport, -) - - -class CustomerUserAccessServiceClientMeta(type): - """Metaclass for the CustomerUserAccessService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomerUserAccessServiceTransport]] - _transport_registry["grpc"] = CustomerUserAccessServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomerUserAccessServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomerUserAccessServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomerUserAccessServiceClient( - metaclass=CustomerUserAccessServiceClientMeta -): - """This service manages the permissions of a user on a given - customer. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerUserAccessServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomerUserAccessServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomerUserAccessServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomerUserAccessServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_user_access_path( - customer_id: str, - user_id: str, - ) -> str: - """Returns a fully-qualified customer_user_access string.""" - return "customers/{customer_id}/customerUserAccesses/{user_id}".format( - customer_id=customer_id, - user_id=user_id, - ) - - @staticmethod - def parse_customer_user_access_path(path: str) -> Dict[str, str]: - """Parses a customer_user_access path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerUserAccesses/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CustomerUserAccessServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = CustomerUserAccessServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = CustomerUserAccessServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomerUserAccessServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomerUserAccessServiceTransport, - Callable[..., CustomerUserAccessServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customer user access service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomerUserAccessServiceTransport,Callable[..., CustomerUserAccessServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomerUserAccessServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomerUserAccessServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomerUserAccessServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomerUserAccessServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomerUserAccessServiceTransport - ) - if transport_provided: - # transport is a CustomerUserAccessServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CustomerUserAccessServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomerUserAccessServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomerUserAccessServiceTransport], - Callable[..., CustomerUserAccessServiceTransport], - ] = ( - CustomerUserAccessServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomerUserAccessServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomerUserAccessServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomerUserAccessService", - "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.ads.googleads.v19.services.CustomerUserAccessService", - "credentialsType": None, - } - ), - ) - - def mutate_customer_user_access( - self, - request: Optional[ - Union[ - customer_user_access_service.MutateCustomerUserAccessRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operation: Optional[ - customer_user_access_service.CustomerUserAccessOperation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customer_user_access_service.MutateCustomerUserAccessResponse: - r"""Updates, removes permission of a user on a given customer. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CustomerUserAccessError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomerUserAccessRequest, dict]): - The request object. Mutate Request for - [CustomerUserAccessService.MutateCustomerUserAccess][google.ads.googleads.v19.services.CustomerUserAccessService.MutateCustomerUserAccess]. - customer_id (str): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operation (google.ads.googleads.v19.services.types.CustomerUserAccessOperation): - Required. The operation to perform on - the customer - - This corresponds to the ``operation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomerUserAccessResponse: - Response message for customer user - access mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customer_user_access_service.MutateCustomerUserAccessRequest, - ): - request = ( - customer_user_access_service.MutateCustomerUserAccessRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operation is not None: - request.operation = operation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customer_user_access - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomerUserAccessServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomerUserAccessServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_service/transports/base.py b/google/ads/googleads/v19/services/services/customer_user_access_service/transports/base.py deleted file mode 100644 index 9159e6d27..000000000 --- a/google/ads/googleads/v19/services/services/customer_user_access_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import customer_user_access_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomerUserAccessServiceTransport(abc.ABC): - """Abstract transport class for CustomerUserAccessService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customer_user_access: gapic_v1.method.wrap_method( - self.mutate_customer_user_access, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customer_user_access( - self, - ) -> Callable[ - [customer_user_access_service.MutateCustomerUserAccessRequest], - Union[ - customer_user_access_service.MutateCustomerUserAccessResponse, - Awaitable[ - customer_user_access_service.MutateCustomerUserAccessResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomerUserAccessServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customer_user_access_service/transports/grpc.py deleted file mode 100644 index 5b4702f9a..000000000 --- a/google/ads/googleads/v19/services/services/customer_user_access_service/transports/grpc.py +++ /dev/null @@ -1,390 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import customer_user_access_service -from .base import CustomerUserAccessServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomerUserAccessService", - "rpcName": str(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.ads.googleads.v19.services.CustomerUserAccessService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerUserAccessServiceGrpcTransport( - CustomerUserAccessServiceTransport -): - """gRPC backend transport for CustomerUserAccessService. - - This service manages the permissions of a user on a given - customer. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customer_user_access( - self, - ) -> Callable[ - [customer_user_access_service.MutateCustomerUserAccessRequest], - customer_user_access_service.MutateCustomerUserAccessResponse, - ]: - r"""Return a callable for the mutate customer user access method over gRPC. - - Updates, removes permission of a user on a given customer. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CustomerUserAccessError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerUserAccessRequest], - ~.MutateCustomerUserAccessResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_user_access" not in self._stubs: - self._stubs["mutate_customer_user_access"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerUserAccessService/MutateCustomerUserAccess", - request_serializer=customer_user_access_service.MutateCustomerUserAccessRequest.serialize, - response_deserializer=customer_user_access_service.MutateCustomerUserAccessResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_user_access"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomerUserAccessServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customer_user_access_service/transports/grpc_asyncio.py deleted file mode 100644 index bc4bab986..000000000 --- a/google/ads/googleads/v19/services/services/customer_user_access_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,413 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import customer_user_access_service -from .base import CustomerUserAccessServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomerUserAccessService", - "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.ads.googleads.v19.services.CustomerUserAccessService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomerUserAccessServiceGrpcAsyncIOTransport( - CustomerUserAccessServiceTransport -): - """gRPC AsyncIO backend transport for CustomerUserAccessService. - - This service manages the permissions of a user on a given - customer. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customer_user_access( - self, - ) -> Callable[ - [customer_user_access_service.MutateCustomerUserAccessRequest], - Awaitable[ - customer_user_access_service.MutateCustomerUserAccessResponse - ], - ]: - r"""Return a callable for the mutate customer user access method over gRPC. - - Updates, removes permission of a user on a given customer. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CustomerUserAccessError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.MutateCustomerUserAccessRequest], - Awaitable[~.MutateCustomerUserAccessResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customer_user_access" not in self._stubs: - self._stubs["mutate_customer_user_access"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomerUserAccessService/MutateCustomerUserAccess", - request_serializer=customer_user_access_service.MutateCustomerUserAccessRequest.serialize, - response_deserializer=customer_user_access_service.MutateCustomerUserAccessResponse.deserialize, - ) - ) - return self._stubs["mutate_customer_user_access"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customer_user_access: self._wrap_method( - self.mutate_customer_user_access, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomerUserAccessServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customizer_attribute_service/async_client.py b/google/ads/googleads/v19/services/services/customizer_attribute_service/async_client.py deleted file mode 100644 index 6e0fdfe08..000000000 --- a/google/ads/googleads/v19/services/services/customizer_attribute_service/async_client.py +++ /dev/null @@ -1,435 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import customizer_attribute_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CustomizerAttributeServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import CustomizerAttributeServiceClient - -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 CustomizerAttributeServiceAsyncClient: - """Service to manage customizer attribute""" - - _client: CustomizerAttributeServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = CustomizerAttributeServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - CustomizerAttributeServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - CustomizerAttributeServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = CustomizerAttributeServiceClient._DEFAULT_UNIVERSE - - customizer_attribute_path = staticmethod( - CustomizerAttributeServiceClient.customizer_attribute_path - ) - parse_customizer_attribute_path = staticmethod( - CustomizerAttributeServiceClient.parse_customizer_attribute_path - ) - common_billing_account_path = staticmethod( - CustomizerAttributeServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - CustomizerAttributeServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - CustomizerAttributeServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - CustomizerAttributeServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - CustomizerAttributeServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - CustomizerAttributeServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - CustomizerAttributeServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - CustomizerAttributeServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - CustomizerAttributeServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - CustomizerAttributeServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomizerAttributeServiceAsyncClient: The constructed client. - """ - return CustomizerAttributeServiceClient.from_service_account_info.__func__(CustomizerAttributeServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomizerAttributeServiceAsyncClient: The constructed client. - """ - return CustomizerAttributeServiceClient.from_service_account_file.__func__(CustomizerAttributeServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return CustomizerAttributeServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> CustomizerAttributeServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomizerAttributeServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = CustomizerAttributeServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomizerAttributeServiceTransport, - Callable[..., CustomizerAttributeServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customizer attribute service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomizerAttributeServiceTransport,Callable[..., CustomizerAttributeServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomizerAttributeServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = CustomizerAttributeServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.CustomizerAttributeServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomizerAttributeService", - "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.ads.googleads.v19.services.CustomizerAttributeService", - "credentialsType": None, - } - ), - ) - - async def mutate_customizer_attributes( - self, - request: Optional[ - Union[ - customizer_attribute_service.MutateCustomizerAttributesRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customizer_attribute_service.CustomizerAttributeOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customizer_attribute_service.MutateCustomizerAttributesResponse: - r"""Creates, updates or removes customizer attributes. - Operation statuses are returned. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateCustomizerAttributesRequest, dict]]): - The request object. Request message for - [CustomizerAttributeService.MutateCustomizerAttributes][google.ads.googleads.v19.services.CustomizerAttributeService.MutateCustomizerAttributes]. - customer_id (:class:`str`): - Required. The ID of the customer - whose customizer attributes are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.CustomizerAttributeOperation]`): - Required. The list of operations to - perform on individual customizer - attributes. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomizerAttributesResponse: - Response message for a customizer - attribute mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customizer_attribute_service.MutateCustomizerAttributesRequest, - ): - request = ( - customizer_attribute_service.MutateCustomizerAttributesRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_customizer_attributes - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "CustomizerAttributeServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("CustomizerAttributeServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/customizer_attribute_service/client.py b/google/ads/googleads/v19/services/services/customizer_attribute_service/client.py deleted file mode 100644 index 0b2b14cb5..000000000 --- a/google/ads/googleads/v19/services/services/customizer_attribute_service/client.py +++ /dev/null @@ -1,898 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import customizer_attribute_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - CustomizerAttributeServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import CustomizerAttributeServiceGrpcTransport -from .transports.grpc_asyncio import ( - CustomizerAttributeServiceGrpcAsyncIOTransport, -) - - -class CustomizerAttributeServiceClientMeta(type): - """Metaclass for the CustomizerAttributeService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[CustomizerAttributeServiceTransport]] - _transport_registry["grpc"] = CustomizerAttributeServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - CustomizerAttributeServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[CustomizerAttributeServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class CustomizerAttributeServiceClient( - metaclass=CustomizerAttributeServiceClientMeta -): - """Service to manage customizer attribute""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomizerAttributeServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - CustomizerAttributeServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> CustomizerAttributeServiceTransport: - """Returns the transport used by the client instance. - - Returns: - CustomizerAttributeServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customizer_attribute_path( - customer_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified customizer_attribute string.""" - return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( - customer_id=customer_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_customizer_attribute_path(path: str) -> Dict[str, str]: - """Parses a customizer_attribute path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - CustomizerAttributeServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - CustomizerAttributeServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = CustomizerAttributeServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = CustomizerAttributeServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - CustomizerAttributeServiceTransport, - Callable[..., CustomizerAttributeServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the customizer attribute service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,CustomizerAttributeServiceTransport,Callable[..., CustomizerAttributeServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the CustomizerAttributeServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = CustomizerAttributeServiceClient._read_environment_variables() - self._client_cert_source = ( - CustomizerAttributeServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - CustomizerAttributeServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, CustomizerAttributeServiceTransport - ) - if transport_provided: - # transport is a CustomizerAttributeServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - CustomizerAttributeServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or CustomizerAttributeServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[CustomizerAttributeServiceTransport], - Callable[..., CustomizerAttributeServiceTransport], - ] = ( - CustomizerAttributeServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., CustomizerAttributeServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.CustomizerAttributeServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.CustomizerAttributeService", - "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.ads.googleads.v19.services.CustomizerAttributeService", - "credentialsType": None, - } - ), - ) - - def mutate_customizer_attributes( - self, - request: Optional[ - Union[ - customizer_attribute_service.MutateCustomizerAttributesRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - customizer_attribute_service.CustomizerAttributeOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> customizer_attribute_service.MutateCustomizerAttributesResponse: - r"""Creates, updates or removes customizer attributes. - Operation statuses are returned. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateCustomizerAttributesRequest, dict]): - The request object. Request message for - [CustomizerAttributeService.MutateCustomizerAttributes][google.ads.googleads.v19.services.CustomizerAttributeService.MutateCustomizerAttributes]. - customer_id (str): - Required. The ID of the customer - whose customizer attributes are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomizerAttributeOperation]): - Required. The list of operations to - perform on individual customizer - attributes. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateCustomizerAttributesResponse: - Response message for a customizer - attribute mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - customizer_attribute_service.MutateCustomizerAttributesRequest, - ): - request = ( - customizer_attribute_service.MutateCustomizerAttributesRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_customizer_attributes - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "CustomizerAttributeServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("CustomizerAttributeServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customizer_attribute_service/transports/base.py b/google/ads/googleads/v19/services/services/customizer_attribute_service/transports/base.py deleted file mode 100644 index 4f96f62c6..000000000 --- a/google/ads/googleads/v19/services/services/customizer_attribute_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import customizer_attribute_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class CustomizerAttributeServiceTransport(abc.ABC): - """Abstract transport class for CustomizerAttributeService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_customizer_attributes: gapic_v1.method.wrap_method( - self.mutate_customizer_attributes, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_customizer_attributes( - self, - ) -> Callable[ - [customizer_attribute_service.MutateCustomizerAttributesRequest], - Union[ - customizer_attribute_service.MutateCustomizerAttributesResponse, - Awaitable[ - customizer_attribute_service.MutateCustomizerAttributesResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("CustomizerAttributeServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/customizer_attribute_service/transports/grpc.py b/google/ads/googleads/v19/services/services/customizer_attribute_service/transports/grpc.py deleted file mode 100644 index f233e4b0e..000000000 --- a/google/ads/googleads/v19/services/services/customizer_attribute_service/transports/grpc.py +++ /dev/null @@ -1,384 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import customizer_attribute_service -from .base import CustomizerAttributeServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.CustomizerAttributeService", - "rpcName": str(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.ads.googleads.v19.services.CustomizerAttributeService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomizerAttributeServiceGrpcTransport( - CustomizerAttributeServiceTransport -): - """gRPC backend transport for CustomizerAttributeService. - - Service to manage customizer attribute - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_customizer_attributes( - self, - ) -> Callable[ - [customizer_attribute_service.MutateCustomizerAttributesRequest], - customizer_attribute_service.MutateCustomizerAttributesResponse, - ]: - r"""Return a callable for the mutate customizer attributes method over gRPC. - - Creates, updates or removes customizer attributes. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCustomizerAttributesRequest], - ~.MutateCustomizerAttributesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customizer_attributes" not in self._stubs: - self._stubs["mutate_customizer_attributes"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomizerAttributeService/MutateCustomizerAttributes", - request_serializer=customizer_attribute_service.MutateCustomizerAttributesRequest.serialize, - response_deserializer=customizer_attribute_service.MutateCustomizerAttributesResponse.deserialize, - ) - ) - return self._stubs["mutate_customizer_attributes"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("CustomizerAttributeServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/customizer_attribute_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/customizer_attribute_service/transports/grpc_asyncio.py deleted file mode 100644 index c28bc4f48..000000000 --- a/google/ads/googleads/v19/services/services/customizer_attribute_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,407 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import customizer_attribute_service -from .base import CustomizerAttributeServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.CustomizerAttributeService", - "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.ads.googleads.v19.services.CustomizerAttributeService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class CustomizerAttributeServiceGrpcAsyncIOTransport( - CustomizerAttributeServiceTransport -): - """gRPC AsyncIO backend transport for CustomizerAttributeService. - - Service to manage customizer attribute - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_customizer_attributes( - self, - ) -> Callable[ - [customizer_attribute_service.MutateCustomizerAttributesRequest], - Awaitable[ - customizer_attribute_service.MutateCustomizerAttributesResponse - ], - ]: - r"""Return a callable for the mutate customizer attributes method over gRPC. - - Creates, updates or removes customizer attributes. - Operation statuses are returned. - - Returns: - Callable[[~.MutateCustomizerAttributesRequest], - Awaitable[~.MutateCustomizerAttributesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_customizer_attributes" not in self._stubs: - self._stubs["mutate_customizer_attributes"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.CustomizerAttributeService/MutateCustomizerAttributes", - request_serializer=customizer_attribute_service.MutateCustomizerAttributesRequest.serialize, - response_deserializer=customizer_attribute_service.MutateCustomizerAttributesResponse.deserialize, - ) - ) - return self._stubs["mutate_customizer_attributes"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_customizer_attributes: self._wrap_method( - self.mutate_customizer_attributes, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("CustomizerAttributeServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/data_link_service/async_client.py b/google/ads/googleads/v19/services/services/data_link_service/async_client.py deleted file mode 100644 index ee0f69e52..000000000 --- a/google/ads/googleads/v19/services/services/data_link_service/async_client.py +++ /dev/null @@ -1,645 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.enums.types import ( - data_link_status as gage_data_link_status, -) -from google.ads.googleads.v19.resources.types import data_link as gagr_data_link -from google.ads.googleads.v19.services.types import data_link_service -from .transports.base import DataLinkServiceTransport, DEFAULT_CLIENT_INFO -from .client import DataLinkServiceClient - -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 DataLinkServiceAsyncClient: - """This service allows management of data links between a - Google Ads customer and another data entity. - """ - - _client: DataLinkServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = DataLinkServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = DataLinkServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - DataLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = DataLinkServiceClient._DEFAULT_UNIVERSE - - data_link_path = staticmethod(DataLinkServiceClient.data_link_path) - parse_data_link_path = staticmethod( - DataLinkServiceClient.parse_data_link_path - ) - common_billing_account_path = staticmethod( - DataLinkServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - DataLinkServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(DataLinkServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - DataLinkServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - DataLinkServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - DataLinkServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - DataLinkServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - DataLinkServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - DataLinkServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - DataLinkServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - DataLinkServiceAsyncClient: The constructed client. - """ - return DataLinkServiceClient.from_service_account_info.__func__(DataLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - DataLinkServiceAsyncClient: The constructed client. - """ - return DataLinkServiceClient.from_service_account_file.__func__(DataLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return DataLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> DataLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - DataLinkServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = DataLinkServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - DataLinkServiceTransport, - Callable[..., DataLinkServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the data link service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,DataLinkServiceTransport,Callable[..., DataLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the DataLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = DataLinkServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.DataLinkServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.DataLinkService", - "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.ads.googleads.v19.services.DataLinkService", - "credentialsType": None, - } - ), - ) - - async def create_data_link( - self, - request: Optional[ - Union[data_link_service.CreateDataLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - data_link: Optional[gagr_data_link.DataLink] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> data_link_service.CreateDataLinkResponse: - r"""Creates a data link. The requesting Google Ads account name and - account ID will be shared with the third party (such as YouTube - creators for video links) to whom you are creating the link - with. Only customers on the allow-list can create data links. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.CreateDataLinkRequest, dict]]): - The request object. Request message for - [DataLinkService.CreateDataLink][google.ads.googleads.v19.services.DataLinkService.CreateDataLink]. - customer_id (:class:`str`): - Required. The ID of the customer for - which the data link is created. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - data_link (:class:`google.ads.googleads.v19.resources.types.DataLink`): - Required. The data link to be - created. - - This corresponds to the ``data_link`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateDataLinkResponse: - Response message for - [DataLinkService.CreateDataLink][google.ads.googleads.v19.services.DataLinkService.CreateDataLink]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, data_link] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, data_link_service.CreateDataLinkRequest): - request = data_link_service.CreateDataLinkRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if data_link is not None: - request.data_link = data_link - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.create_data_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def remove_data_link( - self, - request: Optional[ - Union[data_link_service.RemoveDataLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> data_link_service.RemoveDataLinkResponse: - r"""Remove a data link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.RemoveDataLinkRequest, dict]]): - The request object. Request message for - [DataLinkService.RemoveDataLink][google.ads.googleads.v19.services.DataLinkService.RemoveDataLink]. - customer_id (:class:`str`): - Required. The ID of the customer for - which the data link is updated. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - resource_name (:class:`str`): - Required. The data link is expected - to have a valid resource name. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.RemoveDataLinkResponse: - Response message for - [DataLinkService.RemoveDataLink][google.ads.googleads.v19.services.DataLinkService.RemoveDataLink]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, data_link_service.RemoveDataLinkRequest): - request = data_link_service.RemoveDataLinkRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.remove_data_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def update_data_link( - self, - request: Optional[ - Union[data_link_service.UpdateDataLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - data_link_status: Optional[ - gage_data_link_status.DataLinkStatusEnum.DataLinkStatus - ] = None, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> data_link_service.UpdateDataLinkResponse: - r"""Update a data link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.UpdateDataLinkRequest, dict]]): - The request object. Request message for - [DataLinkService.UpdateDataLink][google.ads.googleads.v19.services.DataLinkService.UpdateDataLink]. - customer_id (:class:`str`): - Required. The ID of the customer for - which the data link is created. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - data_link_status (:class:`google.ads.googleads.v19.enums.types.DataLinkStatusEnum.DataLinkStatus`): - Required. The data link status to be - updated to. - - This corresponds to the ``data_link_status`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - resource_name (:class:`str`): - Required. The data link is expected - to have a valid resource name. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UpdateDataLinkResponse: - Response message for - [DataLinkService.UpdateDataLink][google.ads.googleads.v19.services.DataLinkService.UpdateDataLink]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, data_link_status, resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, data_link_service.UpdateDataLinkRequest): - request = data_link_service.UpdateDataLinkRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if data_link_status is not None: - request.data_link_status = data_link_status - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.update_data_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "DataLinkServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("DataLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/data_link_service/client.py b/google/ads/googleads/v19/services/services/data_link_service/client.py deleted file mode 100644 index 1c3200405..000000000 --- a/google/ads/googleads/v19/services/services/data_link_service/client.py +++ /dev/null @@ -1,1081 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.enums.types import ( - data_link_status as gage_data_link_status, -) -from google.ads.googleads.v19.resources.types import data_link as gagr_data_link -from google.ads.googleads.v19.services.types import data_link_service -from .transports.base import DataLinkServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import DataLinkServiceGrpcTransport -from .transports.grpc_asyncio import DataLinkServiceGrpcAsyncIOTransport - - -class DataLinkServiceClientMeta(type): - """Metaclass for the DataLinkService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[DataLinkServiceTransport]] - _transport_registry["grpc"] = DataLinkServiceGrpcTransport - _transport_registry["grpc_asyncio"] = DataLinkServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[DataLinkServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class DataLinkServiceClient(metaclass=DataLinkServiceClientMeta): - """This service allows management of data links between a - Google Ads customer and another data entity. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - DataLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - DataLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> DataLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - DataLinkServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def data_link_path( - customer_id: str, - product_link_id: str, - data_link_id: str, - ) -> str: - """Returns a fully-qualified data_link string.""" - return "customers/{customer_id}/dataLinks/{product_link_id}~{data_link_id}".format( - customer_id=customer_id, - product_link_id=product_link_id, - data_link_id=data_link_id, - ) - - @staticmethod - def parse_data_link_path(path: str) -> Dict[str, str]: - """Parses a data_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/dataLinks/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = DataLinkServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = DataLinkServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - DataLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = DataLinkServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - DataLinkServiceTransport, - Callable[..., DataLinkServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the data link service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,DataLinkServiceTransport,Callable[..., DataLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the DataLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = DataLinkServiceClient._read_environment_variables() - self._client_cert_source = ( - DataLinkServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = DataLinkServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, DataLinkServiceTransport) - if transport_provided: - # transport is a DataLinkServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(DataLinkServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or DataLinkServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[DataLinkServiceTransport], - Callable[..., DataLinkServiceTransport], - ] = ( - DataLinkServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., DataLinkServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.DataLinkServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.DataLinkService", - "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.ads.googleads.v19.services.DataLinkService", - "credentialsType": None, - } - ), - ) - - def create_data_link( - self, - request: Optional[ - Union[data_link_service.CreateDataLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - data_link: Optional[gagr_data_link.DataLink] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> data_link_service.CreateDataLinkResponse: - r"""Creates a data link. The requesting Google Ads account name and - account ID will be shared with the third party (such as YouTube - creators for video links) to whom you are creating the link - with. Only customers on the allow-list can create data links. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.CreateDataLinkRequest, dict]): - The request object. Request message for - [DataLinkService.CreateDataLink][google.ads.googleads.v19.services.DataLinkService.CreateDataLink]. - customer_id (str): - Required. The ID of the customer for - which the data link is created. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - data_link (google.ads.googleads.v19.resources.types.DataLink): - Required. The data link to be - created. - - This corresponds to the ``data_link`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateDataLinkResponse: - Response message for - [DataLinkService.CreateDataLink][google.ads.googleads.v19.services.DataLinkService.CreateDataLink]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, data_link] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, data_link_service.CreateDataLinkRequest): - request = data_link_service.CreateDataLinkRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if data_link is not None: - request.data_link = data_link - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.create_data_link] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def remove_data_link( - self, - request: Optional[ - Union[data_link_service.RemoveDataLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> data_link_service.RemoveDataLinkResponse: - r"""Remove a data link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.RemoveDataLinkRequest, dict]): - The request object. Request message for - [DataLinkService.RemoveDataLink][google.ads.googleads.v19.services.DataLinkService.RemoveDataLink]. - customer_id (str): - Required. The ID of the customer for - which the data link is updated. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - resource_name (str): - Required. The data link is expected - to have a valid resource name. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.RemoveDataLinkResponse: - Response message for - [DataLinkService.RemoveDataLink][google.ads.googleads.v19.services.DataLinkService.RemoveDataLink]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, data_link_service.RemoveDataLinkRequest): - request = data_link_service.RemoveDataLinkRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.remove_data_link] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def update_data_link( - self, - request: Optional[ - Union[data_link_service.UpdateDataLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - data_link_status: Optional[ - gage_data_link_status.DataLinkStatusEnum.DataLinkStatus - ] = None, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> data_link_service.UpdateDataLinkResponse: - r"""Update a data link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.UpdateDataLinkRequest, dict]): - The request object. Request message for - [DataLinkService.UpdateDataLink][google.ads.googleads.v19.services.DataLinkService.UpdateDataLink]. - customer_id (str): - Required. The ID of the customer for - which the data link is created. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - data_link_status (google.ads.googleads.v19.enums.types.DataLinkStatusEnum.DataLinkStatus): - Required. The data link status to be - updated to. - - This corresponds to the ``data_link_status`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - resource_name (str): - Required. The data link is expected - to have a valid resource name. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UpdateDataLinkResponse: - Response message for - [DataLinkService.UpdateDataLink][google.ads.googleads.v19.services.DataLinkService.UpdateDataLink]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, data_link_status, resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, data_link_service.UpdateDataLinkRequest): - request = data_link_service.UpdateDataLinkRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if data_link_status is not None: - request.data_link_status = data_link_status - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.update_data_link] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "DataLinkServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("DataLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/data_link_service/transports/base.py b/google/ads/googleads/v19/services/services/data_link_service/transports/base.py deleted file mode 100644 index 74bf67b15..000000000 --- a/google/ads/googleads/v19/services/services/data_link_service/transports/base.py +++ /dev/null @@ -1,206 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import data_link_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class DataLinkServiceTransport(abc.ABC): - """Abstract transport class for DataLinkService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.create_data_link: gapic_v1.method.wrap_method( - self.create_data_link, - default_timeout=None, - client_info=client_info, - ), - self.remove_data_link: gapic_v1.method.wrap_method( - self.remove_data_link, - default_timeout=None, - client_info=client_info, - ), - self.update_data_link: gapic_v1.method.wrap_method( - self.update_data_link, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def create_data_link( - self, - ) -> Callable[ - [data_link_service.CreateDataLinkRequest], - Union[ - data_link_service.CreateDataLinkResponse, - Awaitable[data_link_service.CreateDataLinkResponse], - ], - ]: - raise NotImplementedError() - - @property - def remove_data_link( - self, - ) -> Callable[ - [data_link_service.RemoveDataLinkRequest], - Union[ - data_link_service.RemoveDataLinkResponse, - Awaitable[data_link_service.RemoveDataLinkResponse], - ], - ]: - raise NotImplementedError() - - @property - def update_data_link( - self, - ) -> Callable[ - [data_link_service.UpdateDataLinkRequest], - Union[ - data_link_service.UpdateDataLinkResponse, - Awaitable[data_link_service.UpdateDataLinkResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("DataLinkServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/data_link_service/transports/grpc.py b/google/ads/googleads/v19/services/services/data_link_service/transports/grpc.py deleted file mode 100644 index 423249858..000000000 --- a/google/ads/googleads/v19/services/services/data_link_service/transports/grpc.py +++ /dev/null @@ -1,459 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import data_link_service -from .base import DataLinkServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.DataLinkService", - "rpcName": str(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.ads.googleads.v19.services.DataLinkService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class DataLinkServiceGrpcTransport(DataLinkServiceTransport): - """gRPC backend transport for DataLinkService. - - This service allows management of data links between a - Google Ads customer and another data entity. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def create_data_link( - self, - ) -> Callable[ - [data_link_service.CreateDataLinkRequest], - data_link_service.CreateDataLinkResponse, - ]: - r"""Return a callable for the create data link method over gRPC. - - Creates a data link. The requesting Google Ads account name and - account ID will be shared with the third party (such as YouTube - creators for video links) to whom you are creating the link - with. Only customers on the allow-list can create data links. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.CreateDataLinkRequest], - ~.CreateDataLinkResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_data_link" not in self._stubs: - self._stubs["create_data_link"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.DataLinkService/CreateDataLink", - request_serializer=data_link_service.CreateDataLinkRequest.serialize, - response_deserializer=data_link_service.CreateDataLinkResponse.deserialize, - ) - return self._stubs["create_data_link"] - - @property - def remove_data_link( - self, - ) -> Callable[ - [data_link_service.RemoveDataLinkRequest], - data_link_service.RemoveDataLinkResponse, - ]: - r"""Return a callable for the remove data link method over gRPC. - - Remove a data link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.RemoveDataLinkRequest], - ~.RemoveDataLinkResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "remove_data_link" not in self._stubs: - self._stubs["remove_data_link"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.DataLinkService/RemoveDataLink", - request_serializer=data_link_service.RemoveDataLinkRequest.serialize, - response_deserializer=data_link_service.RemoveDataLinkResponse.deserialize, - ) - return self._stubs["remove_data_link"] - - @property - def update_data_link( - self, - ) -> Callable[ - [data_link_service.UpdateDataLinkRequest], - data_link_service.UpdateDataLinkResponse, - ]: - r"""Return a callable for the update data link method over gRPC. - - Update a data link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.UpdateDataLinkRequest], - ~.UpdateDataLinkResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "update_data_link" not in self._stubs: - self._stubs["update_data_link"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.DataLinkService/UpdateDataLink", - request_serializer=data_link_service.UpdateDataLinkRequest.serialize, - response_deserializer=data_link_service.UpdateDataLinkResponse.deserialize, - ) - return self._stubs["update_data_link"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("DataLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/data_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/data_link_service/transports/grpc_asyncio.py deleted file mode 100644 index 240227b76..000000000 --- a/google/ads/googleads/v19/services/services/data_link_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,490 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import data_link_service -from .base import DataLinkServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.DataLinkService", - "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.ads.googleads.v19.services.DataLinkService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class DataLinkServiceGrpcAsyncIOTransport(DataLinkServiceTransport): - """gRPC AsyncIO backend transport for DataLinkService. - - This service allows management of data links between a - Google Ads customer and another data entity. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def create_data_link( - self, - ) -> Callable[ - [data_link_service.CreateDataLinkRequest], - Awaitable[data_link_service.CreateDataLinkResponse], - ]: - r"""Return a callable for the create data link method over gRPC. - - Creates a data link. The requesting Google Ads account name and - account ID will be shared with the third party (such as YouTube - creators for video links) to whom you are creating the link - with. Only customers on the allow-list can create data links. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.CreateDataLinkRequest], - Awaitable[~.CreateDataLinkResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_data_link" not in self._stubs: - self._stubs["create_data_link"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.DataLinkService/CreateDataLink", - request_serializer=data_link_service.CreateDataLinkRequest.serialize, - response_deserializer=data_link_service.CreateDataLinkResponse.deserialize, - ) - return self._stubs["create_data_link"] - - @property - def remove_data_link( - self, - ) -> Callable[ - [data_link_service.RemoveDataLinkRequest], - Awaitable[data_link_service.RemoveDataLinkResponse], - ]: - r"""Return a callable for the remove data link method over gRPC. - - Remove a data link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.RemoveDataLinkRequest], - Awaitable[~.RemoveDataLinkResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "remove_data_link" not in self._stubs: - self._stubs["remove_data_link"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.DataLinkService/RemoveDataLink", - request_serializer=data_link_service.RemoveDataLinkRequest.serialize, - response_deserializer=data_link_service.RemoveDataLinkResponse.deserialize, - ) - return self._stubs["remove_data_link"] - - @property - def update_data_link( - self, - ) -> Callable[ - [data_link_service.UpdateDataLinkRequest], - Awaitable[data_link_service.UpdateDataLinkResponse], - ]: - r"""Return a callable for the update data link method over gRPC. - - Update a data link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.UpdateDataLinkRequest], - Awaitable[~.UpdateDataLinkResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "update_data_link" not in self._stubs: - self._stubs["update_data_link"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.DataLinkService/UpdateDataLink", - request_serializer=data_link_service.UpdateDataLinkRequest.serialize, - response_deserializer=data_link_service.UpdateDataLinkResponse.deserialize, - ) - return self._stubs["update_data_link"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.create_data_link: self._wrap_method( - self.create_data_link, - default_timeout=None, - client_info=client_info, - ), - self.remove_data_link: self._wrap_method( - self.remove_data_link, - default_timeout=None, - client_info=client_info, - ), - self.update_data_link: self._wrap_method( - self.update_data_link, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("DataLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/experiment_arm_service/async_client.py b/google/ads/googleads/v19/services/services/experiment_arm_service/async_client.py deleted file mode 100644 index 345dbc3a3..000000000 --- a/google/ads/googleads/v19/services/services/experiment_arm_service/async_client.py +++ /dev/null @@ -1,433 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import experiment_arm_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ExperimentArmServiceTransport, DEFAULT_CLIENT_INFO -from .client import ExperimentArmServiceClient - -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 ExperimentArmServiceAsyncClient: - """Service to manage experiment arms.""" - - _client: ExperimentArmServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ExperimentArmServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ExperimentArmServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - ExperimentArmServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ExperimentArmServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod(ExperimentArmServiceClient.campaign_path) - parse_campaign_path = staticmethod( - ExperimentArmServiceClient.parse_campaign_path - ) - experiment_path = staticmethod(ExperimentArmServiceClient.experiment_path) - parse_experiment_path = staticmethod( - ExperimentArmServiceClient.parse_experiment_path - ) - experiment_arm_path = staticmethod( - ExperimentArmServiceClient.experiment_arm_path - ) - parse_experiment_arm_path = staticmethod( - ExperimentArmServiceClient.parse_experiment_arm_path - ) - common_billing_account_path = staticmethod( - ExperimentArmServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ExperimentArmServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ExperimentArmServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ExperimentArmServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ExperimentArmServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ExperimentArmServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ExperimentArmServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ExperimentArmServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ExperimentArmServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ExperimentArmServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ExperimentArmServiceAsyncClient: The constructed client. - """ - return ExperimentArmServiceClient.from_service_account_info.__func__(ExperimentArmServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ExperimentArmServiceAsyncClient: The constructed client. - """ - return ExperimentArmServiceClient.from_service_account_file.__func__(ExperimentArmServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ExperimentArmServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ExperimentArmServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ExperimentArmServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ExperimentArmServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ExperimentArmServiceTransport, - Callable[..., ExperimentArmServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the experiment arm service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ExperimentArmServiceTransport,Callable[..., ExperimentArmServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ExperimentArmServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ExperimentArmServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ExperimentArmServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ExperimentArmService", - "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.ads.googleads.v19.services.ExperimentArmService", - "credentialsType": None, - } - ), - ) - - async def mutate_experiment_arms( - self, - request: Optional[ - Union[experiment_arm_service.MutateExperimentArmsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[experiment_arm_service.ExperimentArmOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> experiment_arm_service.MutateExperimentArmsResponse: - r"""Creates, updates, or removes experiment arms. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentArmError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateExperimentArmsRequest, dict]]): - The request object. Request message for - [ExperimentArmService.MutateExperimentArms][google.ads.googleads.v19.services.ExperimentArmService.MutateExperimentArms]. - customer_id (:class:`str`): - Required. The ID of the customer - whose experiments are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.ExperimentArmOperation]`): - Required. The list of operations to - perform on individual experiment arm. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateExperimentArmsResponse: - Response message for experiment arm - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, experiment_arm_service.MutateExperimentArmsRequest - ): - request = experiment_arm_service.MutateExperimentArmsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_experiment_arms - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ExperimentArmServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ExperimentArmServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/experiment_arm_service/client.py b/google/ads/googleads/v19/services/services/experiment_arm_service/client.py deleted file mode 100644 index e1154a221..000000000 --- a/google/ads/googleads/v19/services/services/experiment_arm_service/client.py +++ /dev/null @@ -1,921 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import experiment_arm_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ExperimentArmServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import ExperimentArmServiceGrpcTransport -from .transports.grpc_asyncio import ExperimentArmServiceGrpcAsyncIOTransport - - -class ExperimentArmServiceClientMeta(type): - """Metaclass for the ExperimentArmService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ExperimentArmServiceTransport]] - _transport_registry["grpc"] = ExperimentArmServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - ExperimentArmServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ExperimentArmServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ExperimentArmServiceClient(metaclass=ExperimentArmServiceClientMeta): - """Service to manage experiment arms.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ExperimentArmServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ExperimentArmServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ExperimentArmServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ExperimentArmServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def experiment_path( - customer_id: str, - trial_id: str, - ) -> str: - """Returns a fully-qualified experiment string.""" - return "customers/{customer_id}/experiments/{trial_id}".format( - customer_id=customer_id, - trial_id=trial_id, - ) - - @staticmethod - def parse_experiment_path(path: str) -> Dict[str, str]: - """Parses a experiment path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/experiments/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def experiment_arm_path( - customer_id: str, - trial_id: str, - trial_arm_id: str, - ) -> str: - """Returns a fully-qualified experiment_arm string.""" - return "customers/{customer_id}/experimentArms/{trial_id}~{trial_arm_id}".format( - customer_id=customer_id, - trial_id=trial_id, - trial_arm_id=trial_arm_id, - ) - - @staticmethod - def parse_experiment_arm_path(path: str) -> Dict[str, str]: - """Parses a experiment_arm path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/experimentArms/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ExperimentArmServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ExperimentArmServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - ExperimentArmServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ExperimentArmServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ExperimentArmServiceTransport, - Callable[..., ExperimentArmServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the experiment arm service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ExperimentArmServiceTransport,Callable[..., ExperimentArmServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ExperimentArmServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ExperimentArmServiceClient._read_environment_variables() - self._client_cert_source = ( - ExperimentArmServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ExperimentArmServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ExperimentArmServiceTransport - ) - if transport_provided: - # transport is a ExperimentArmServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(ExperimentArmServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ExperimentArmServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ExperimentArmServiceTransport], - Callable[..., ExperimentArmServiceTransport], - ] = ( - ExperimentArmServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ExperimentArmServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ExperimentArmServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ExperimentArmService", - "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.ads.googleads.v19.services.ExperimentArmService", - "credentialsType": None, - } - ), - ) - - def mutate_experiment_arms( - self, - request: Optional[ - Union[experiment_arm_service.MutateExperimentArmsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[experiment_arm_service.ExperimentArmOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> experiment_arm_service.MutateExperimentArmsResponse: - r"""Creates, updates, or removes experiment arms. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentArmError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateExperimentArmsRequest, dict]): - The request object. Request message for - [ExperimentArmService.MutateExperimentArms][google.ads.googleads.v19.services.ExperimentArmService.MutateExperimentArms]. - customer_id (str): - Required. The ID of the customer - whose experiments are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.ExperimentArmOperation]): - Required. The list of operations to - perform on individual experiment arm. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateExperimentArmsResponse: - Response message for experiment arm - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, experiment_arm_service.MutateExperimentArmsRequest - ): - request = experiment_arm_service.MutateExperimentArmsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_experiment_arms - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ExperimentArmServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ExperimentArmServiceClient",) diff --git a/google/ads/googleads/v19/services/services/experiment_arm_service/transports/base.py b/google/ads/googleads/v19/services/services/experiment_arm_service/transports/base.py deleted file mode 100644 index 683f80ffb..000000000 --- a/google/ads/googleads/v19/services/services/experiment_arm_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import experiment_arm_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ExperimentArmServiceTransport(abc.ABC): - """Abstract transport class for ExperimentArmService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_experiment_arms: gapic_v1.method.wrap_method( - self.mutate_experiment_arms, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_experiment_arms( - self, - ) -> Callable[ - [experiment_arm_service.MutateExperimentArmsRequest], - Union[ - experiment_arm_service.MutateExperimentArmsResponse, - Awaitable[experiment_arm_service.MutateExperimentArmsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ExperimentArmServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/experiment_arm_service/transports/grpc.py b/google/ads/googleads/v19/services/services/experiment_arm_service/transports/grpc.py deleted file mode 100644 index 46496f8dc..000000000 --- a/google/ads/googleads/v19/services/services/experiment_arm_service/transports/grpc.py +++ /dev/null @@ -1,387 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import experiment_arm_service -from .base import ExperimentArmServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ExperimentArmService", - "rpcName": str(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.ads.googleads.v19.services.ExperimentArmService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ExperimentArmServiceGrpcTransport(ExperimentArmServiceTransport): - """gRPC backend transport for ExperimentArmService. - - Service to manage experiment arms. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_experiment_arms( - self, - ) -> Callable[ - [experiment_arm_service.MutateExperimentArmsRequest], - experiment_arm_service.MutateExperimentArmsResponse, - ]: - r"""Return a callable for the mutate experiment arms method over gRPC. - - Creates, updates, or removes experiment arms. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentArmError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateExperimentArmsRequest], - ~.MutateExperimentArmsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_experiment_arms" not in self._stubs: - self._stubs["mutate_experiment_arms"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentArmService/MutateExperimentArms", - request_serializer=experiment_arm_service.MutateExperimentArmsRequest.serialize, - response_deserializer=experiment_arm_service.MutateExperimentArmsResponse.deserialize, - ) - ) - return self._stubs["mutate_experiment_arms"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ExperimentArmServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/experiment_arm_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/experiment_arm_service/transports/grpc_asyncio.py deleted file mode 100644 index f048233ae..000000000 --- a/google/ads/googleads/v19/services/services/experiment_arm_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,408 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import experiment_arm_service -from .base import ExperimentArmServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ExperimentArmService", - "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.ads.googleads.v19.services.ExperimentArmService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ExperimentArmServiceGrpcAsyncIOTransport(ExperimentArmServiceTransport): - """gRPC AsyncIO backend transport for ExperimentArmService. - - Service to manage experiment arms. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_experiment_arms( - self, - ) -> Callable[ - [experiment_arm_service.MutateExperimentArmsRequest], - Awaitable[experiment_arm_service.MutateExperimentArmsResponse], - ]: - r"""Return a callable for the mutate experiment arms method over gRPC. - - Creates, updates, or removes experiment arms. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentArmError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateExperimentArmsRequest], - Awaitable[~.MutateExperimentArmsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_experiment_arms" not in self._stubs: - self._stubs["mutate_experiment_arms"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentArmService/MutateExperimentArms", - request_serializer=experiment_arm_service.MutateExperimentArmsRequest.serialize, - response_deserializer=experiment_arm_service.MutateExperimentArmsResponse.deserialize, - ) - ) - return self._stubs["mutate_experiment_arms"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_experiment_arms: self._wrap_method( - self.mutate_experiment_arms, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ExperimentArmServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/experiment_service/async_client.py b/google/ads/googleads/v19/services/services/experiment_service/async_client.py deleted file mode 100644 index dd49b8faf..000000000 --- a/google/ads/googleads/v19/services/services/experiment_service/async_client.py +++ /dev/null @@ -1,977 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.services.experiment_service import pagers -from google.ads.googleads.v19.services.types import experiment_service -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from google.rpc import status_pb2 # type: ignore -from .transports.base import ExperimentServiceTransport, DEFAULT_CLIENT_INFO -from .client import ExperimentServiceClient - -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 ExperimentServiceAsyncClient: - """Service to manage experiments.""" - - _client: ExperimentServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ExperimentServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ExperimentServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - ExperimentServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ExperimentServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod(ExperimentServiceClient.campaign_path) - parse_campaign_path = staticmethod( - ExperimentServiceClient.parse_campaign_path - ) - campaign_budget_path = staticmethod( - ExperimentServiceClient.campaign_budget_path - ) - parse_campaign_budget_path = staticmethod( - ExperimentServiceClient.parse_campaign_budget_path - ) - experiment_path = staticmethod(ExperimentServiceClient.experiment_path) - parse_experiment_path = staticmethod( - ExperimentServiceClient.parse_experiment_path - ) - common_billing_account_path = staticmethod( - ExperimentServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ExperimentServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ExperimentServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ExperimentServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ExperimentServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ExperimentServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ExperimentServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ExperimentServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ExperimentServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ExperimentServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ExperimentServiceAsyncClient: The constructed client. - """ - return ExperimentServiceClient.from_service_account_info.__func__(ExperimentServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ExperimentServiceAsyncClient: The constructed client. - """ - return ExperimentServiceClient.from_service_account_file.__func__(ExperimentServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ExperimentServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ExperimentServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ExperimentServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ExperimentServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ExperimentServiceTransport, - Callable[..., ExperimentServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the experiment service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ExperimentServiceTransport,Callable[..., ExperimentServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ExperimentServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ExperimentServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ExperimentServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ExperimentService", - "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.ads.googleads.v19.services.ExperimentService", - "credentialsType": None, - } - ), - ) - - async def mutate_experiments( - self, - request: Optional[ - Union[experiment_service.MutateExperimentsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[experiment_service.ExperimentOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> experiment_service.MutateExperimentsResponse: - r"""Creates, updates, or removes experiments. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateExperimentsRequest, dict]]): - The request object. Request message for - [ExperimentService.MutateExperiments][google.ads.googleads.v19.services.ExperimentService.MutateExperiments]. - customer_id (:class:`str`): - Required. The ID of the customer - whose experiments are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.ExperimentOperation]`): - Required. The list of operations to - perform on individual experiments. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateExperimentsResponse: - Response message for experiment - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, experiment_service.MutateExperimentsRequest): - request = experiment_service.MutateExperimentsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_experiments - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def end_experiment( - self, - request: Optional[ - Union[experiment_service.EndExperimentRequest, dict] - ] = None, - *, - experiment: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> None: - r"""Immediately ends an experiment, changing the experiment's - scheduled end date and without waiting for end of day. End date - is updated to be the time of the request. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.EndExperimentRequest, dict]]): - The request object. Request message for - [ExperimentService.EndExperiment][google.ads.googleads.v19.services.ExperimentService.EndExperiment]. - experiment (:class:`str`): - Required. The resource name of the - campaign experiment to end. - - This corresponds to the ``experiment`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 - # gotten any keyword arguments that map to the request. - flattened_params = [experiment] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, experiment_service.EndExperimentRequest): - request = experiment_service.EndExperimentRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if experiment is not None: - request.experiment = experiment - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.end_experiment - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("experiment", request.experiment),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - async def list_experiment_async_errors( - self, - request: Optional[ - Union[experiment_service.ListExperimentAsyncErrorsRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListExperimentAsyncErrorsAsyncPager: - r"""Returns all errors that occurred during the last Experiment - update (either scheduling or promotion). Supports standard list - paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ListExperimentAsyncErrorsRequest, dict]]): - The request object. Request message for - [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v19.services.ExperimentService.ListExperimentAsyncErrors]. - resource_name (:class:`str`): - Required. The name of the experiment - from which to retrieve the async errors. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.experiment_service.pagers.ListExperimentAsyncErrorsAsyncPager: - Response message for - [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v19.services.ExperimentService.ListExperimentAsyncErrors]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, experiment_service.ListExperimentAsyncErrorsRequest - ): - request = experiment_service.ListExperimentAsyncErrorsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_experiment_async_errors - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.ListExperimentAsyncErrorsAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def graduate_experiment( - self, - request: Optional[ - Union[experiment_service.GraduateExperimentRequest, dict] - ] = None, - *, - experiment: Optional[str] = None, - campaign_budget_mappings: Optional[ - MutableSequence[experiment_service.CampaignBudgetMapping] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> None: - r"""Graduates an experiment to a full campaign. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GraduateExperimentRequest, dict]]): - The request object. Request message for - [ExperimentService.GraduateExperiment][google.ads.googleads.v19.services.ExperimentService.GraduateExperiment]. - experiment (:class:`str`): - Required. The experiment to be - graduated. - - This corresponds to the ``experiment`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - campaign_budget_mappings (:class:`MutableSequence[google.ads.googleads.v19.services.types.CampaignBudgetMapping]`): - Required. List of campaign budget - mappings for graduation. Each campaign - that appears here will graduate, and - will be assigned a new budget that is - paired with it in the mapping. The - maximum size is one. - - This corresponds to the ``campaign_budget_mappings`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 - # gotten any keyword arguments that map to the request. - flattened_params = [experiment, campaign_budget_mappings] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, experiment_service.GraduateExperimentRequest - ): - request = experiment_service.GraduateExperimentRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if experiment is not None: - request.experiment = experiment - if campaign_budget_mappings: - request.campaign_budget_mappings.extend(campaign_budget_mappings) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.graduate_experiment - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("experiment", request.experiment),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - async def schedule_experiment( - self, - request: Optional[ - Union[experiment_service.ScheduleExperimentRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operation_async.AsyncOperation: - r"""Schedule an experiment. The in design campaign will be converted - into a real campaign (called the experiment campaign) that will - begin serving ads if successfully created. - - The experiment is scheduled immediately with status - INITIALIZING. This method returns a long running operation that - tracks the forking of the in design campaign. If the forking - fails, a list of errors can be retrieved using the - ListExperimentAsyncErrors method. The operation's metadata will - be a string containing the resource name of the created - experiment. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ScheduleExperimentRequest, dict]]): - The request object. Request message for - [ExperimentService.ScheduleExperiment][google.ads.googleads.v19.services.ExperimentService.ScheduleExperiment]. - resource_name (:class:`str`): - Required. The scheduled experiment. - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, experiment_service.ScheduleExperimentRequest - ): - request = experiment_service.ScheduleExperimentRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.schedule_experiment - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - empty_pb2.Empty, - metadata_type=experiment_service.ScheduleExperimentMetadata, - ) - - # Done; return the response. - return response - - async def promote_experiment( - self, - request: Optional[ - Union[experiment_service.PromoteExperimentRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operation_async.AsyncOperation: - r"""Promotes the trial campaign thus applying changes in the trial - campaign to the base campaign. This method returns a long - running operation that tracks the promotion of the experiment - campaign. If it fails, a list of errors can be retrieved using - the ListExperimentAsyncErrors method. The operation's metadata - will be a string containing the resource name of the created - experiment. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.PromoteExperimentRequest, dict]]): - The request object. Request message for - [ExperimentService.PromoteExperiment][google.ads.googleads.v19.services.ExperimentService.PromoteExperiment]. - resource_name (:class:`str`): - Required. The resource name of the - experiment to promote. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, experiment_service.PromoteExperimentRequest): - request = experiment_service.PromoteExperimentRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.promote_experiment - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - empty_pb2.Empty, - metadata_type=experiment_service.PromoteExperimentMetadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ExperimentServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ExperimentServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/experiment_service/client.py b/google/ads/googleads/v19/services/services/experiment_service/client.py deleted file mode 100644 index 54978abef..000000000 --- a/google/ads/googleads/v19/services/services/experiment_service/client.py +++ /dev/null @@ -1,1450 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.services.experiment_service import pagers -from google.ads.googleads.v19.services.types import experiment_service -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from google.rpc import status_pb2 # type: ignore -from .transports.base import ExperimentServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import ExperimentServiceGrpcTransport -from .transports.grpc_asyncio import ExperimentServiceGrpcAsyncIOTransport - - -class ExperimentServiceClientMeta(type): - """Metaclass for the ExperimentService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ExperimentServiceTransport]] - _transport_registry["grpc"] = ExperimentServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ExperimentServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ExperimentServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ExperimentServiceClient(metaclass=ExperimentServiceClientMeta): - """Service to manage experiments.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ExperimentServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ExperimentServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ExperimentServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ExperimentServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_budget_path( - customer_id: str, - campaign_budget_id: str, - ) -> str: - """Returns a fully-qualified campaign_budget string.""" - return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( - customer_id=customer_id, - campaign_budget_id=campaign_budget_id, - ) - - @staticmethod - def parse_campaign_budget_path(path: str) -> Dict[str, str]: - """Parses a campaign_budget path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def experiment_path( - customer_id: str, - trial_id: str, - ) -> str: - """Returns a fully-qualified experiment string.""" - return "customers/{customer_id}/experiments/{trial_id}".format( - customer_id=customer_id, - trial_id=trial_id, - ) - - @staticmethod - def parse_experiment_path(path: str) -> Dict[str, str]: - """Parses a experiment path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/experiments/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ExperimentServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ExperimentServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - ExperimentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ExperimentServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ExperimentServiceTransport, - Callable[..., ExperimentServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the experiment service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ExperimentServiceTransport,Callable[..., ExperimentServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ExperimentServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ExperimentServiceClient._read_environment_variables() - self._client_cert_source = ( - ExperimentServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ExperimentServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, ExperimentServiceTransport) - if transport_provided: - # transport is a ExperimentServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(ExperimentServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ExperimentServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ExperimentServiceTransport], - Callable[..., ExperimentServiceTransport], - ] = ( - ExperimentServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., ExperimentServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ExperimentServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ExperimentService", - "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.ads.googleads.v19.services.ExperimentService", - "credentialsType": None, - } - ), - ) - - def mutate_experiments( - self, - request: Optional[ - Union[experiment_service.MutateExperimentsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[experiment_service.ExperimentOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> experiment_service.MutateExperimentsResponse: - r"""Creates, updates, or removes experiments. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateExperimentsRequest, dict]): - The request object. Request message for - [ExperimentService.MutateExperiments][google.ads.googleads.v19.services.ExperimentService.MutateExperiments]. - customer_id (str): - Required. The ID of the customer - whose experiments are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.ExperimentOperation]): - Required. The list of operations to - perform on individual experiments. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateExperimentsResponse: - Response message for experiment - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, experiment_service.MutateExperimentsRequest): - request = experiment_service.MutateExperimentsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_experiments - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def end_experiment( - self, - request: Optional[ - Union[experiment_service.EndExperimentRequest, dict] - ] = None, - *, - experiment: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> None: - r"""Immediately ends an experiment, changing the experiment's - scheduled end date and without waiting for end of day. End date - is updated to be the time of the request. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.EndExperimentRequest, dict]): - The request object. Request message for - [ExperimentService.EndExperiment][google.ads.googleads.v19.services.ExperimentService.EndExperiment]. - experiment (str): - Required. The resource name of the - campaign experiment to end. - - This corresponds to the ``experiment`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 - # gotten any keyword arguments that map to the request. - flattened_params = [experiment] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, experiment_service.EndExperimentRequest): - request = experiment_service.EndExperimentRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if experiment is not None: - request.experiment = experiment - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.end_experiment] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("experiment", request.experiment),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - def list_experiment_async_errors( - self, - request: Optional[ - Union[experiment_service.ListExperimentAsyncErrorsRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.ListExperimentAsyncErrorsPager: - r"""Returns all errors that occurred during the last Experiment - update (either scheduling or promotion). Supports standard list - paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ListExperimentAsyncErrorsRequest, dict]): - The request object. Request message for - [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v19.services.ExperimentService.ListExperimentAsyncErrors]. - resource_name (str): - Required. The name of the experiment - from which to retrieve the async errors. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.experiment_service.pagers.ListExperimentAsyncErrorsPager: - Response message for - [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v19.services.ExperimentService.ListExperimentAsyncErrors]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, experiment_service.ListExperimentAsyncErrorsRequest - ): - request = experiment_service.ListExperimentAsyncErrorsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.list_experiment_async_errors - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.ListExperimentAsyncErrorsPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def graduate_experiment( - self, - request: Optional[ - Union[experiment_service.GraduateExperimentRequest, dict] - ] = None, - *, - experiment: Optional[str] = None, - campaign_budget_mappings: Optional[ - MutableSequence[experiment_service.CampaignBudgetMapping] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> None: - r"""Graduates an experiment to a full campaign. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GraduateExperimentRequest, dict]): - The request object. Request message for - [ExperimentService.GraduateExperiment][google.ads.googleads.v19.services.ExperimentService.GraduateExperiment]. - experiment (str): - Required. The experiment to be - graduated. - - This corresponds to the ``experiment`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - campaign_budget_mappings (MutableSequence[google.ads.googleads.v19.services.types.CampaignBudgetMapping]): - Required. List of campaign budget - mappings for graduation. Each campaign - that appears here will graduate, and - will be assigned a new budget that is - paired with it in the mapping. The - maximum size is one. - - This corresponds to the ``campaign_budget_mappings`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 - # gotten any keyword arguments that map to the request. - flattened_params = [experiment, campaign_budget_mappings] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, experiment_service.GraduateExperimentRequest - ): - request = experiment_service.GraduateExperimentRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if experiment is not None: - request.experiment = experiment - if campaign_budget_mappings is not None: - request.campaign_budget_mappings = campaign_budget_mappings - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.graduate_experiment - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("experiment", request.experiment),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - def schedule_experiment( - self, - request: Optional[ - Union[experiment_service.ScheduleExperimentRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operation.Operation: - r"""Schedule an experiment. The in design campaign will be converted - into a real campaign (called the experiment campaign) that will - begin serving ads if successfully created. - - The experiment is scheduled immediately with status - INITIALIZING. This method returns a long running operation that - tracks the forking of the in design campaign. If the forking - fails, a list of errors can be retrieved using the - ListExperimentAsyncErrors method. The operation's metadata will - be a string containing the resource name of the created - experiment. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ScheduleExperimentRequest, dict]): - The request object. Request message for - [ExperimentService.ScheduleExperiment][google.ads.googleads.v19.services.ExperimentService.ScheduleExperiment]. - resource_name (str): - Required. The scheduled experiment. - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, experiment_service.ScheduleExperimentRequest - ): - request = experiment_service.ScheduleExperimentRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.schedule_experiment - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - empty_pb2.Empty, - metadata_type=experiment_service.ScheduleExperimentMetadata, - ) - - # Done; return the response. - return response - - def promote_experiment( - self, - request: Optional[ - Union[experiment_service.PromoteExperimentRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operation.Operation: - r"""Promotes the trial campaign thus applying changes in the trial - campaign to the base campaign. This method returns a long - running operation that tracks the promotion of the experiment - campaign. If it fails, a list of errors can be retrieved using - the ListExperimentAsyncErrors method. The operation's metadata - will be a string containing the resource name of the created - experiment. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.PromoteExperimentRequest, dict]): - The request object. Request message for - [ExperimentService.PromoteExperiment][google.ads.googleads.v19.services.ExperimentService.PromoteExperiment]. - resource_name (str): - Required. The resource name of the - experiment to promote. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, experiment_service.PromoteExperimentRequest): - request = experiment_service.PromoteExperimentRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.promote_experiment - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - empty_pb2.Empty, - metadata_type=experiment_service.PromoteExperimentMetadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ExperimentServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ExperimentServiceClient",) diff --git a/google/ads/googleads/v19/services/services/experiment_service/pagers.py b/google/ads/googleads/v19/services/services/experiment_service/pagers.py deleted file mode 100644 index 07afa6f8e..000000000 --- a/google/ads/googleads/v19/services/services/experiment_service/pagers.py +++ /dev/null @@ -1,208 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import retry_async as retries_async -from typing import ( - Any, - AsyncIterator, - Awaitable, - Callable, - Sequence, - Tuple, - Iterator, - Union, -) - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] - OptionalAsyncRetry = Union[ - retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import experiment_service -from google.rpc import status_pb2 # type: ignore - - -class ListExperimentAsyncErrorsPager: - """A pager for iterating through ``list_experiment_async_errors`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.ListExperimentAsyncErrorsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``errors`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``ListExperimentAsyncErrors`` requests and continue to iterate - through the ``errors`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.ListExperimentAsyncErrorsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[ - ..., experiment_service.ListExperimentAsyncErrorsResponse - ], - request: experiment_service.ListExperimentAsyncErrorsRequest, - response: experiment_service.ListExperimentAsyncErrorsResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.ListExperimentAsyncErrorsRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.ListExperimentAsyncErrorsResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = experiment_service.ListExperimentAsyncErrorsRequest( - request - ) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages( - self, - ) -> Iterator[experiment_service.ListExperimentAsyncErrorsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __iter__(self) -> Iterator[status_pb2.Status]: - for page in self.pages: - yield from page.errors - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) - - -class ListExperimentAsyncErrorsAsyncPager: - """A pager for iterating through ``list_experiment_async_errors`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.ListExperimentAsyncErrorsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``errors`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``ListExperimentAsyncErrors`` requests and continue to iterate - through the ``errors`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.ListExperimentAsyncErrorsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[ - ..., Awaitable[experiment_service.ListExperimentAsyncErrorsResponse] - ], - request: experiment_service.ListExperimentAsyncErrorsRequest, - response: experiment_service.ListExperimentAsyncErrorsResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.ListExperimentAsyncErrorsRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.ListExperimentAsyncErrorsResponse): - The initial response object. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = experiment_service.ListExperimentAsyncErrorsRequest( - request - ) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages( - self, - ) -> AsyncIterator[experiment_service.ListExperimentAsyncErrorsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __aiter__(self) -> AsyncIterator[status_pb2.Status]: - async def async_generator(): - async for page in self.pages: - for response in page.errors: - yield response - - return async_generator() - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/experiment_service/transports/base.py b/google/ads/googleads/v19/services/services/experiment_service/transports/base.py deleted file mode 100644 index f67ac94c9..000000000 --- a/google/ads/googleads/v19/services/services/experiment_service/transports/base.py +++ /dev/null @@ -1,252 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import experiment_service -from google.longrunning import operations_pb2 # type: ignore -from google.protobuf import empty_pb2 # type: ignore - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ExperimentServiceTransport(abc.ABC): - """Abstract transport class for ExperimentService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_experiments: gapic_v1.method.wrap_method( - self.mutate_experiments, - default_timeout=None, - client_info=client_info, - ), - self.end_experiment: gapic_v1.method.wrap_method( - self.end_experiment, - default_timeout=None, - client_info=client_info, - ), - self.list_experiment_async_errors: gapic_v1.method.wrap_method( - self.list_experiment_async_errors, - default_timeout=None, - client_info=client_info, - ), - self.graduate_experiment: gapic_v1.method.wrap_method( - self.graduate_experiment, - default_timeout=None, - client_info=client_info, - ), - self.schedule_experiment: gapic_v1.method.wrap_method( - self.schedule_experiment, - default_timeout=None, - client_info=client_info, - ), - self.promote_experiment: gapic_v1.method.wrap_method( - self.promote_experiment, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def operations_client(self): - """Return the client designed to process long-running operations.""" - raise NotImplementedError() - - @property - def mutate_experiments( - self, - ) -> Callable[ - [experiment_service.MutateExperimentsRequest], - Union[ - experiment_service.MutateExperimentsResponse, - Awaitable[experiment_service.MutateExperimentsResponse], - ], - ]: - raise NotImplementedError() - - @property - def end_experiment( - self, - ) -> Callable[ - [experiment_service.EndExperimentRequest], - Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], - ]: - raise NotImplementedError() - - @property - def list_experiment_async_errors( - self, - ) -> Callable[ - [experiment_service.ListExperimentAsyncErrorsRequest], - Union[ - experiment_service.ListExperimentAsyncErrorsResponse, - Awaitable[experiment_service.ListExperimentAsyncErrorsResponse], - ], - ]: - raise NotImplementedError() - - @property - def graduate_experiment( - self, - ) -> Callable[ - [experiment_service.GraduateExperimentRequest], - Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], - ]: - raise NotImplementedError() - - @property - def schedule_experiment( - self, - ) -> Callable[ - [experiment_service.ScheduleExperimentRequest], - Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], - ]: - raise NotImplementedError() - - @property - def promote_experiment( - self, - ) -> Callable[ - [experiment_service.PromoteExperimentRequest], - Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ExperimentServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/experiment_service/transports/grpc.py b/google/ads/googleads/v19/services/services/experiment_service/transports/grpc.py deleted file mode 100644 index 545fe14bd..000000000 --- a/google/ads/googleads/v19/services/services/experiment_service/transports/grpc.py +++ /dev/null @@ -1,599 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import operations_v1 -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import experiment_service -from google.longrunning import operations_pb2 # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from .base import ExperimentServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ExperimentService", - "rpcName": str(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.ads.googleads.v19.services.ExperimentService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ExperimentServiceGrpcTransport(ExperimentServiceTransport): - """gRPC backend transport for ExperimentService. - - Service to manage experiments. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[operations_v1.OperationsClient] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # 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._logged_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def mutate_experiments( - self, - ) -> Callable[ - [experiment_service.MutateExperimentsRequest], - experiment_service.MutateExperimentsResponse, - ]: - r"""Return a callable for the mutate experiments method over gRPC. - - Creates, updates, or removes experiments. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateExperimentsRequest], - ~.MutateExperimentsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_experiments" not in self._stubs: - self._stubs["mutate_experiments"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/MutateExperiments", - request_serializer=experiment_service.MutateExperimentsRequest.serialize, - response_deserializer=experiment_service.MutateExperimentsResponse.deserialize, - ) - ) - return self._stubs["mutate_experiments"] - - @property - def end_experiment( - self, - ) -> Callable[[experiment_service.EndExperimentRequest], empty_pb2.Empty]: - r"""Return a callable for the end experiment method over gRPC. - - Immediately ends an experiment, changing the experiment's - scheduled end date and without waiting for end of day. End date - is updated to be the time of the request. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.EndExperimentRequest], - ~.Empty]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "end_experiment" not in self._stubs: - self._stubs["end_experiment"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/EndExperiment", - request_serializer=experiment_service.EndExperimentRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - return self._stubs["end_experiment"] - - @property - def list_experiment_async_errors( - self, - ) -> Callable[ - [experiment_service.ListExperimentAsyncErrorsRequest], - experiment_service.ListExperimentAsyncErrorsResponse, - ]: - r"""Return a callable for the list experiment async errors method over gRPC. - - Returns all errors that occurred during the last Experiment - update (either scheduling or promotion). Supports standard list - paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListExperimentAsyncErrorsRequest], - ~.ListExperimentAsyncErrorsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_experiment_async_errors" not in self._stubs: - self._stubs["list_experiment_async_errors"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/ListExperimentAsyncErrors", - request_serializer=experiment_service.ListExperimentAsyncErrorsRequest.serialize, - response_deserializer=experiment_service.ListExperimentAsyncErrorsResponse.deserialize, - ) - ) - return self._stubs["list_experiment_async_errors"] - - @property - def graduate_experiment( - self, - ) -> Callable[ - [experiment_service.GraduateExperimentRequest], empty_pb2.Empty - ]: - r"""Return a callable for the graduate experiment method over gRPC. - - Graduates an experiment to a full campaign. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GraduateExperimentRequest], - ~.Empty]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "graduate_experiment" not in self._stubs: - self._stubs["graduate_experiment"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/GraduateExperiment", - request_serializer=experiment_service.GraduateExperimentRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - ) - return self._stubs["graduate_experiment"] - - @property - def schedule_experiment( - self, - ) -> Callable[ - [experiment_service.ScheduleExperimentRequest], operations_pb2.Operation - ]: - r"""Return a callable for the schedule experiment method over gRPC. - - Schedule an experiment. The in design campaign will be converted - into a real campaign (called the experiment campaign) that will - begin serving ads if successfully created. - - The experiment is scheduled immediately with status - INITIALIZING. This method returns a long running operation that - tracks the forking of the in design campaign. If the forking - fails, a list of errors can be retrieved using the - ListExperimentAsyncErrors method. The operation's metadata will - be a string containing the resource name of the created - experiment. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ScheduleExperimentRequest], - ~.Operation]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "schedule_experiment" not in self._stubs: - self._stubs["schedule_experiment"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/ScheduleExperiment", - request_serializer=experiment_service.ScheduleExperimentRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - ) - return self._stubs["schedule_experiment"] - - @property - def promote_experiment( - self, - ) -> Callable[ - [experiment_service.PromoteExperimentRequest], operations_pb2.Operation - ]: - r"""Return a callable for the promote experiment method over gRPC. - - Promotes the trial campaign thus applying changes in the trial - campaign to the base campaign. This method returns a long - running operation that tracks the promotion of the experiment - campaign. If it fails, a list of errors can be retrieved using - the ListExperimentAsyncErrors method. The operation's metadata - will be a string containing the resource name of the created - experiment. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.PromoteExperimentRequest], - ~.Operation]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "promote_experiment" not in self._stubs: - self._stubs["promote_experiment"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/PromoteExperiment", - request_serializer=experiment_service.PromoteExperimentRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - ) - return self._stubs["promote_experiment"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ExperimentServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/experiment_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/experiment_service/transports/grpc_asyncio.py deleted file mode 100644 index 8eccb9eb2..000000000 --- a/google/ads/googleads/v19/services/services/experiment_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,652 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.api_core import operations_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import experiment_service -from google.longrunning import operations_pb2 # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from .base import ExperimentServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ExperimentService", - "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.ads.googleads.v19.services.ExperimentService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ExperimentServiceGrpcAsyncIOTransport(ExperimentServiceTransport): - """gRPC AsyncIO backend transport for ExperimentService. - - Service to manage experiments. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[ - operations_v1.OperationsAsyncClient - ] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsAsyncClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # 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._logged_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def mutate_experiments( - self, - ) -> Callable[ - [experiment_service.MutateExperimentsRequest], - Awaitable[experiment_service.MutateExperimentsResponse], - ]: - r"""Return a callable for the mutate experiments method over gRPC. - - Creates, updates, or removes experiments. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateExperimentsRequest], - Awaitable[~.MutateExperimentsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_experiments" not in self._stubs: - self._stubs["mutate_experiments"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/MutateExperiments", - request_serializer=experiment_service.MutateExperimentsRequest.serialize, - response_deserializer=experiment_service.MutateExperimentsResponse.deserialize, - ) - ) - return self._stubs["mutate_experiments"] - - @property - def end_experiment( - self, - ) -> Callable[ - [experiment_service.EndExperimentRequest], Awaitable[empty_pb2.Empty] - ]: - r"""Return a callable for the end experiment method over gRPC. - - Immediately ends an experiment, changing the experiment's - scheduled end date and without waiting for end of day. End date - is updated to be the time of the request. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.EndExperimentRequest], - Awaitable[~.Empty]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "end_experiment" not in self._stubs: - self._stubs["end_experiment"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/EndExperiment", - request_serializer=experiment_service.EndExperimentRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - return self._stubs["end_experiment"] - - @property - def list_experiment_async_errors( - self, - ) -> Callable[ - [experiment_service.ListExperimentAsyncErrorsRequest], - Awaitable[experiment_service.ListExperimentAsyncErrorsResponse], - ]: - r"""Return a callable for the list experiment async errors method over gRPC. - - Returns all errors that occurred during the last Experiment - update (either scheduling or promotion). Supports standard list - paging. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListExperimentAsyncErrorsRequest], - Awaitable[~.ListExperimentAsyncErrorsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_experiment_async_errors" not in self._stubs: - self._stubs["list_experiment_async_errors"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/ListExperimentAsyncErrors", - request_serializer=experiment_service.ListExperimentAsyncErrorsRequest.serialize, - response_deserializer=experiment_service.ListExperimentAsyncErrorsResponse.deserialize, - ) - ) - return self._stubs["list_experiment_async_errors"] - - @property - def graduate_experiment( - self, - ) -> Callable[ - [experiment_service.GraduateExperimentRequest], - Awaitable[empty_pb2.Empty], - ]: - r"""Return a callable for the graduate experiment method over gRPC. - - Graduates an experiment to a full campaign. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GraduateExperimentRequest], - Awaitable[~.Empty]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "graduate_experiment" not in self._stubs: - self._stubs["graduate_experiment"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/GraduateExperiment", - request_serializer=experiment_service.GraduateExperimentRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - ) - return self._stubs["graduate_experiment"] - - @property - def schedule_experiment( - self, - ) -> Callable[ - [experiment_service.ScheduleExperimentRequest], - Awaitable[operations_pb2.Operation], - ]: - r"""Return a callable for the schedule experiment method over gRPC. - - Schedule an experiment. The in design campaign will be converted - into a real campaign (called the experiment campaign) that will - begin serving ads if successfully created. - - The experiment is scheduled immediately with status - INITIALIZING. This method returns a long running operation that - tracks the forking of the in design campaign. If the forking - fails, a list of errors can be retrieved using the - ListExperimentAsyncErrors method. The operation's metadata will - be a string containing the resource name of the created - experiment. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ScheduleExperimentRequest], - Awaitable[~.Operation]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "schedule_experiment" not in self._stubs: - self._stubs["schedule_experiment"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/ScheduleExperiment", - request_serializer=experiment_service.ScheduleExperimentRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - ) - return self._stubs["schedule_experiment"] - - @property - def promote_experiment( - self, - ) -> Callable[ - [experiment_service.PromoteExperimentRequest], - Awaitable[operations_pb2.Operation], - ]: - r"""Return a callable for the promote experiment method over gRPC. - - Promotes the trial campaign thus applying changes in the trial - campaign to the base campaign. This method returns a long - running operation that tracks the promotion of the experiment - campaign. If it fails, a list of errors can be retrieved using - the ListExperimentAsyncErrors method. The operation's metadata - will be a string containing the resource name of the created - experiment. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ExperimentError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.PromoteExperimentRequest], - Awaitable[~.Operation]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "promote_experiment" not in self._stubs: - self._stubs["promote_experiment"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ExperimentService/PromoteExperiment", - request_serializer=experiment_service.PromoteExperimentRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - ) - return self._stubs["promote_experiment"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_experiments: self._wrap_method( - self.mutate_experiments, - default_timeout=None, - client_info=client_info, - ), - self.end_experiment: self._wrap_method( - self.end_experiment, - default_timeout=None, - client_info=client_info, - ), - self.list_experiment_async_errors: self._wrap_method( - self.list_experiment_async_errors, - default_timeout=None, - client_info=client_info, - ), - self.graduate_experiment: self._wrap_method( - self.graduate_experiment, - default_timeout=None, - client_info=client_info, - ), - self.schedule_experiment: self._wrap_method( - self.schedule_experiment, - default_timeout=None, - client_info=client_info, - ), - self.promote_experiment: self._wrap_method( - self.promote_experiment, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ExperimentServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/geo_target_constant_service/async_client.py b/google/ads/googleads/v19/services/services/geo_target_constant_service/async_client.py deleted file mode 100644 index 6c682e4b2..000000000 --- a/google/ads/googleads/v19/services/services/geo_target_constant_service/async_client.py +++ /dev/null @@ -1,388 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import geo_target_constant_service -from .transports.base import ( - GeoTargetConstantServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import GeoTargetConstantServiceClient - -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 GeoTargetConstantServiceAsyncClient: - """Service to fetch geo target constants.""" - - _client: GeoTargetConstantServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = GeoTargetConstantServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = GeoTargetConstantServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - GeoTargetConstantServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = GeoTargetConstantServiceClient._DEFAULT_UNIVERSE - - geo_target_constant_path = staticmethod( - GeoTargetConstantServiceClient.geo_target_constant_path - ) - parse_geo_target_constant_path = staticmethod( - GeoTargetConstantServiceClient.parse_geo_target_constant_path - ) - common_billing_account_path = staticmethod( - GeoTargetConstantServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - GeoTargetConstantServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - GeoTargetConstantServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - GeoTargetConstantServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - GeoTargetConstantServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - GeoTargetConstantServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - GeoTargetConstantServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - GeoTargetConstantServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - GeoTargetConstantServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - GeoTargetConstantServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GeoTargetConstantServiceAsyncClient: The constructed client. - """ - return GeoTargetConstantServiceClient.from_service_account_info.__func__(GeoTargetConstantServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GeoTargetConstantServiceAsyncClient: The constructed client. - """ - return GeoTargetConstantServiceClient.from_service_account_file.__func__(GeoTargetConstantServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return GeoTargetConstantServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> GeoTargetConstantServiceTransport: - """Returns the transport used by the client instance. - - Returns: - GeoTargetConstantServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = GeoTargetConstantServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - GeoTargetConstantServiceTransport, - Callable[..., GeoTargetConstantServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the geo target constant service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,GeoTargetConstantServiceTransport,Callable[..., GeoTargetConstantServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the GeoTargetConstantServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = GeoTargetConstantServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.GeoTargetConstantServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.GeoTargetConstantService", - "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.ads.googleads.v19.services.GeoTargetConstantService", - "credentialsType": None, - } - ), - ) - - async def suggest_geo_target_constants( - self, - request: Optional[ - Union[ - geo_target_constant_service.SuggestGeoTargetConstantsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> geo_target_constant_service.SuggestGeoTargetConstantsResponse: - r"""Returns GeoTargetConstant suggestions by location name or by - resource name. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `GeoTargetConstantSuggestionError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.SuggestGeoTargetConstantsRequest, dict]]): - The request object. Request message for - [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v19.services.GeoTargetConstantService.SuggestGeoTargetConstants]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestGeoTargetConstantsResponse: - Response message for - [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v19.services.GeoTargetConstantService.SuggestGeoTargetConstants]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - geo_target_constant_service.SuggestGeoTargetConstantsRequest, - ): - request = ( - geo_target_constant_service.SuggestGeoTargetConstantsRequest( - request - ) - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.suggest_geo_target_constants - ] - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "GeoTargetConstantServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("GeoTargetConstantServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/geo_target_constant_service/client.py b/google/ads/googleads/v19/services/services/geo_target_constant_service/client.py deleted file mode 100644 index 3f00cd85e..000000000 --- a/google/ads/googleads/v19/services/services/geo_target_constant_service/client.py +++ /dev/null @@ -1,832 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import geo_target_constant_service -from .transports.base import ( - GeoTargetConstantServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import GeoTargetConstantServiceGrpcTransport -from .transports.grpc_asyncio import ( - GeoTargetConstantServiceGrpcAsyncIOTransport, -) - - -class GeoTargetConstantServiceClientMeta(type): - """Metaclass for the GeoTargetConstantService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[GeoTargetConstantServiceTransport]] - _transport_registry["grpc"] = GeoTargetConstantServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - GeoTargetConstantServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[GeoTargetConstantServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class GeoTargetConstantServiceClient( - metaclass=GeoTargetConstantServiceClientMeta -): - """Service to fetch geo target constants.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GeoTargetConstantServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GeoTargetConstantServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> GeoTargetConstantServiceTransport: - """Returns the transport used by the client instance. - - Returns: - GeoTargetConstantServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def geo_target_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified geo_target_constant string.""" - return "geoTargetConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_geo_target_constant_path(path: str) -> Dict[str, str]: - """Parses a geo_target_constant path into its component segments.""" - m = re.match(r"^geoTargetConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = GeoTargetConstantServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = GeoTargetConstantServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = GeoTargetConstantServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = GeoTargetConstantServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - GeoTargetConstantServiceTransport, - Callable[..., GeoTargetConstantServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the geo target constant service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,GeoTargetConstantServiceTransport,Callable[..., GeoTargetConstantServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the GeoTargetConstantServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = GeoTargetConstantServiceClient._read_environment_variables() - self._client_cert_source = ( - GeoTargetConstantServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - GeoTargetConstantServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, GeoTargetConstantServiceTransport - ) - if transport_provided: - # transport is a GeoTargetConstantServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(GeoTargetConstantServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or GeoTargetConstantServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[GeoTargetConstantServiceTransport], - Callable[..., GeoTargetConstantServiceTransport], - ] = ( - GeoTargetConstantServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., GeoTargetConstantServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.GeoTargetConstantServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.GeoTargetConstantService", - "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.ads.googleads.v19.services.GeoTargetConstantService", - "credentialsType": None, - } - ), - ) - - def suggest_geo_target_constants( - self, - request: Optional[ - Union[ - geo_target_constant_service.SuggestGeoTargetConstantsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> geo_target_constant_service.SuggestGeoTargetConstantsResponse: - r"""Returns GeoTargetConstant suggestions by location name or by - resource name. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `GeoTargetConstantSuggestionError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.SuggestGeoTargetConstantsRequest, dict]): - The request object. Request message for - [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v19.services.GeoTargetConstantService.SuggestGeoTargetConstants]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestGeoTargetConstantsResponse: - Response message for - [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v19.services.GeoTargetConstantService.SuggestGeoTargetConstants]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - geo_target_constant_service.SuggestGeoTargetConstantsRequest, - ): - request = ( - geo_target_constant_service.SuggestGeoTargetConstantsRequest( - request - ) - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.suggest_geo_target_constants - ] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "GeoTargetConstantServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("GeoTargetConstantServiceClient",) diff --git a/google/ads/googleads/v19/services/services/geo_target_constant_service/transports/base.py b/google/ads/googleads/v19/services/services/geo_target_constant_service/transports/base.py deleted file mode 100644 index f68912352..000000000 --- a/google/ads/googleads/v19/services/services/geo_target_constant_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import geo_target_constant_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class GeoTargetConstantServiceTransport(abc.ABC): - """Abstract transport class for GeoTargetConstantService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.suggest_geo_target_constants: gapic_v1.method.wrap_method( - self.suggest_geo_target_constants, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def suggest_geo_target_constants( - self, - ) -> Callable[ - [geo_target_constant_service.SuggestGeoTargetConstantsRequest], - Union[ - geo_target_constant_service.SuggestGeoTargetConstantsResponse, - Awaitable[ - geo_target_constant_service.SuggestGeoTargetConstantsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("GeoTargetConstantServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/geo_target_constant_service/transports/grpc.py b/google/ads/googleads/v19/services/services/geo_target_constant_service/transports/grpc.py deleted file mode 100644 index cbcb49c59..000000000 --- a/google/ads/googleads/v19/services/services/geo_target_constant_service/transports/grpc.py +++ /dev/null @@ -1,387 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import geo_target_constant_service -from .base import GeoTargetConstantServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.GeoTargetConstantService", - "rpcName": str(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.ads.googleads.v19.services.GeoTargetConstantService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class GeoTargetConstantServiceGrpcTransport(GeoTargetConstantServiceTransport): - """gRPC backend transport for GeoTargetConstantService. - - Service to fetch geo target constants. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def suggest_geo_target_constants( - self, - ) -> Callable[ - [geo_target_constant_service.SuggestGeoTargetConstantsRequest], - geo_target_constant_service.SuggestGeoTargetConstantsResponse, - ]: - r"""Return a callable for the suggest geo target constants method over gRPC. - - Returns GeoTargetConstant suggestions by location name or by - resource name. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `GeoTargetConstantSuggestionError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.SuggestGeoTargetConstantsRequest], - ~.SuggestGeoTargetConstantsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_geo_target_constants" not in self._stubs: - self._stubs["suggest_geo_target_constants"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.GeoTargetConstantService/SuggestGeoTargetConstants", - request_serializer=geo_target_constant_service.SuggestGeoTargetConstantsRequest.serialize, - response_deserializer=geo_target_constant_service.SuggestGeoTargetConstantsResponse.deserialize, - ) - ) - return self._stubs["suggest_geo_target_constants"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("GeoTargetConstantServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/geo_target_constant_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/geo_target_constant_service/transports/grpc_asyncio.py deleted file mode 100644 index b0f4defeb..000000000 --- a/google/ads/googleads/v19/services/services/geo_target_constant_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,412 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import geo_target_constant_service -from .base import GeoTargetConstantServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.GeoTargetConstantService", - "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.ads.googleads.v19.services.GeoTargetConstantService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class GeoTargetConstantServiceGrpcAsyncIOTransport( - GeoTargetConstantServiceTransport -): - """gRPC AsyncIO backend transport for GeoTargetConstantService. - - Service to fetch geo target constants. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def suggest_geo_target_constants( - self, - ) -> Callable[ - [geo_target_constant_service.SuggestGeoTargetConstantsRequest], - Awaitable[ - geo_target_constant_service.SuggestGeoTargetConstantsResponse - ], - ]: - r"""Return a callable for the suggest geo target constants method over gRPC. - - Returns GeoTargetConstant suggestions by location name or by - resource name. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ - `GeoTargetConstantSuggestionError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.SuggestGeoTargetConstantsRequest], - Awaitable[~.SuggestGeoTargetConstantsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_geo_target_constants" not in self._stubs: - self._stubs["suggest_geo_target_constants"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.GeoTargetConstantService/SuggestGeoTargetConstants", - request_serializer=geo_target_constant_service.SuggestGeoTargetConstantsRequest.serialize, - response_deserializer=geo_target_constant_service.SuggestGeoTargetConstantsResponse.deserialize, - ) - ) - return self._stubs["suggest_geo_target_constants"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.suggest_geo_target_constants: self._wrap_method( - self.suggest_geo_target_constants, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("GeoTargetConstantServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/google_ads_field_service/async_client.py b/google/ads/googleads/v19/services/services/google_ads_field_service/async_client.py deleted file mode 100644 index c062a774a..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_field_service/async_client.py +++ /dev/null @@ -1,514 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.resources.types import google_ads_field -from google.ads.googleads.v19.services.services.google_ads_field_service import ( - pagers, -) -from google.ads.googleads.v19.services.types import google_ads_field_service -from .transports.base import GoogleAdsFieldServiceTransport, DEFAULT_CLIENT_INFO -from .client import GoogleAdsFieldServiceClient - -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 GoogleAdsFieldServiceAsyncClient: - """Service to fetch Google Ads API fields.""" - - _client: GoogleAdsFieldServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = GoogleAdsFieldServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = GoogleAdsFieldServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - GoogleAdsFieldServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = GoogleAdsFieldServiceClient._DEFAULT_UNIVERSE - - google_ads_field_path = staticmethod( - GoogleAdsFieldServiceClient.google_ads_field_path - ) - parse_google_ads_field_path = staticmethod( - GoogleAdsFieldServiceClient.parse_google_ads_field_path - ) - common_billing_account_path = staticmethod( - GoogleAdsFieldServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - GoogleAdsFieldServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - GoogleAdsFieldServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - GoogleAdsFieldServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - GoogleAdsFieldServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - GoogleAdsFieldServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - GoogleAdsFieldServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - GoogleAdsFieldServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - GoogleAdsFieldServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - GoogleAdsFieldServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GoogleAdsFieldServiceAsyncClient: The constructed client. - """ - return GoogleAdsFieldServiceClient.from_service_account_info.__func__(GoogleAdsFieldServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GoogleAdsFieldServiceAsyncClient: The constructed client. - """ - return GoogleAdsFieldServiceClient.from_service_account_file.__func__(GoogleAdsFieldServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return GoogleAdsFieldServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> GoogleAdsFieldServiceTransport: - """Returns the transport used by the client instance. - - Returns: - GoogleAdsFieldServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = GoogleAdsFieldServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - GoogleAdsFieldServiceTransport, - Callable[..., GoogleAdsFieldServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the google ads field service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,GoogleAdsFieldServiceTransport,Callable[..., GoogleAdsFieldServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the GoogleAdsFieldServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = GoogleAdsFieldServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.GoogleAdsFieldServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.GoogleAdsFieldService", - "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.ads.googleads.v19.services.GoogleAdsFieldService", - "credentialsType": None, - } - ), - ) - - async def get_google_ads_field( - self, - request: Optional[ - Union[google_ads_field_service.GetGoogleAdsFieldRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> google_ads_field.GoogleAdsField: - r"""Returns just the requested field. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GetGoogleAdsFieldRequest, dict]]): - The request object. Request message for - [GoogleAdsFieldService.GetGoogleAdsField][google.ads.googleads.v19.services.GoogleAdsFieldService.GetGoogleAdsField]. - resource_name (:class:`str`): - Required. The resource name of the - field to get. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.resources.types.GoogleAdsField: - A field or resource (artifact) used - by GoogleAdsService. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, google_ads_field_service.GetGoogleAdsFieldRequest - ): - request = google_ads_field_service.GetGoogleAdsFieldRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.get_google_ads_field - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def search_google_ads_fields( - self, - request: Optional[ - Union[google_ads_field_service.SearchGoogleAdsFieldsRequest, dict] - ] = None, - *, - query: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.SearchGoogleAdsFieldsAsyncPager: - r"""Returns all fields that match the search query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QueryError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.SearchGoogleAdsFieldsRequest, dict]]): - The request object. Request message for - [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v19.services.GoogleAdsFieldService.SearchGoogleAdsFields]. - query (:class:`str`): - Required. The query string. - This corresponds to the ``query`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.google_ads_field_service.pagers.SearchGoogleAdsFieldsAsyncPager: - Response message for - [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v19.services.GoogleAdsFieldService.SearchGoogleAdsFields]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [query] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, google_ads_field_service.SearchGoogleAdsFieldsRequest - ): - request = google_ads_field_service.SearchGoogleAdsFieldsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if query is not None: - request.query = query - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.search_google_ads_fields - ] - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.SearchGoogleAdsFieldsAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "GoogleAdsFieldServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("GoogleAdsFieldServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/google_ads_field_service/client.py b/google/ads/googleads/v19/services/services/google_ads_field_service/client.py deleted file mode 100644 index d4e230eeb..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_field_service/client.py +++ /dev/null @@ -1,954 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.resources.types import google_ads_field -from google.ads.googleads.v19.services.services.google_ads_field_service import ( - pagers, -) -from google.ads.googleads.v19.services.types import google_ads_field_service -from .transports.base import GoogleAdsFieldServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import GoogleAdsFieldServiceGrpcTransport -from .transports.grpc_asyncio import GoogleAdsFieldServiceGrpcAsyncIOTransport - - -class GoogleAdsFieldServiceClientMeta(type): - """Metaclass for the GoogleAdsFieldService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[GoogleAdsFieldServiceTransport]] - _transport_registry["grpc"] = GoogleAdsFieldServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - GoogleAdsFieldServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[GoogleAdsFieldServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class GoogleAdsFieldServiceClient(metaclass=GoogleAdsFieldServiceClientMeta): - """Service to fetch Google Ads API fields.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GoogleAdsFieldServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GoogleAdsFieldServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> GoogleAdsFieldServiceTransport: - """Returns the transport used by the client instance. - - Returns: - GoogleAdsFieldServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def google_ads_field_path( - google_ads_field: str, - ) -> str: - """Returns a fully-qualified google_ads_field string.""" - return "googleAdsFields/{google_ads_field}".format( - google_ads_field=google_ads_field, - ) - - @staticmethod - def parse_google_ads_field_path(path: str) -> Dict[str, str]: - """Parses a google_ads_field path into its component segments.""" - m = re.match(r"^googleAdsFields/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = GoogleAdsFieldServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = GoogleAdsFieldServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - GoogleAdsFieldServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = GoogleAdsFieldServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - GoogleAdsFieldServiceTransport, - Callable[..., GoogleAdsFieldServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the google ads field service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,GoogleAdsFieldServiceTransport,Callable[..., GoogleAdsFieldServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the GoogleAdsFieldServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = GoogleAdsFieldServiceClient._read_environment_variables() - self._client_cert_source = ( - GoogleAdsFieldServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - GoogleAdsFieldServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, GoogleAdsFieldServiceTransport - ) - if transport_provided: - # transport is a GoogleAdsFieldServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(GoogleAdsFieldServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or GoogleAdsFieldServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[GoogleAdsFieldServiceTransport], - Callable[..., GoogleAdsFieldServiceTransport], - ] = ( - GoogleAdsFieldServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., GoogleAdsFieldServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.GoogleAdsFieldServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.GoogleAdsFieldService", - "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.ads.googleads.v19.services.GoogleAdsFieldService", - "credentialsType": None, - } - ), - ) - - def get_google_ads_field( - self, - request: Optional[ - Union[google_ads_field_service.GetGoogleAdsFieldRequest, dict] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> google_ads_field.GoogleAdsField: - r"""Returns just the requested field. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GetGoogleAdsFieldRequest, dict]): - The request object. Request message for - [GoogleAdsFieldService.GetGoogleAdsField][google.ads.googleads.v19.services.GoogleAdsFieldService.GetGoogleAdsField]. - resource_name (str): - Required. The resource name of the - field to get. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.resources.types.GoogleAdsField: - A field or resource (artifact) used - by GoogleAdsService. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, google_ads_field_service.GetGoogleAdsFieldRequest - ): - request = google_ads_field_service.GetGoogleAdsFieldRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.get_google_ads_field - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def search_google_ads_fields( - self, - request: Optional[ - Union[google_ads_field_service.SearchGoogleAdsFieldsRequest, dict] - ] = None, - *, - query: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.SearchGoogleAdsFieldsPager: - r"""Returns all fields that match the search query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QueryError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.SearchGoogleAdsFieldsRequest, dict]): - The request object. Request message for - [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v19.services.GoogleAdsFieldService.SearchGoogleAdsFields]. - query (str): - Required. The query string. - This corresponds to the ``query`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.google_ads_field_service.pagers.SearchGoogleAdsFieldsPager: - Response message for - [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v19.services.GoogleAdsFieldService.SearchGoogleAdsFields]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [query] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, google_ads_field_service.SearchGoogleAdsFieldsRequest - ): - request = google_ads_field_service.SearchGoogleAdsFieldsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if query is not None: - request.query = query - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.search_google_ads_fields - ] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.SearchGoogleAdsFieldsPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "GoogleAdsFieldServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("GoogleAdsFieldServiceClient",) diff --git a/google/ads/googleads/v19/services/services/google_ads_field_service/pagers.py b/google/ads/googleads/v19/services/services/google_ads_field_service/pagers.py deleted file mode 100644 index f0059daf8..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_field_service/pagers.py +++ /dev/null @@ -1,209 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import retry_async as retries_async -from typing import ( - Any, - AsyncIterator, - Awaitable, - Callable, - Sequence, - Tuple, - Iterator, - Union, -) - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] - OptionalAsyncRetry = Union[ - retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.resources.types import google_ads_field -from google.ads.googleads.v19.services.types import google_ads_field_service - - -class SearchGoogleAdsFieldsPager: - """A pager for iterating through ``search_google_ads_fields`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.SearchGoogleAdsFieldsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``results`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``SearchGoogleAdsFields`` requests and continue to iterate - through the ``results`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.SearchGoogleAdsFieldsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[ - ..., google_ads_field_service.SearchGoogleAdsFieldsResponse - ], - request: google_ads_field_service.SearchGoogleAdsFieldsRequest, - response: google_ads_field_service.SearchGoogleAdsFieldsResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.SearchGoogleAdsFieldsRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.SearchGoogleAdsFieldsResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = google_ads_field_service.SearchGoogleAdsFieldsRequest( - request - ) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages( - self, - ) -> Iterator[google_ads_field_service.SearchGoogleAdsFieldsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __iter__(self) -> Iterator[google_ads_field.GoogleAdsField]: - for page in self.pages: - yield from page.results - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) - - -class SearchGoogleAdsFieldsAsyncPager: - """A pager for iterating through ``search_google_ads_fields`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.SearchGoogleAdsFieldsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``results`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``SearchGoogleAdsFields`` requests and continue to iterate - through the ``results`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.SearchGoogleAdsFieldsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[ - ..., - Awaitable[google_ads_field_service.SearchGoogleAdsFieldsResponse], - ], - request: google_ads_field_service.SearchGoogleAdsFieldsRequest, - response: google_ads_field_service.SearchGoogleAdsFieldsResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.SearchGoogleAdsFieldsRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.SearchGoogleAdsFieldsResponse): - The initial response object. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = google_ads_field_service.SearchGoogleAdsFieldsRequest( - request - ) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages( - self, - ) -> AsyncIterator[google_ads_field_service.SearchGoogleAdsFieldsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __aiter__(self) -> AsyncIterator[google_ads_field.GoogleAdsField]: - async def async_generator(): - async for page in self.pages: - for response in page.results: - yield response - - return async_generator() - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/google_ads_field_service/transports/base.py b/google/ads/googleads/v19/services/services/google_ads_field_service/transports/base.py deleted file mode 100644 index f9a0ab729..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_field_service/transports/base.py +++ /dev/null @@ -1,190 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.resources.types import google_ads_field -from google.ads.googleads.v19.services.types import google_ads_field_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class GoogleAdsFieldServiceTransport(abc.ABC): - """Abstract transport class for GoogleAdsFieldService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.get_google_ads_field: gapic_v1.method.wrap_method( - self.get_google_ads_field, - default_timeout=None, - client_info=client_info, - ), - self.search_google_ads_fields: gapic_v1.method.wrap_method( - self.search_google_ads_fields, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def get_google_ads_field( - self, - ) -> Callable[ - [google_ads_field_service.GetGoogleAdsFieldRequest], - Union[ - google_ads_field.GoogleAdsField, - Awaitable[google_ads_field.GoogleAdsField], - ], - ]: - raise NotImplementedError() - - @property - def search_google_ads_fields( - self, - ) -> Callable[ - [google_ads_field_service.SearchGoogleAdsFieldsRequest], - Union[ - google_ads_field_service.SearchGoogleAdsFieldsResponse, - Awaitable[google_ads_field_service.SearchGoogleAdsFieldsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("GoogleAdsFieldServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/google_ads_field_service/transports/grpc.py b/google/ads/googleads/v19/services/services/google_ads_field_service/transports/grpc.py deleted file mode 100644 index 4da8616f4..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_field_service/transports/grpc.py +++ /dev/null @@ -1,422 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.resources.types import google_ads_field -from google.ads.googleads.v19.services.types import google_ads_field_service -from .base import GoogleAdsFieldServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.GoogleAdsFieldService", - "rpcName": str(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.ads.googleads.v19.services.GoogleAdsFieldService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class GoogleAdsFieldServiceGrpcTransport(GoogleAdsFieldServiceTransport): - """gRPC backend transport for GoogleAdsFieldService. - - Service to fetch Google Ads API fields. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def get_google_ads_field( - self, - ) -> Callable[ - [google_ads_field_service.GetGoogleAdsFieldRequest], - google_ads_field.GoogleAdsField, - ]: - r"""Return a callable for the get google ads field method over gRPC. - - Returns just the requested field. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GetGoogleAdsFieldRequest], - ~.GoogleAdsField]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_google_ads_field" not in self._stubs: - self._stubs["get_google_ads_field"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.GoogleAdsFieldService/GetGoogleAdsField", - request_serializer=google_ads_field_service.GetGoogleAdsFieldRequest.serialize, - response_deserializer=google_ads_field.GoogleAdsField.deserialize, - ) - ) - return self._stubs["get_google_ads_field"] - - @property - def search_google_ads_fields( - self, - ) -> Callable[ - [google_ads_field_service.SearchGoogleAdsFieldsRequest], - google_ads_field_service.SearchGoogleAdsFieldsResponse, - ]: - r"""Return a callable for the search google ads fields method over gRPC. - - Returns all fields that match the search query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QueryError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.SearchGoogleAdsFieldsRequest], - ~.SearchGoogleAdsFieldsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "search_google_ads_fields" not in self._stubs: - self._stubs["search_google_ads_fields"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.GoogleAdsFieldService/SearchGoogleAdsFields", - request_serializer=google_ads_field_service.SearchGoogleAdsFieldsRequest.serialize, - response_deserializer=google_ads_field_service.SearchGoogleAdsFieldsResponse.deserialize, - ) - ) - return self._stubs["search_google_ads_fields"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("GoogleAdsFieldServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/google_ads_field_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/google_ads_field_service/transports/grpc_asyncio.py deleted file mode 100644 index dc80e44d0..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_field_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,448 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.resources.types import google_ads_field -from google.ads.googleads.v19.services.types import google_ads_field_service -from .base import GoogleAdsFieldServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.GoogleAdsFieldService", - "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.ads.googleads.v19.services.GoogleAdsFieldService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class GoogleAdsFieldServiceGrpcAsyncIOTransport(GoogleAdsFieldServiceTransport): - """gRPC AsyncIO backend transport for GoogleAdsFieldService. - - Service to fetch Google Ads API fields. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def get_google_ads_field( - self, - ) -> Callable[ - [google_ads_field_service.GetGoogleAdsFieldRequest], - Awaitable[google_ads_field.GoogleAdsField], - ]: - r"""Return a callable for the get google ads field method over gRPC. - - Returns just the requested field. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GetGoogleAdsFieldRequest], - Awaitable[~.GoogleAdsField]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_google_ads_field" not in self._stubs: - self._stubs["get_google_ads_field"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.GoogleAdsFieldService/GetGoogleAdsField", - request_serializer=google_ads_field_service.GetGoogleAdsFieldRequest.serialize, - response_deserializer=google_ads_field.GoogleAdsField.deserialize, - ) - ) - return self._stubs["get_google_ads_field"] - - @property - def search_google_ads_fields( - self, - ) -> Callable[ - [google_ads_field_service.SearchGoogleAdsFieldsRequest], - Awaitable[google_ads_field_service.SearchGoogleAdsFieldsResponse], - ]: - r"""Return a callable for the search google ads fields method over gRPC. - - Returns all fields that match the search query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QueryError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.SearchGoogleAdsFieldsRequest], - Awaitable[~.SearchGoogleAdsFieldsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "search_google_ads_fields" not in self._stubs: - self._stubs["search_google_ads_fields"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.GoogleAdsFieldService/SearchGoogleAdsFields", - request_serializer=google_ads_field_service.SearchGoogleAdsFieldsRequest.serialize, - response_deserializer=google_ads_field_service.SearchGoogleAdsFieldsResponse.deserialize, - ) - ) - return self._stubs["search_google_ads_fields"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.get_google_ads_field: self._wrap_method( - self.get_google_ads_field, - default_timeout=None, - client_info=client_info, - ), - self.search_google_ads_fields: self._wrap_method( - self.search_google_ads_fields, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("GoogleAdsFieldServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/google_ads_service/async_client.py b/google/ads/googleads/v19/services/services/google_ads_service/async_client.py deleted file mode 100644 index 198e09851..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_service/async_client.py +++ /dev/null @@ -1,1660 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import ( - Callable, - MutableSequence, - Optional, - AsyncIterable, - Awaitable, - Sequence, - Tuple, - Union, -) - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.services.google_ads_service import pagers -from google.ads.googleads.v19.services.types import google_ads_service -from google.protobuf import field_mask_pb2 # type: ignore -from google.rpc import status_pb2 # type: ignore -from .transports.base import GoogleAdsServiceTransport, DEFAULT_CLIENT_INFO -from .client import GoogleAdsServiceClient - -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 GoogleAdsServiceAsyncClient: - """Service to fetch data and metrics across resources.""" - - _client: GoogleAdsServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = GoogleAdsServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = GoogleAdsServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - GoogleAdsServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = GoogleAdsServiceClient._DEFAULT_UNIVERSE - - accessible_bidding_strategy_path = staticmethod( - GoogleAdsServiceClient.accessible_bidding_strategy_path - ) - parse_accessible_bidding_strategy_path = staticmethod( - GoogleAdsServiceClient.parse_accessible_bidding_strategy_path - ) - account_budget_path = staticmethod( - GoogleAdsServiceClient.account_budget_path - ) - parse_account_budget_path = staticmethod( - GoogleAdsServiceClient.parse_account_budget_path - ) - account_budget_proposal_path = staticmethod( - GoogleAdsServiceClient.account_budget_proposal_path - ) - parse_account_budget_proposal_path = staticmethod( - GoogleAdsServiceClient.parse_account_budget_proposal_path - ) - account_link_path = staticmethod(GoogleAdsServiceClient.account_link_path) - parse_account_link_path = staticmethod( - GoogleAdsServiceClient.parse_account_link_path - ) - ad_path = staticmethod(GoogleAdsServiceClient.ad_path) - parse_ad_path = staticmethod(GoogleAdsServiceClient.parse_ad_path) - ad_group_path = staticmethod(GoogleAdsServiceClient.ad_group_path) - parse_ad_group_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_path - ) - ad_group_ad_path = staticmethod(GoogleAdsServiceClient.ad_group_ad_path) - parse_ad_group_ad_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_ad_path - ) - ad_group_ad_asset_combination_view_path = staticmethod( - GoogleAdsServiceClient.ad_group_ad_asset_combination_view_path - ) - parse_ad_group_ad_asset_combination_view_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_ad_asset_combination_view_path - ) - ad_group_ad_asset_view_path = staticmethod( - GoogleAdsServiceClient.ad_group_ad_asset_view_path - ) - parse_ad_group_ad_asset_view_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_ad_asset_view_path - ) - ad_group_ad_label_path = staticmethod( - GoogleAdsServiceClient.ad_group_ad_label_path - ) - parse_ad_group_ad_label_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_ad_label_path - ) - ad_group_asset_path = staticmethod( - GoogleAdsServiceClient.ad_group_asset_path - ) - parse_ad_group_asset_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_asset_path - ) - ad_group_asset_set_path = staticmethod( - GoogleAdsServiceClient.ad_group_asset_set_path - ) - parse_ad_group_asset_set_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_asset_set_path - ) - ad_group_audience_view_path = staticmethod( - GoogleAdsServiceClient.ad_group_audience_view_path - ) - parse_ad_group_audience_view_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_audience_view_path - ) - ad_group_bid_modifier_path = staticmethod( - GoogleAdsServiceClient.ad_group_bid_modifier_path - ) - parse_ad_group_bid_modifier_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_bid_modifier_path - ) - ad_group_criterion_path = staticmethod( - GoogleAdsServiceClient.ad_group_criterion_path - ) - parse_ad_group_criterion_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_criterion_path - ) - ad_group_criterion_customizer_path = staticmethod( - GoogleAdsServiceClient.ad_group_criterion_customizer_path - ) - parse_ad_group_criterion_customizer_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_criterion_customizer_path - ) - ad_group_criterion_label_path = staticmethod( - GoogleAdsServiceClient.ad_group_criterion_label_path - ) - parse_ad_group_criterion_label_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_criterion_label_path - ) - ad_group_criterion_simulation_path = staticmethod( - GoogleAdsServiceClient.ad_group_criterion_simulation_path - ) - parse_ad_group_criterion_simulation_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_criterion_simulation_path - ) - ad_group_customizer_path = staticmethod( - GoogleAdsServiceClient.ad_group_customizer_path - ) - parse_ad_group_customizer_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_customizer_path - ) - ad_group_label_path = staticmethod( - GoogleAdsServiceClient.ad_group_label_path - ) - parse_ad_group_label_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_label_path - ) - ad_group_simulation_path = staticmethod( - GoogleAdsServiceClient.ad_group_simulation_path - ) - parse_ad_group_simulation_path = staticmethod( - GoogleAdsServiceClient.parse_ad_group_simulation_path - ) - ad_parameter_path = staticmethod(GoogleAdsServiceClient.ad_parameter_path) - parse_ad_parameter_path = staticmethod( - GoogleAdsServiceClient.parse_ad_parameter_path - ) - ad_schedule_view_path = staticmethod( - GoogleAdsServiceClient.ad_schedule_view_path - ) - parse_ad_schedule_view_path = staticmethod( - GoogleAdsServiceClient.parse_ad_schedule_view_path - ) - age_range_view_path = staticmethod( - GoogleAdsServiceClient.age_range_view_path - ) - parse_age_range_view_path = staticmethod( - GoogleAdsServiceClient.parse_age_range_view_path - ) - android_privacy_shared_key_google_ad_group_path = staticmethod( - GoogleAdsServiceClient.android_privacy_shared_key_google_ad_group_path - ) - parse_android_privacy_shared_key_google_ad_group_path = staticmethod( - GoogleAdsServiceClient.parse_android_privacy_shared_key_google_ad_group_path - ) - android_privacy_shared_key_google_campaign_path = staticmethod( - GoogleAdsServiceClient.android_privacy_shared_key_google_campaign_path - ) - parse_android_privacy_shared_key_google_campaign_path = staticmethod( - GoogleAdsServiceClient.parse_android_privacy_shared_key_google_campaign_path - ) - android_privacy_shared_key_google_network_type_path = staticmethod( - GoogleAdsServiceClient.android_privacy_shared_key_google_network_type_path - ) - parse_android_privacy_shared_key_google_network_type_path = staticmethod( - GoogleAdsServiceClient.parse_android_privacy_shared_key_google_network_type_path - ) - asset_path = staticmethod(GoogleAdsServiceClient.asset_path) - parse_asset_path = staticmethod(GoogleAdsServiceClient.parse_asset_path) - asset_field_type_view_path = staticmethod( - GoogleAdsServiceClient.asset_field_type_view_path - ) - parse_asset_field_type_view_path = staticmethod( - GoogleAdsServiceClient.parse_asset_field_type_view_path - ) - asset_group_path = staticmethod(GoogleAdsServiceClient.asset_group_path) - parse_asset_group_path = staticmethod( - GoogleAdsServiceClient.parse_asset_group_path - ) - asset_group_asset_path = staticmethod( - GoogleAdsServiceClient.asset_group_asset_path - ) - parse_asset_group_asset_path = staticmethod( - GoogleAdsServiceClient.parse_asset_group_asset_path - ) - asset_group_listing_group_filter_path = staticmethod( - GoogleAdsServiceClient.asset_group_listing_group_filter_path - ) - parse_asset_group_listing_group_filter_path = staticmethod( - GoogleAdsServiceClient.parse_asset_group_listing_group_filter_path - ) - asset_group_product_group_view_path = staticmethod( - GoogleAdsServiceClient.asset_group_product_group_view_path - ) - parse_asset_group_product_group_view_path = staticmethod( - GoogleAdsServiceClient.parse_asset_group_product_group_view_path - ) - asset_group_signal_path = staticmethod( - GoogleAdsServiceClient.asset_group_signal_path - ) - parse_asset_group_signal_path = staticmethod( - GoogleAdsServiceClient.parse_asset_group_signal_path - ) - asset_group_top_combination_view_path = staticmethod( - GoogleAdsServiceClient.asset_group_top_combination_view_path - ) - parse_asset_group_top_combination_view_path = staticmethod( - GoogleAdsServiceClient.parse_asset_group_top_combination_view_path - ) - asset_set_path = staticmethod(GoogleAdsServiceClient.asset_set_path) - parse_asset_set_path = staticmethod( - GoogleAdsServiceClient.parse_asset_set_path - ) - asset_set_asset_path = staticmethod( - GoogleAdsServiceClient.asset_set_asset_path - ) - parse_asset_set_asset_path = staticmethod( - GoogleAdsServiceClient.parse_asset_set_asset_path - ) - asset_set_type_view_path = staticmethod( - GoogleAdsServiceClient.asset_set_type_view_path - ) - parse_asset_set_type_view_path = staticmethod( - GoogleAdsServiceClient.parse_asset_set_type_view_path - ) - audience_path = staticmethod(GoogleAdsServiceClient.audience_path) - parse_audience_path = staticmethod( - GoogleAdsServiceClient.parse_audience_path - ) - batch_job_path = staticmethod(GoogleAdsServiceClient.batch_job_path) - parse_batch_job_path = staticmethod( - GoogleAdsServiceClient.parse_batch_job_path - ) - bidding_data_exclusion_path = staticmethod( - GoogleAdsServiceClient.bidding_data_exclusion_path - ) - parse_bidding_data_exclusion_path = staticmethod( - GoogleAdsServiceClient.parse_bidding_data_exclusion_path - ) - bidding_seasonality_adjustment_path = staticmethod( - GoogleAdsServiceClient.bidding_seasonality_adjustment_path - ) - parse_bidding_seasonality_adjustment_path = staticmethod( - GoogleAdsServiceClient.parse_bidding_seasonality_adjustment_path - ) - bidding_strategy_path = staticmethod( - GoogleAdsServiceClient.bidding_strategy_path - ) - parse_bidding_strategy_path = staticmethod( - GoogleAdsServiceClient.parse_bidding_strategy_path - ) - bidding_strategy_simulation_path = staticmethod( - GoogleAdsServiceClient.bidding_strategy_simulation_path - ) - parse_bidding_strategy_simulation_path = staticmethod( - GoogleAdsServiceClient.parse_bidding_strategy_simulation_path - ) - billing_setup_path = staticmethod(GoogleAdsServiceClient.billing_setup_path) - parse_billing_setup_path = staticmethod( - GoogleAdsServiceClient.parse_billing_setup_path - ) - call_view_path = staticmethod(GoogleAdsServiceClient.call_view_path) - parse_call_view_path = staticmethod( - GoogleAdsServiceClient.parse_call_view_path - ) - campaign_path = staticmethod(GoogleAdsServiceClient.campaign_path) - parse_campaign_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_path - ) - campaign_aggregate_asset_view_path = staticmethod( - GoogleAdsServiceClient.campaign_aggregate_asset_view_path - ) - parse_campaign_aggregate_asset_view_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_aggregate_asset_view_path - ) - campaign_asset_path = staticmethod( - GoogleAdsServiceClient.campaign_asset_path - ) - parse_campaign_asset_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_asset_path - ) - campaign_asset_set_path = staticmethod( - GoogleAdsServiceClient.campaign_asset_set_path - ) - parse_campaign_asset_set_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_asset_set_path - ) - campaign_audience_view_path = staticmethod( - GoogleAdsServiceClient.campaign_audience_view_path - ) - parse_campaign_audience_view_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_audience_view_path - ) - campaign_bid_modifier_path = staticmethod( - GoogleAdsServiceClient.campaign_bid_modifier_path - ) - parse_campaign_bid_modifier_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_bid_modifier_path - ) - campaign_budget_path = staticmethod( - GoogleAdsServiceClient.campaign_budget_path - ) - parse_campaign_budget_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_budget_path - ) - campaign_conversion_goal_path = staticmethod( - GoogleAdsServiceClient.campaign_conversion_goal_path - ) - parse_campaign_conversion_goal_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_conversion_goal_path - ) - campaign_criterion_path = staticmethod( - GoogleAdsServiceClient.campaign_criterion_path - ) - parse_campaign_criterion_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_criterion_path - ) - campaign_customizer_path = staticmethod( - GoogleAdsServiceClient.campaign_customizer_path - ) - parse_campaign_customizer_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_customizer_path - ) - campaign_draft_path = staticmethod( - GoogleAdsServiceClient.campaign_draft_path - ) - parse_campaign_draft_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_draft_path - ) - campaign_group_path = staticmethod( - GoogleAdsServiceClient.campaign_group_path - ) - parse_campaign_group_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_group_path - ) - campaign_label_path = staticmethod( - GoogleAdsServiceClient.campaign_label_path - ) - parse_campaign_label_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_label_path - ) - campaign_lifecycle_goal_path = staticmethod( - GoogleAdsServiceClient.campaign_lifecycle_goal_path - ) - parse_campaign_lifecycle_goal_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_lifecycle_goal_path - ) - campaign_search_term_insight_path = staticmethod( - GoogleAdsServiceClient.campaign_search_term_insight_path - ) - parse_campaign_search_term_insight_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_search_term_insight_path - ) - campaign_shared_set_path = staticmethod( - GoogleAdsServiceClient.campaign_shared_set_path - ) - parse_campaign_shared_set_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_shared_set_path - ) - campaign_simulation_path = staticmethod( - GoogleAdsServiceClient.campaign_simulation_path - ) - parse_campaign_simulation_path = staticmethod( - GoogleAdsServiceClient.parse_campaign_simulation_path - ) - carrier_constant_path = staticmethod( - GoogleAdsServiceClient.carrier_constant_path - ) - parse_carrier_constant_path = staticmethod( - GoogleAdsServiceClient.parse_carrier_constant_path - ) - change_event_path = staticmethod(GoogleAdsServiceClient.change_event_path) - parse_change_event_path = staticmethod( - GoogleAdsServiceClient.parse_change_event_path - ) - change_status_path = staticmethod(GoogleAdsServiceClient.change_status_path) - parse_change_status_path = staticmethod( - GoogleAdsServiceClient.parse_change_status_path - ) - channel_aggregate_asset_view_path = staticmethod( - GoogleAdsServiceClient.channel_aggregate_asset_view_path - ) - parse_channel_aggregate_asset_view_path = staticmethod( - GoogleAdsServiceClient.parse_channel_aggregate_asset_view_path - ) - click_view_path = staticmethod(GoogleAdsServiceClient.click_view_path) - parse_click_view_path = staticmethod( - GoogleAdsServiceClient.parse_click_view_path - ) - combined_audience_path = staticmethod( - GoogleAdsServiceClient.combined_audience_path - ) - parse_combined_audience_path = staticmethod( - GoogleAdsServiceClient.parse_combined_audience_path - ) - content_criterion_view_path = staticmethod( - GoogleAdsServiceClient.content_criterion_view_path - ) - parse_content_criterion_view_path = staticmethod( - GoogleAdsServiceClient.parse_content_criterion_view_path - ) - conversion_action_path = staticmethod( - GoogleAdsServiceClient.conversion_action_path - ) - parse_conversion_action_path = staticmethod( - GoogleAdsServiceClient.parse_conversion_action_path - ) - conversion_custom_variable_path = staticmethod( - GoogleAdsServiceClient.conversion_custom_variable_path - ) - parse_conversion_custom_variable_path = staticmethod( - GoogleAdsServiceClient.parse_conversion_custom_variable_path - ) - conversion_goal_campaign_config_path = staticmethod( - GoogleAdsServiceClient.conversion_goal_campaign_config_path - ) - parse_conversion_goal_campaign_config_path = staticmethod( - GoogleAdsServiceClient.parse_conversion_goal_campaign_config_path - ) - conversion_value_rule_path = staticmethod( - GoogleAdsServiceClient.conversion_value_rule_path - ) - parse_conversion_value_rule_path = staticmethod( - GoogleAdsServiceClient.parse_conversion_value_rule_path - ) - conversion_value_rule_set_path = staticmethod( - GoogleAdsServiceClient.conversion_value_rule_set_path - ) - parse_conversion_value_rule_set_path = staticmethod( - GoogleAdsServiceClient.parse_conversion_value_rule_set_path - ) - currency_constant_path = staticmethod( - GoogleAdsServiceClient.currency_constant_path - ) - parse_currency_constant_path = staticmethod( - GoogleAdsServiceClient.parse_currency_constant_path - ) - custom_audience_path = staticmethod( - GoogleAdsServiceClient.custom_audience_path - ) - parse_custom_audience_path = staticmethod( - GoogleAdsServiceClient.parse_custom_audience_path - ) - custom_conversion_goal_path = staticmethod( - GoogleAdsServiceClient.custom_conversion_goal_path - ) - parse_custom_conversion_goal_path = staticmethod( - GoogleAdsServiceClient.parse_custom_conversion_goal_path - ) - customer_path = staticmethod(GoogleAdsServiceClient.customer_path) - parse_customer_path = staticmethod( - GoogleAdsServiceClient.parse_customer_path - ) - customer_asset_path = staticmethod( - GoogleAdsServiceClient.customer_asset_path - ) - parse_customer_asset_path = staticmethod( - GoogleAdsServiceClient.parse_customer_asset_path - ) - customer_asset_set_path = staticmethod( - GoogleAdsServiceClient.customer_asset_set_path - ) - parse_customer_asset_set_path = staticmethod( - GoogleAdsServiceClient.parse_customer_asset_set_path - ) - customer_client_path = staticmethod( - GoogleAdsServiceClient.customer_client_path - ) - parse_customer_client_path = staticmethod( - GoogleAdsServiceClient.parse_customer_client_path - ) - customer_client_link_path = staticmethod( - GoogleAdsServiceClient.customer_client_link_path - ) - parse_customer_client_link_path = staticmethod( - GoogleAdsServiceClient.parse_customer_client_link_path - ) - customer_conversion_goal_path = staticmethod( - GoogleAdsServiceClient.customer_conversion_goal_path - ) - parse_customer_conversion_goal_path = staticmethod( - GoogleAdsServiceClient.parse_customer_conversion_goal_path - ) - customer_customizer_path = staticmethod( - GoogleAdsServiceClient.customer_customizer_path - ) - parse_customer_customizer_path = staticmethod( - GoogleAdsServiceClient.parse_customer_customizer_path - ) - customer_label_path = staticmethod( - GoogleAdsServiceClient.customer_label_path - ) - parse_customer_label_path = staticmethod( - GoogleAdsServiceClient.parse_customer_label_path - ) - customer_lifecycle_goal_path = staticmethod( - GoogleAdsServiceClient.customer_lifecycle_goal_path - ) - parse_customer_lifecycle_goal_path = staticmethod( - GoogleAdsServiceClient.parse_customer_lifecycle_goal_path - ) - customer_manager_link_path = staticmethod( - GoogleAdsServiceClient.customer_manager_link_path - ) - parse_customer_manager_link_path = staticmethod( - GoogleAdsServiceClient.parse_customer_manager_link_path - ) - customer_negative_criterion_path = staticmethod( - GoogleAdsServiceClient.customer_negative_criterion_path - ) - parse_customer_negative_criterion_path = staticmethod( - GoogleAdsServiceClient.parse_customer_negative_criterion_path - ) - customer_search_term_insight_path = staticmethod( - GoogleAdsServiceClient.customer_search_term_insight_path - ) - parse_customer_search_term_insight_path = staticmethod( - GoogleAdsServiceClient.parse_customer_search_term_insight_path - ) - customer_user_access_path = staticmethod( - GoogleAdsServiceClient.customer_user_access_path - ) - parse_customer_user_access_path = staticmethod( - GoogleAdsServiceClient.parse_customer_user_access_path - ) - customer_user_access_invitation_path = staticmethod( - GoogleAdsServiceClient.customer_user_access_invitation_path - ) - parse_customer_user_access_invitation_path = staticmethod( - GoogleAdsServiceClient.parse_customer_user_access_invitation_path - ) - custom_interest_path = staticmethod( - GoogleAdsServiceClient.custom_interest_path - ) - parse_custom_interest_path = staticmethod( - GoogleAdsServiceClient.parse_custom_interest_path - ) - customizer_attribute_path = staticmethod( - GoogleAdsServiceClient.customizer_attribute_path - ) - parse_customizer_attribute_path = staticmethod( - GoogleAdsServiceClient.parse_customizer_attribute_path - ) - data_link_path = staticmethod(GoogleAdsServiceClient.data_link_path) - parse_data_link_path = staticmethod( - GoogleAdsServiceClient.parse_data_link_path - ) - detailed_demographic_path = staticmethod( - GoogleAdsServiceClient.detailed_demographic_path - ) - parse_detailed_demographic_path = staticmethod( - GoogleAdsServiceClient.parse_detailed_demographic_path - ) - detail_placement_view_path = staticmethod( - GoogleAdsServiceClient.detail_placement_view_path - ) - parse_detail_placement_view_path = staticmethod( - GoogleAdsServiceClient.parse_detail_placement_view_path - ) - display_keyword_view_path = staticmethod( - GoogleAdsServiceClient.display_keyword_view_path - ) - parse_display_keyword_view_path = staticmethod( - GoogleAdsServiceClient.parse_display_keyword_view_path - ) - distance_view_path = staticmethod(GoogleAdsServiceClient.distance_view_path) - parse_distance_view_path = staticmethod( - GoogleAdsServiceClient.parse_distance_view_path - ) - domain_category_path = staticmethod( - GoogleAdsServiceClient.domain_category_path - ) - parse_domain_category_path = staticmethod( - GoogleAdsServiceClient.parse_domain_category_path - ) - dynamic_search_ads_search_term_view_path = staticmethod( - GoogleAdsServiceClient.dynamic_search_ads_search_term_view_path - ) - parse_dynamic_search_ads_search_term_view_path = staticmethod( - GoogleAdsServiceClient.parse_dynamic_search_ads_search_term_view_path - ) - expanded_landing_page_view_path = staticmethod( - GoogleAdsServiceClient.expanded_landing_page_view_path - ) - parse_expanded_landing_page_view_path = staticmethod( - GoogleAdsServiceClient.parse_expanded_landing_page_view_path - ) - experiment_path = staticmethod(GoogleAdsServiceClient.experiment_path) - parse_experiment_path = staticmethod( - GoogleAdsServiceClient.parse_experiment_path - ) - experiment_arm_path = staticmethod( - GoogleAdsServiceClient.experiment_arm_path - ) - parse_experiment_arm_path = staticmethod( - GoogleAdsServiceClient.parse_experiment_arm_path - ) - gender_view_path = staticmethod(GoogleAdsServiceClient.gender_view_path) - parse_gender_view_path = staticmethod( - GoogleAdsServiceClient.parse_gender_view_path - ) - geographic_view_path = staticmethod( - GoogleAdsServiceClient.geographic_view_path - ) - parse_geographic_view_path = staticmethod( - GoogleAdsServiceClient.parse_geographic_view_path - ) - geo_target_constant_path = staticmethod( - GoogleAdsServiceClient.geo_target_constant_path - ) - parse_geo_target_constant_path = staticmethod( - GoogleAdsServiceClient.parse_geo_target_constant_path - ) - group_placement_view_path = staticmethod( - GoogleAdsServiceClient.group_placement_view_path - ) - parse_group_placement_view_path = staticmethod( - GoogleAdsServiceClient.parse_group_placement_view_path - ) - hotel_group_view_path = staticmethod( - GoogleAdsServiceClient.hotel_group_view_path - ) - parse_hotel_group_view_path = staticmethod( - GoogleAdsServiceClient.parse_hotel_group_view_path - ) - hotel_performance_view_path = staticmethod( - GoogleAdsServiceClient.hotel_performance_view_path - ) - parse_hotel_performance_view_path = staticmethod( - GoogleAdsServiceClient.parse_hotel_performance_view_path - ) - hotel_reconciliation_path = staticmethod( - GoogleAdsServiceClient.hotel_reconciliation_path - ) - parse_hotel_reconciliation_path = staticmethod( - GoogleAdsServiceClient.parse_hotel_reconciliation_path - ) - income_range_view_path = staticmethod( - GoogleAdsServiceClient.income_range_view_path - ) - parse_income_range_view_path = staticmethod( - GoogleAdsServiceClient.parse_income_range_view_path - ) - keyword_plan_path = staticmethod(GoogleAdsServiceClient.keyword_plan_path) - parse_keyword_plan_path = staticmethod( - GoogleAdsServiceClient.parse_keyword_plan_path - ) - keyword_plan_ad_group_path = staticmethod( - GoogleAdsServiceClient.keyword_plan_ad_group_path - ) - parse_keyword_plan_ad_group_path = staticmethod( - GoogleAdsServiceClient.parse_keyword_plan_ad_group_path - ) - keyword_plan_ad_group_keyword_path = staticmethod( - GoogleAdsServiceClient.keyword_plan_ad_group_keyword_path - ) - parse_keyword_plan_ad_group_keyword_path = staticmethod( - GoogleAdsServiceClient.parse_keyword_plan_ad_group_keyword_path - ) - keyword_plan_campaign_path = staticmethod( - GoogleAdsServiceClient.keyword_plan_campaign_path - ) - parse_keyword_plan_campaign_path = staticmethod( - GoogleAdsServiceClient.parse_keyword_plan_campaign_path - ) - keyword_plan_campaign_keyword_path = staticmethod( - GoogleAdsServiceClient.keyword_plan_campaign_keyword_path - ) - parse_keyword_plan_campaign_keyword_path = staticmethod( - GoogleAdsServiceClient.parse_keyword_plan_campaign_keyword_path - ) - keyword_theme_constant_path = staticmethod( - GoogleAdsServiceClient.keyword_theme_constant_path - ) - parse_keyword_theme_constant_path = staticmethod( - GoogleAdsServiceClient.parse_keyword_theme_constant_path - ) - keyword_view_path = staticmethod(GoogleAdsServiceClient.keyword_view_path) - parse_keyword_view_path = staticmethod( - GoogleAdsServiceClient.parse_keyword_view_path - ) - label_path = staticmethod(GoogleAdsServiceClient.label_path) - parse_label_path = staticmethod(GoogleAdsServiceClient.parse_label_path) - landing_page_view_path = staticmethod( - GoogleAdsServiceClient.landing_page_view_path - ) - parse_landing_page_view_path = staticmethod( - GoogleAdsServiceClient.parse_landing_page_view_path - ) - language_constant_path = staticmethod( - GoogleAdsServiceClient.language_constant_path - ) - parse_language_constant_path = staticmethod( - GoogleAdsServiceClient.parse_language_constant_path - ) - lead_form_submission_data_path = staticmethod( - GoogleAdsServiceClient.lead_form_submission_data_path - ) - parse_lead_form_submission_data_path = staticmethod( - GoogleAdsServiceClient.parse_lead_form_submission_data_path - ) - life_event_path = staticmethod(GoogleAdsServiceClient.life_event_path) - parse_life_event_path = staticmethod( - GoogleAdsServiceClient.parse_life_event_path - ) - local_services_employee_path = staticmethod( - GoogleAdsServiceClient.local_services_employee_path - ) - parse_local_services_employee_path = staticmethod( - GoogleAdsServiceClient.parse_local_services_employee_path - ) - local_services_lead_path = staticmethod( - GoogleAdsServiceClient.local_services_lead_path - ) - parse_local_services_lead_path = staticmethod( - GoogleAdsServiceClient.parse_local_services_lead_path - ) - local_services_lead_conversation_path = staticmethod( - GoogleAdsServiceClient.local_services_lead_conversation_path - ) - parse_local_services_lead_conversation_path = staticmethod( - GoogleAdsServiceClient.parse_local_services_lead_conversation_path - ) - local_services_verification_artifact_path = staticmethod( - GoogleAdsServiceClient.local_services_verification_artifact_path - ) - parse_local_services_verification_artifact_path = staticmethod( - GoogleAdsServiceClient.parse_local_services_verification_artifact_path - ) - location_view_path = staticmethod(GoogleAdsServiceClient.location_view_path) - parse_location_view_path = staticmethod( - GoogleAdsServiceClient.parse_location_view_path - ) - managed_placement_view_path = staticmethod( - GoogleAdsServiceClient.managed_placement_view_path - ) - parse_managed_placement_view_path = staticmethod( - GoogleAdsServiceClient.parse_managed_placement_view_path - ) - media_file_path = staticmethod(GoogleAdsServiceClient.media_file_path) - parse_media_file_path = staticmethod( - GoogleAdsServiceClient.parse_media_file_path - ) - mobile_app_category_constant_path = staticmethod( - GoogleAdsServiceClient.mobile_app_category_constant_path - ) - parse_mobile_app_category_constant_path = staticmethod( - GoogleAdsServiceClient.parse_mobile_app_category_constant_path - ) - mobile_device_constant_path = staticmethod( - GoogleAdsServiceClient.mobile_device_constant_path - ) - parse_mobile_device_constant_path = staticmethod( - GoogleAdsServiceClient.parse_mobile_device_constant_path - ) - offline_conversion_upload_client_summary_path = staticmethod( - GoogleAdsServiceClient.offline_conversion_upload_client_summary_path - ) - parse_offline_conversion_upload_client_summary_path = staticmethod( - GoogleAdsServiceClient.parse_offline_conversion_upload_client_summary_path - ) - offline_conversion_upload_conversion_action_summary_path = staticmethod( - GoogleAdsServiceClient.offline_conversion_upload_conversion_action_summary_path - ) - parse_offline_conversion_upload_conversion_action_summary_path = staticmethod( - GoogleAdsServiceClient.parse_offline_conversion_upload_conversion_action_summary_path - ) - offline_user_data_job_path = staticmethod( - GoogleAdsServiceClient.offline_user_data_job_path - ) - parse_offline_user_data_job_path = staticmethod( - GoogleAdsServiceClient.parse_offline_user_data_job_path - ) - operating_system_version_constant_path = staticmethod( - GoogleAdsServiceClient.operating_system_version_constant_path - ) - parse_operating_system_version_constant_path = staticmethod( - GoogleAdsServiceClient.parse_operating_system_version_constant_path - ) - paid_organic_search_term_view_path = staticmethod( - GoogleAdsServiceClient.paid_organic_search_term_view_path - ) - parse_paid_organic_search_term_view_path = staticmethod( - GoogleAdsServiceClient.parse_paid_organic_search_term_view_path - ) - parental_status_view_path = staticmethod( - GoogleAdsServiceClient.parental_status_view_path - ) - parse_parental_status_view_path = staticmethod( - GoogleAdsServiceClient.parse_parental_status_view_path - ) - payments_account_path = staticmethod( - GoogleAdsServiceClient.payments_account_path - ) - parse_payments_account_path = staticmethod( - GoogleAdsServiceClient.parse_payments_account_path - ) - performance_max_placement_view_path = staticmethod( - GoogleAdsServiceClient.performance_max_placement_view_path - ) - parse_performance_max_placement_view_path = staticmethod( - GoogleAdsServiceClient.parse_performance_max_placement_view_path - ) - per_store_view_path = staticmethod( - GoogleAdsServiceClient.per_store_view_path - ) - parse_per_store_view_path = staticmethod( - GoogleAdsServiceClient.parse_per_store_view_path - ) - product_category_constant_path = staticmethod( - GoogleAdsServiceClient.product_category_constant_path - ) - parse_product_category_constant_path = staticmethod( - GoogleAdsServiceClient.parse_product_category_constant_path - ) - product_group_view_path = staticmethod( - GoogleAdsServiceClient.product_group_view_path - ) - parse_product_group_view_path = staticmethod( - GoogleAdsServiceClient.parse_product_group_view_path - ) - product_link_path = staticmethod(GoogleAdsServiceClient.product_link_path) - parse_product_link_path = staticmethod( - GoogleAdsServiceClient.parse_product_link_path - ) - product_link_invitation_path = staticmethod( - GoogleAdsServiceClient.product_link_invitation_path - ) - parse_product_link_invitation_path = staticmethod( - GoogleAdsServiceClient.parse_product_link_invitation_path - ) - qualifying_question_path = staticmethod( - GoogleAdsServiceClient.qualifying_question_path - ) - parse_qualifying_question_path = staticmethod( - GoogleAdsServiceClient.parse_qualifying_question_path - ) - recommendation_path = staticmethod( - GoogleAdsServiceClient.recommendation_path - ) - parse_recommendation_path = staticmethod( - GoogleAdsServiceClient.parse_recommendation_path - ) - recommendation_subscription_path = staticmethod( - GoogleAdsServiceClient.recommendation_subscription_path - ) - parse_recommendation_subscription_path = staticmethod( - GoogleAdsServiceClient.parse_recommendation_subscription_path - ) - remarketing_action_path = staticmethod( - GoogleAdsServiceClient.remarketing_action_path - ) - parse_remarketing_action_path = staticmethod( - GoogleAdsServiceClient.parse_remarketing_action_path - ) - search_term_view_path = staticmethod( - GoogleAdsServiceClient.search_term_view_path - ) - parse_search_term_view_path = staticmethod( - GoogleAdsServiceClient.parse_search_term_view_path - ) - shared_criterion_path = staticmethod( - GoogleAdsServiceClient.shared_criterion_path - ) - parse_shared_criterion_path = staticmethod( - GoogleAdsServiceClient.parse_shared_criterion_path - ) - shared_set_path = staticmethod(GoogleAdsServiceClient.shared_set_path) - parse_shared_set_path = staticmethod( - GoogleAdsServiceClient.parse_shared_set_path - ) - shopping_performance_view_path = staticmethod( - GoogleAdsServiceClient.shopping_performance_view_path - ) - parse_shopping_performance_view_path = staticmethod( - GoogleAdsServiceClient.parse_shopping_performance_view_path - ) - shopping_product_path = staticmethod( - GoogleAdsServiceClient.shopping_product_path - ) - parse_shopping_product_path = staticmethod( - GoogleAdsServiceClient.parse_shopping_product_path - ) - smart_campaign_search_term_view_path = staticmethod( - GoogleAdsServiceClient.smart_campaign_search_term_view_path - ) - parse_smart_campaign_search_term_view_path = staticmethod( - GoogleAdsServiceClient.parse_smart_campaign_search_term_view_path - ) - smart_campaign_setting_path = staticmethod( - GoogleAdsServiceClient.smart_campaign_setting_path - ) - parse_smart_campaign_setting_path = staticmethod( - GoogleAdsServiceClient.parse_smart_campaign_setting_path - ) - third_party_app_analytics_link_path = staticmethod( - GoogleAdsServiceClient.third_party_app_analytics_link_path - ) - parse_third_party_app_analytics_link_path = staticmethod( - GoogleAdsServiceClient.parse_third_party_app_analytics_link_path - ) - topic_constant_path = staticmethod( - GoogleAdsServiceClient.topic_constant_path - ) - parse_topic_constant_path = staticmethod( - GoogleAdsServiceClient.parse_topic_constant_path - ) - topic_view_path = staticmethod(GoogleAdsServiceClient.topic_view_path) - parse_topic_view_path = staticmethod( - GoogleAdsServiceClient.parse_topic_view_path - ) - travel_activity_group_view_path = staticmethod( - GoogleAdsServiceClient.travel_activity_group_view_path - ) - parse_travel_activity_group_view_path = staticmethod( - GoogleAdsServiceClient.parse_travel_activity_group_view_path - ) - travel_activity_performance_view_path = staticmethod( - GoogleAdsServiceClient.travel_activity_performance_view_path - ) - parse_travel_activity_performance_view_path = staticmethod( - GoogleAdsServiceClient.parse_travel_activity_performance_view_path - ) - user_interest_path = staticmethod(GoogleAdsServiceClient.user_interest_path) - parse_user_interest_path = staticmethod( - GoogleAdsServiceClient.parse_user_interest_path - ) - user_list_path = staticmethod(GoogleAdsServiceClient.user_list_path) - parse_user_list_path = staticmethod( - GoogleAdsServiceClient.parse_user_list_path - ) - user_list_customer_type_path = staticmethod( - GoogleAdsServiceClient.user_list_customer_type_path - ) - parse_user_list_customer_type_path = staticmethod( - GoogleAdsServiceClient.parse_user_list_customer_type_path - ) - user_location_view_path = staticmethod( - GoogleAdsServiceClient.user_location_view_path - ) - parse_user_location_view_path = staticmethod( - GoogleAdsServiceClient.parse_user_location_view_path - ) - video_path = staticmethod(GoogleAdsServiceClient.video_path) - parse_video_path = staticmethod(GoogleAdsServiceClient.parse_video_path) - webpage_view_path = staticmethod(GoogleAdsServiceClient.webpage_view_path) - parse_webpage_view_path = staticmethod( - GoogleAdsServiceClient.parse_webpage_view_path - ) - common_billing_account_path = staticmethod( - GoogleAdsServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - GoogleAdsServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(GoogleAdsServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - GoogleAdsServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - GoogleAdsServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - GoogleAdsServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - GoogleAdsServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - GoogleAdsServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - GoogleAdsServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - GoogleAdsServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GoogleAdsServiceAsyncClient: The constructed client. - """ - return GoogleAdsServiceClient.from_service_account_info.__func__(GoogleAdsServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GoogleAdsServiceAsyncClient: The constructed client. - """ - return GoogleAdsServiceClient.from_service_account_file.__func__(GoogleAdsServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return GoogleAdsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> GoogleAdsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - GoogleAdsServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = GoogleAdsServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - GoogleAdsServiceTransport, - Callable[..., GoogleAdsServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the google ads service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,GoogleAdsServiceTransport,Callable[..., GoogleAdsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the GoogleAdsServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = GoogleAdsServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.GoogleAdsServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.GoogleAdsService", - "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.ads.googleads.v19.services.GoogleAdsService", - "credentialsType": None, - } - ), - ) - - async def search( - self, - request: Optional[ - Union[google_ads_service.SearchGoogleAdsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - query: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.SearchAsyncPager: - r"""Returns all rows that match the search query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ChangeEventError <>`__ - `ChangeStatusError <>`__ `ClickViewError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.SearchGoogleAdsRequest, dict]]): - The request object. Request message for - [GoogleAdsService.Search][google.ads.googleads.v19.services.GoogleAdsService.Search]. - customer_id (:class:`str`): - Required. The ID of the customer - being queried. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - query (:class:`str`): - Required. The query string. - This corresponds to the ``query`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.google_ads_service.pagers.SearchAsyncPager: - Response message for - [GoogleAdsService.Search][google.ads.googleads.v19.services.GoogleAdsService.Search]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, query] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, google_ads_service.SearchGoogleAdsRequest): - request = google_ads_service.SearchGoogleAdsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if query is not None: - request.query = query - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.search - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.SearchAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def search_stream( - self, - request: Optional[ - Union[google_ads_service.SearchGoogleAdsStreamRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - query: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> Awaitable[ - AsyncIterable[google_ads_service.SearchGoogleAdsStreamResponse] - ]: - r"""Returns all rows that match the search stream query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ChangeEventError <>`__ - `ChangeStatusError <>`__ `ClickViewError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.SearchGoogleAdsStreamRequest, dict]]): - The request object. Request message for - [GoogleAdsService.SearchStream][google.ads.googleads.v19.services.GoogleAdsService.SearchStream]. - customer_id (:class:`str`): - Required. The ID of the customer - being queried. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - query (:class:`str`): - Required. The query string. - This corresponds to the ``query`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SearchGoogleAdsStreamResponse]: - Response message for - [GoogleAdsService.SearchStream][google.ads.googleads.v19.services.GoogleAdsService.SearchStream]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, query] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, google_ads_service.SearchGoogleAdsStreamRequest - ): - request = google_ads_service.SearchGoogleAdsStreamRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if query is not None: - request.query = query - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.search_stream - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def mutate( - self, - request: Optional[ - Union[google_ads_service.MutateGoogleAdsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - mutate_operations: Optional[ - MutableSequence[google_ads_service.MutateOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> google_ads_service.MutateGoogleAdsResponse: - r"""Creates, updates, or removes resources. This method supports - atomic transactions with multiple types of resources. For - example, you can atomically create a campaign and a campaign - budget, or perform up to thousands of mutates atomically. - - This method is essentially a wrapper around a series of mutate - methods. The only features it offers over calling those methods - directly are: - - - Atomic transactions - - Temp resource names (described below) - - Somewhat reduced latency over making a series of mutate calls - - Note: Only resources that support atomic transactions are - included, so this method can't replace all calls to individual - services. - - Atomic Transaction Benefits - --------------------------- - - Atomicity makes error handling much easier. If you're making a - series of changes and one fails, it can leave your account in an - inconsistent state. With atomicity, you either reach the chosen - state directly, or the request fails and you can retry. - - Temp Resource Names - ------------------- - - Temp resource names are a special type of resource name used to - create a resource and reference that resource in the same - request. For example, if a campaign budget is created with - ``resource_name`` equal to ``customers/123/campaignBudgets/-1``, - that resource name can be reused in the ``Campaign.budget`` - field in the same request. That way, the two resources are - created and linked atomically. - - To create a temp resource name, put a negative number in the - part of the name that the server would normally allocate. - - Note: - - - Resources must be created with a temp name before the name - can be reused. For example, the previous - CampaignBudget+Campaign example would fail if the mutate - order was reversed. - - Temp names are not remembered across requests. - - There's no limit to the number of temp names in a request. - - Each temp name must use a unique negative number, even if the - resource types differ. - - Latency - ------- - - It's important to group mutates by resource type or the request - may time out and fail. Latency is roughly equal to a series of - calls to individual mutate methods, where each change in - resource type is a new call. For example, mutating 10 campaigns - then 10 ad groups is like 2 calls, while mutating 1 campaign, 1 - ad group, 1 campaign, 1 ad group is like 4 calls. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdGroupAdError <>`__ `AdGroupCriterionError <>`__ - `AdGroupError <>`__ `AssetError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `BiddingError <>`__ - `CampaignBudgetError <>`__ `CampaignCriterionError <>`__ - `CampaignError <>`__ `CampaignExperimentError <>`__ - `CampaignSharedSetError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `ConversionActionError <>`__ - `CriterionError <>`__ `CustomerFeedError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ - `DistinctError <>`__ `ExtensionFeedItemError <>`__ - `ExtensionSettingError <>`__ `FeedAttributeReferenceError <>`__ - `FeedError <>`__ `FeedItemError <>`__ `FeedItemSetError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `ImageError <>`__ - `InternalError <>`__ `KeywordPlanAdGroupKeywordError <>`__ - `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ - `LabelError <>`__ `ListOperationError <>`__ - `MediaUploadError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `PolicyFindingError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SharedSetError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ `UserListError <>`__ - `YoutubeVideoRegistrationError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateGoogleAdsRequest, dict]]): - The request object. Request message for - [GoogleAdsService.Mutate][google.ads.googleads.v19.services.GoogleAdsService.Mutate]. - customer_id (:class:`str`): - Required. The ID of the customer - whose resources are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - mutate_operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.MutateOperation]`): - Required. The list of operations to - perform on individual resources. - - This corresponds to the ``mutate_operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateGoogleAdsResponse: - Response message for - [GoogleAdsService.Mutate][google.ads.googleads.v19.services.GoogleAdsService.Mutate]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, mutate_operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, google_ads_service.MutateGoogleAdsRequest): - request = google_ads_service.MutateGoogleAdsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if mutate_operations: - request.mutate_operations.extend(mutate_operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "GoogleAdsServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("GoogleAdsServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/google_ads_service/client.py b/google/ads/googleads/v19/services/services/google_ads_service/client.py deleted file mode 100644 index dcdc3f7d4..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_service/client.py +++ /dev/null @@ -1,4734 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Iterable, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.services.google_ads_service import pagers -from google.ads.googleads.v19.services.types import google_ads_service -from google.protobuf import field_mask_pb2 # type: ignore -from google.rpc import status_pb2 # type: ignore -from .transports.base import GoogleAdsServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import GoogleAdsServiceGrpcTransport -from .transports.grpc_asyncio import GoogleAdsServiceGrpcAsyncIOTransport - - -class GoogleAdsServiceClientMeta(type): - """Metaclass for the GoogleAdsService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[GoogleAdsServiceTransport]] - _transport_registry["grpc"] = GoogleAdsServiceGrpcTransport - _transport_registry["grpc_asyncio"] = GoogleAdsServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[GoogleAdsServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class GoogleAdsServiceClient(metaclass=GoogleAdsServiceClientMeta): - """Service to fetch data and metrics across resources.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GoogleAdsServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - GoogleAdsServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> GoogleAdsServiceTransport: - """Returns the transport used by the client instance. - - Returns: - GoogleAdsServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def accessible_bidding_strategy_path( - customer_id: str, - bidding_strategy_id: str, - ) -> str: - """Returns a fully-qualified accessible_bidding_strategy string.""" - return "customers/{customer_id}/accessibleBiddingStrategies/{bidding_strategy_id}".format( - customer_id=customer_id, - bidding_strategy_id=bidding_strategy_id, - ) - - @staticmethod - def parse_accessible_bidding_strategy_path(path: str) -> Dict[str, str]: - """Parses a accessible_bidding_strategy path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/accessibleBiddingStrategies/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def account_budget_path( - customer_id: str, - account_budget_id: str, - ) -> str: - """Returns a fully-qualified account_budget string.""" - return ( - "customers/{customer_id}/accountBudgets/{account_budget_id}".format( - customer_id=customer_id, - account_budget_id=account_budget_id, - ) - ) - - @staticmethod - def parse_account_budget_path(path: str) -> Dict[str, str]: - """Parses a account_budget path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/accountBudgets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def account_budget_proposal_path( - customer_id: str, - account_budget_proposal_id: str, - ) -> str: - """Returns a fully-qualified account_budget_proposal string.""" - return "customers/{customer_id}/accountBudgetProposals/{account_budget_proposal_id}".format( - customer_id=customer_id, - account_budget_proposal_id=account_budget_proposal_id, - ) - - @staticmethod - def parse_account_budget_proposal_path(path: str) -> Dict[str, str]: - """Parses a account_budget_proposal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/accountBudgetProposals/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def account_link_path( - customer_id: str, - account_link_id: str, - ) -> str: - """Returns a fully-qualified account_link string.""" - return "customers/{customer_id}/accountLinks/{account_link_id}".format( - customer_id=customer_id, - account_link_id=account_link_id, - ) - - @staticmethod - def parse_account_link_path(path: str) -> Dict[str, str]: - """Parses a account_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/accountLinks/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_path( - customer_id: str, - ad_id: str, - ) -> str: - """Returns a fully-qualified ad string.""" - return "customers/{customer_id}/ads/{ad_id}".format( - customer_id=customer_id, - ad_id=ad_id, - ) - - @staticmethod - def parse_ad_path(path: str) -> Dict[str, str]: - """Parses a ad path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/ads/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_path( - customer_id: str, - ad_group_id: str, - ) -> str: - """Returns a fully-qualified ad_group string.""" - return "customers/{customer_id}/adGroups/{ad_group_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ) - - @staticmethod - def parse_ad_group_path(path: str) -> Dict[str, str]: - """Parses a ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_ad_path( - customer_id: str, - ad_group_id: str, - ad_id: str, - ) -> str: - """Returns a fully-qualified ad_group_ad string.""" - return ( - "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ad_id=ad_id, - ) - ) - - @staticmethod - def parse_ad_group_ad_path(path: str) -> Dict[str, str]: - """Parses a ad_group_ad path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_ad_asset_combination_view_path( - customer_id: str, - ad_group_id: str, - ad_id: str, - asset_combination_id_low: str, - asset_combination_id_high: str, - ) -> str: - """Returns a fully-qualified ad_group_ad_asset_combination_view string.""" - return "customers/{customer_id}/adGroupAdAssetCombinationViews/{ad_group_id}~{ad_id}~{asset_combination_id_low}~{asset_combination_id_high}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ad_id=ad_id, - asset_combination_id_low=asset_combination_id_low, - asset_combination_id_high=asset_combination_id_high, - ) - - @staticmethod - def parse_ad_group_ad_asset_combination_view_path( - path: str, - ) -> Dict[str, str]: - """Parses a ad_group_ad_asset_combination_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAdAssetCombinationViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_ad_asset_view_path( - customer_id: str, - ad_group_id: str, - ad_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified ad_group_ad_asset_view string.""" - return "customers/{customer_id}/adGroupAdAssetViews/{ad_group_id}~{ad_id}~{asset_id}~{field_type}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ad_id=ad_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_ad_group_ad_asset_view_path(path: str) -> Dict[str, str]: - """Parses a ad_group_ad_asset_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAdAssetViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_ad_label_path( - customer_id: str, - ad_group_id: str, - ad_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_ad_label string.""" - return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ad_id=ad_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_ad_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_asset_path( - customer_id: str, - ad_group_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified ad_group_asset string.""" - return "customers/{customer_id}/adGroupAssets/{ad_group_id}~{asset_id}~{field_type}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_ad_group_asset_path(path: str) -> Dict[str, str]: - """Parses a ad_group_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_asset_set_path( - customer_id: str, - ad_group_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified ad_group_asset_set string.""" - return "customers/{customer_id}/adGroupAssetSets/{ad_group_id}~{asset_set_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_ad_group_asset_set_path(path: str) -> Dict[str, str]: - """Parses a ad_group_asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAssetSets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_audience_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified ad_group_audience_view string.""" - return "customers/{customer_id}/adGroupAudienceViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_ad_group_audience_view_path(path: str) -> Dict[str, str]: - """Parses a ad_group_audience_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupAudienceViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_bid_modifier_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified ad_group_bid_modifier string.""" - return "customers/{customer_id}/adGroupBidModifiers/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_ad_group_bid_modifier_path(path: str) -> Dict[str, str]: - """Parses a ad_group_bid_modifier path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupBidModifiers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_criterion_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion string.""" - return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_criterion_customizer_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion_customizer string.""" - return "customers/{customer_id}/adGroupCriterionCustomizers/{ad_group_id}~{criterion_id}~{customizer_attribute_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_ad_group_criterion_customizer_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriterionCustomizers/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_criterion_label_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion_label string.""" - return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_criterion_simulation_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - type: str, - modification_method: str, - start_date: str, - end_date: str, - ) -> str: - """Returns a fully-qualified ad_group_criterion_simulation string.""" - return "customers/{customer_id}/adGroupCriterionSimulations/{ad_group_id}~{criterion_id}~{type}~{modification_method}~{start_date}~{end_date}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - type=type, - modification_method=modification_method, - start_date=start_date, - end_date=end_date, - ) - - @staticmethod - def parse_ad_group_criterion_simulation_path(path: str) -> Dict[str, str]: - """Parses a ad_group_criterion_simulation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCriterionSimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_customizer_path( - customer_id: str, - ad_group_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified ad_group_customizer string.""" - return "customers/{customer_id}/adGroupCustomizers/{ad_group_id}~{customizer_attribute_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_ad_group_customizer_path(path: str) -> Dict[str, str]: - """Parses a ad_group_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupCustomizers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_label_path( - customer_id: str, - ad_group_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified ad_group_label string.""" - return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - label_id=label_id, - ) - - @staticmethod - def parse_ad_group_label_path(path: str) -> Dict[str, str]: - """Parses a ad_group_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_simulation_path( - customer_id: str, - ad_group_id: str, - type: str, - modification_method: str, - start_date: str, - end_date: str, - ) -> str: - """Returns a fully-qualified ad_group_simulation string.""" - return "customers/{customer_id}/adGroupSimulations/{ad_group_id}~{type}~{modification_method}~{start_date}~{end_date}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - type=type, - modification_method=modification_method, - start_date=start_date, - end_date=end_date, - ) - - @staticmethod - def parse_ad_group_simulation_path(path: str) -> Dict[str, str]: - """Parses a ad_group_simulation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroupSimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_parameter_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - parameter_index: str, - ) -> str: - """Returns a fully-qualified ad_parameter string.""" - return "customers/{customer_id}/adParameters/{ad_group_id}~{criterion_id}~{parameter_index}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - parameter_index=parameter_index, - ) - - @staticmethod - def parse_ad_parameter_path(path: str) -> Dict[str, str]: - """Parses a ad_parameter path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adParameters/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_schedule_view_path( - customer_id: str, - campaign_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified ad_schedule_view string.""" - return "customers/{customer_id}/adScheduleViews/{campaign_id}~{criterion_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_ad_schedule_view_path(path: str) -> Dict[str, str]: - """Parses a ad_schedule_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adScheduleViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def age_range_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified age_range_view string.""" - return "customers/{customer_id}/ageRangeViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_age_range_view_path(path: str) -> Dict[str, str]: - """Parses a age_range_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/ageRangeViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def android_privacy_shared_key_google_ad_group_path( - customer_id: str, - campaign_id: str, - ad_group_id: str, - android_privacy_interaction_type: str, - android_privacy_network_type: str, - android_privacy_interaction_date: str, - ) -> str: - """Returns a fully-qualified android_privacy_shared_key_google_ad_group string.""" - return "customers/{customer_id}/androidPrivacySharedKeyGoogleAdGroups/{campaign_id}~{ad_group_id}~{android_privacy_interaction_type}~{android_privacy_network_type}~{android_privacy_interaction_date}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ad_group_id=ad_group_id, - android_privacy_interaction_type=android_privacy_interaction_type, - android_privacy_network_type=android_privacy_network_type, - android_privacy_interaction_date=android_privacy_interaction_date, - ) - - @staticmethod - def parse_android_privacy_shared_key_google_ad_group_path( - path: str, - ) -> Dict[str, str]: - """Parses a android_privacy_shared_key_google_ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/androidPrivacySharedKeyGoogleAdGroups/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def android_privacy_shared_key_google_campaign_path( - customer_id: str, - campaign_id: str, - android_privacy_interaction_type: str, - android_privacy_interaction_date: str, - ) -> str: - """Returns a fully-qualified android_privacy_shared_key_google_campaign string.""" - return "customers/{customer_id}/androidPrivacySharedKeyGoogleCampaigns/{campaign_id}~{android_privacy_interaction_type}~{android_privacy_interaction_date}".format( - customer_id=customer_id, - campaign_id=campaign_id, - android_privacy_interaction_type=android_privacy_interaction_type, - android_privacy_interaction_date=android_privacy_interaction_date, - ) - - @staticmethod - def parse_android_privacy_shared_key_google_campaign_path( - path: str, - ) -> Dict[str, str]: - """Parses a android_privacy_shared_key_google_campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/androidPrivacySharedKeyGoogleCampaigns/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def android_privacy_shared_key_google_network_type_path( - customer_id: str, - campaign_id: str, - android_privacy_interaction_type: str, - android_privacy_network_type: str, - android_privacy_interaction_date: str, - ) -> str: - """Returns a fully-qualified android_privacy_shared_key_google_network_type string.""" - return "customers/{customer_id}/androidPrivacySharedKeyGoogleNetworkTypes/{campaign_id}~{android_privacy_interaction_type}~{android_privacy_network_type}~{android_privacy_interaction_date}".format( - customer_id=customer_id, - campaign_id=campaign_id, - android_privacy_interaction_type=android_privacy_interaction_type, - android_privacy_network_type=android_privacy_network_type, - android_privacy_interaction_date=android_privacy_interaction_date, - ) - - @staticmethod - def parse_android_privacy_shared_key_google_network_type_path( - path: str, - ) -> Dict[str, str]: - """Parses a android_privacy_shared_key_google_network_type path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/androidPrivacySharedKeyGoogleNetworkTypes/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_path( - customer_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset string.""" - return "customers/{customer_id}/assets/{asset_id}".format( - customer_id=customer_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_path(path: str) -> Dict[str, str]: - """Parses a asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assets/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_field_type_view_path( - customer_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified asset_field_type_view string.""" - return ( - "customers/{customer_id}/assetFieldTypeViews/{field_type}".format( - customer_id=customer_id, - field_type=field_type, - ) - ) - - @staticmethod - def parse_asset_field_type_view_path(path: str) -> Dict[str, str]: - """Parses a asset_field_type_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetFieldTypeViews/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_path( - customer_id: str, - asset_group_id: str, - ) -> str: - """Returns a fully-qualified asset_group string.""" - return "customers/{customer_id}/assetGroups/{asset_group_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - ) - - @staticmethod - def parse_asset_group_path(path: str) -> Dict[str, str]: - """Parses a asset_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_asset_path( - customer_id: str, - asset_group_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified asset_group_asset string.""" - return "customers/{customer_id}/assetGroupAssets/{asset_group_id}~{asset_id}~{field_type}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_asset_group_asset_path(path: str) -> Dict[str, str]: - """Parses a asset_group_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_listing_group_filter_path( - customer_id: str, - asset_group_id: str, - listing_group_filter_id: str, - ) -> str: - """Returns a fully-qualified asset_group_listing_group_filter string.""" - return "customers/{customer_id}/assetGroupListingGroupFilters/{asset_group_id}~{listing_group_filter_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - listing_group_filter_id=listing_group_filter_id, - ) - - @staticmethod - def parse_asset_group_listing_group_filter_path( - path: str, - ) -> Dict[str, str]: - """Parses a asset_group_listing_group_filter path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroupListingGroupFilters/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_product_group_view_path( - customer_id: str, - asset_group_id: str, - listing_group_filter_id: str, - ) -> str: - """Returns a fully-qualified asset_group_product_group_view string.""" - return "customers/{customer_id}/assetGroupProductGroupViews/{asset_group_id}~{listing_group_filter_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - listing_group_filter_id=listing_group_filter_id, - ) - - @staticmethod - def parse_asset_group_product_group_view_path(path: str) -> Dict[str, str]: - """Parses a asset_group_product_group_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroupProductGroupViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_signal_path( - customer_id: str, - asset_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified asset_group_signal string.""" - return "customers/{customer_id}/assetGroupSignals/{asset_group_id}~{criterion_id}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_asset_group_signal_path(path: str) -> Dict[str, str]: - """Parses a asset_group_signal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroupSignals/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_group_top_combination_view_path( - customer_id: str, - asset_group_id: str, - asset_combination_category: str, - ) -> str: - """Returns a fully-qualified asset_group_top_combination_view string.""" - return "customers/{customer_id}/assetGroupTopCombinationViews/{asset_group_id}~{asset_combination_category}".format( - customer_id=customer_id, - asset_group_id=asset_group_id, - asset_combination_category=asset_combination_category, - ) - - @staticmethod - def parse_asset_group_top_combination_view_path( - path: str, - ) -> Dict[str, str]: - """Parses a asset_group_top_combination_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetGroupTopCombinationViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_set_path( - customer_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified asset_set string.""" - return "customers/{customer_id}/assetSets/{asset_set_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_asset_set_path(path: str) -> Dict[str, str]: - """Parses a asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_set_asset_path( - customer_id: str, - asset_set_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset_set_asset string.""" - return "customers/{customer_id}/assetSetAssets/{asset_set_id}~{asset_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_set_asset_path(path: str) -> Dict[str, str]: - """Parses a asset_set_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSetAssets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_set_type_view_path( - customer_id: str, - asset_set_type: str, - ) -> str: - """Returns a fully-qualified asset_set_type_view string.""" - return ( - "customers/{customer_id}/assetSetTypeViews/{asset_set_type}".format( - customer_id=customer_id, - asset_set_type=asset_set_type, - ) - ) - - @staticmethod - def parse_asset_set_type_view_path(path: str) -> Dict[str, str]: - """Parses a asset_set_type_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assetSetTypeViews/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def audience_path( - customer_id: str, - audience_id: str, - ) -> str: - """Returns a fully-qualified audience string.""" - return "customers/{customer_id}/audiences/{audience_id}".format( - customer_id=customer_id, - audience_id=audience_id, - ) - - @staticmethod - def parse_audience_path(path: str) -> Dict[str, str]: - """Parses a audience path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/audiences/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def batch_job_path( - customer_id: str, - batch_job_id: str, - ) -> str: - """Returns a fully-qualified batch_job string.""" - return "customers/{customer_id}/batchJobs/{batch_job_id}".format( - customer_id=customer_id, - batch_job_id=batch_job_id, - ) - - @staticmethod - def parse_batch_job_path(path: str) -> Dict[str, str]: - """Parses a batch_job path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/batchJobs/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def bidding_data_exclusion_path( - customer_id: str, - seasonality_event_id: str, - ) -> str: - """Returns a fully-qualified bidding_data_exclusion string.""" - return "customers/{customer_id}/biddingDataExclusions/{seasonality_event_id}".format( - customer_id=customer_id, - seasonality_event_id=seasonality_event_id, - ) - - @staticmethod - def parse_bidding_data_exclusion_path(path: str) -> Dict[str, str]: - """Parses a bidding_data_exclusion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/biddingDataExclusions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def bidding_seasonality_adjustment_path( - customer_id: str, - seasonality_event_id: str, - ) -> str: - """Returns a fully-qualified bidding_seasonality_adjustment string.""" - return "customers/{customer_id}/biddingSeasonalityAdjustments/{seasonality_event_id}".format( - customer_id=customer_id, - seasonality_event_id=seasonality_event_id, - ) - - @staticmethod - def parse_bidding_seasonality_adjustment_path(path: str) -> Dict[str, str]: - """Parses a bidding_seasonality_adjustment path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/biddingSeasonalityAdjustments/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def bidding_strategy_path( - customer_id: str, - bidding_strategy_id: str, - ) -> str: - """Returns a fully-qualified bidding_strategy string.""" - return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( - customer_id=customer_id, - bidding_strategy_id=bidding_strategy_id, - ) - - @staticmethod - def parse_bidding_strategy_path(path: str) -> Dict[str, str]: - """Parses a bidding_strategy path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def bidding_strategy_simulation_path( - customer_id: str, - bidding_strategy_id: str, - type: str, - modification_method: str, - start_date: str, - end_date: str, - ) -> str: - """Returns a fully-qualified bidding_strategy_simulation string.""" - return "customers/{customer_id}/biddingStrategySimulations/{bidding_strategy_id}~{type}~{modification_method}~{start_date}~{end_date}".format( - customer_id=customer_id, - bidding_strategy_id=bidding_strategy_id, - type=type, - modification_method=modification_method, - start_date=start_date, - end_date=end_date, - ) - - @staticmethod - def parse_bidding_strategy_simulation_path(path: str) -> Dict[str, str]: - """Parses a bidding_strategy_simulation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/biddingStrategySimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def billing_setup_path( - customer_id: str, - billing_setup_id: str, - ) -> str: - """Returns a fully-qualified billing_setup string.""" - return ( - "customers/{customer_id}/billingSetups/{billing_setup_id}".format( - customer_id=customer_id, - billing_setup_id=billing_setup_id, - ) - ) - - @staticmethod - def parse_billing_setup_path(path: str) -> Dict[str, str]: - """Parses a billing_setup path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/billingSetups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def call_view_path( - customer_id: str, - call_detail_id: str, - ) -> str: - """Returns a fully-qualified call_view string.""" - return "customers/{customer_id}/callViews/{call_detail_id}".format( - customer_id=customer_id, - call_detail_id=call_detail_id, - ) - - @staticmethod - def parse_call_view_path(path: str) -> Dict[str, str]: - """Parses a call_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/callViews/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_aggregate_asset_view_path( - customer_id: str, - campaign_id: str, - asset_id: str, - asset_link_source: str, - field_type: str, - ) -> str: - """Returns a fully-qualified campaign_aggregate_asset_view string.""" - return "customers/{customer_id}/campaignAggregateAssetViews/{campaign_id}~{asset_id}~{asset_link_source}~{field_type}".format( - customer_id=customer_id, - campaign_id=campaign_id, - asset_id=asset_id, - asset_link_source=asset_link_source, - field_type=field_type, - ) - - @staticmethod - def parse_campaign_aggregate_asset_view_path(path: str) -> Dict[str, str]: - """Parses a campaign_aggregate_asset_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignAggregateAssetViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_asset_path( - customer_id: str, - campaign_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified campaign_asset string.""" - return "customers/{customer_id}/campaignAssets/{campaign_id}~{asset_id}~{field_type}".format( - customer_id=customer_id, - campaign_id=campaign_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_campaign_asset_path(path: str) -> Dict[str, str]: - """Parses a campaign_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignAssets/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_asset_set_path( - customer_id: str, - campaign_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified campaign_asset_set string.""" - return "customers/{customer_id}/campaignAssetSets/{campaign_id}~{asset_set_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - asset_set_id=asset_set_id, - ) - - @staticmethod - def parse_campaign_asset_set_path(path: str) -> Dict[str, str]: - """Parses a campaign_asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignAssetSets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_audience_view_path( - customer_id: str, - campaign_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified campaign_audience_view string.""" - return "customers/{customer_id}/campaignAudienceViews/{campaign_id}~{criterion_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_campaign_audience_view_path(path: str) -> Dict[str, str]: - """Parses a campaign_audience_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignAudienceViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_bid_modifier_path( - customer_id: str, - campaign_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified campaign_bid_modifier string.""" - return "customers/{customer_id}/campaignBidModifiers/{campaign_id}~{criterion_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_campaign_bid_modifier_path(path: str) -> Dict[str, str]: - """Parses a campaign_bid_modifier path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignBidModifiers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_budget_path( - customer_id: str, - campaign_budget_id: str, - ) -> str: - """Returns a fully-qualified campaign_budget string.""" - return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( - customer_id=customer_id, - campaign_budget_id=campaign_budget_id, - ) - - @staticmethod - def parse_campaign_budget_path(path: str) -> Dict[str, str]: - """Parses a campaign_budget path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_conversion_goal_path( - customer_id: str, - campaign_id: str, - category: str, - source: str, - ) -> str: - """Returns a fully-qualified campaign_conversion_goal string.""" - return "customers/{customer_id}/campaignConversionGoals/{campaign_id}~{category}~{source}".format( - customer_id=customer_id, - campaign_id=campaign_id, - category=category, - source=source, - ) - - @staticmethod - def parse_campaign_conversion_goal_path(path: str) -> Dict[str, str]: - """Parses a campaign_conversion_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignConversionGoals/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_criterion_path( - customer_id: str, - campaign_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified campaign_criterion string.""" - return "customers/{customer_id}/campaignCriteria/{campaign_id}~{criterion_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_campaign_criterion_path(path: str) -> Dict[str, str]: - """Parses a campaign_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_customizer_path( - customer_id: str, - campaign_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified campaign_customizer string.""" - return "customers/{customer_id}/campaignCustomizers/{campaign_id}~{customizer_attribute_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_campaign_customizer_path(path: str) -> Dict[str, str]: - """Parses a campaign_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignCustomizers/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_draft_path( - customer_id: str, - base_campaign_id: str, - draft_id: str, - ) -> str: - """Returns a fully-qualified campaign_draft string.""" - return "customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}".format( - customer_id=customer_id, - base_campaign_id=base_campaign_id, - draft_id=draft_id, - ) - - @staticmethod - def parse_campaign_draft_path(path: str) -> Dict[str, str]: - """Parses a campaign_draft path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignDrafts/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_group_path( - customer_id: str, - campaign_group_id: str, - ) -> str: - """Returns a fully-qualified campaign_group string.""" - return ( - "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( - customer_id=customer_id, - campaign_group_id=campaign_group_id, - ) - ) - - @staticmethod - def parse_campaign_group_path(path: str) -> Dict[str, str]: - """Parses a campaign_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_label_path( - customer_id: str, - campaign_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified campaign_label string.""" - return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - label_id=label_id, - ) - - @staticmethod - def parse_campaign_label_path(path: str) -> Dict[str, str]: - """Parses a campaign_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_lifecycle_goal_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign_lifecycle_goal string.""" - return "customers/{customer_id}/campaignLifecycleGoals/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_lifecycle_goal_path(path: str) -> Dict[str, str]: - """Parses a campaign_lifecycle_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignLifecycleGoals/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_search_term_insight_path( - customer_id: str, - campaign_id: str, - cluster_id: str, - ) -> str: - """Returns a fully-qualified campaign_search_term_insight string.""" - return "customers/{customer_id}/campaignSearchTermInsights/{campaign_id}~{cluster_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - cluster_id=cluster_id, - ) - - @staticmethod - def parse_campaign_search_term_insight_path(path: str) -> Dict[str, str]: - """Parses a campaign_search_term_insight path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignSearchTermInsights/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_shared_set_path( - customer_id: str, - campaign_id: str, - shared_set_id: str, - ) -> str: - """Returns a fully-qualified campaign_shared_set string.""" - return "customers/{customer_id}/campaignSharedSets/{campaign_id}~{shared_set_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - shared_set_id=shared_set_id, - ) - - @staticmethod - def parse_campaign_shared_set_path(path: str) -> Dict[str, str]: - """Parses a campaign_shared_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignSharedSets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_simulation_path( - customer_id: str, - campaign_id: str, - type: str, - modification_method: str, - start_date: str, - end_date: str, - ) -> str: - """Returns a fully-qualified campaign_simulation string.""" - return "customers/{customer_id}/campaignSimulations/{campaign_id}~{type}~{modification_method}~{start_date}~{end_date}".format( - customer_id=customer_id, - campaign_id=campaign_id, - type=type, - modification_method=modification_method, - start_date=start_date, - end_date=end_date, - ) - - @staticmethod - def parse_campaign_simulation_path(path: str) -> Dict[str, str]: - """Parses a campaign_simulation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignSimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def carrier_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified carrier_constant string.""" - return "carrierConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_carrier_constant_path(path: str) -> Dict[str, str]: - """Parses a carrier_constant path into its component segments.""" - m = re.match(r"^carrierConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def change_event_path( - customer_id: str, - timestamp_micros: str, - command_index: str, - mutate_index: str, - ) -> str: - """Returns a fully-qualified change_event string.""" - return "customers/{customer_id}/changeEvents/{timestamp_micros}~{command_index}~{mutate_index}".format( - customer_id=customer_id, - timestamp_micros=timestamp_micros, - command_index=command_index, - mutate_index=mutate_index, - ) - - @staticmethod - def parse_change_event_path(path: str) -> Dict[str, str]: - """Parses a change_event path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/changeEvents/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def change_status_path( - customer_id: str, - change_status_id: str, - ) -> str: - """Returns a fully-qualified change_status string.""" - return "customers/{customer_id}/changeStatus/{change_status_id}".format( - customer_id=customer_id, - change_status_id=change_status_id, - ) - - @staticmethod - def parse_change_status_path(path: str) -> Dict[str, str]: - """Parses a change_status path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/changeStatus/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def channel_aggregate_asset_view_path( - customer_id: str, - advertising_channel_type: str, - asset_id: str, - asset_source: str, - field_type: str, - ) -> str: - """Returns a fully-qualified channel_aggregate_asset_view string.""" - return "customers/{customer_id}/channelAggregateAssetViews/{advertising_channel_type}~{asset_id}~{asset_source}~{field_type}".format( - customer_id=customer_id, - advertising_channel_type=advertising_channel_type, - asset_id=asset_id, - asset_source=asset_source, - field_type=field_type, - ) - - @staticmethod - def parse_channel_aggregate_asset_view_path(path: str) -> Dict[str, str]: - """Parses a channel_aggregate_asset_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/channelAggregateAssetViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def click_view_path( - customer_id: str, - date: str, - gclid: str, - ) -> str: - """Returns a fully-qualified click_view string.""" - return "customers/{customer_id}/clickViews/{date}~{gclid}".format( - customer_id=customer_id, - date=date, - gclid=gclid, - ) - - @staticmethod - def parse_click_view_path(path: str) -> Dict[str, str]: - """Parses a click_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/clickViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def combined_audience_path( - customer_id: str, - combined_audience_id: str, - ) -> str: - """Returns a fully-qualified combined_audience string.""" - return "customers/{customer_id}/combinedAudiences/{combined_audience_id}".format( - customer_id=customer_id, - combined_audience_id=combined_audience_id, - ) - - @staticmethod - def parse_combined_audience_path(path: str) -> Dict[str, str]: - """Parses a combined_audience path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/combinedAudiences/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def content_criterion_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified content_criterion_view string.""" - return "customers/{customer_id}/contentCriterionViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_content_criterion_view_path(path: str) -> Dict[str, str]: - """Parses a content_criterion_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/contentCriterionViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_action_path( - customer_id: str, - conversion_action_id: str, - ) -> str: - """Returns a fully-qualified conversion_action string.""" - return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( - customer_id=customer_id, - conversion_action_id=conversion_action_id, - ) - - @staticmethod - def parse_conversion_action_path(path: str) -> Dict[str, str]: - """Parses a conversion_action path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionActions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_custom_variable_path( - customer_id: str, - conversion_custom_variable_id: str, - ) -> str: - """Returns a fully-qualified conversion_custom_variable string.""" - return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( - customer_id=customer_id, - conversion_custom_variable_id=conversion_custom_variable_id, - ) - - @staticmethod - def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: - """Parses a conversion_custom_variable path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_goal_campaign_config_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified conversion_goal_campaign_config string.""" - return "customers/{customer_id}/conversionGoalCampaignConfigs/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_conversion_goal_campaign_config_path(path: str) -> Dict[str, str]: - """Parses a conversion_goal_campaign_config path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionGoalCampaignConfigs/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_value_rule_path( - customer_id: str, - conversion_value_rule_id: str, - ) -> str: - """Returns a fully-qualified conversion_value_rule string.""" - return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( - customer_id=customer_id, - conversion_value_rule_id=conversion_value_rule_id, - ) - - @staticmethod - def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: - """Parses a conversion_value_rule path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_value_rule_set_path( - customer_id: str, - conversion_value_rule_set_id: str, - ) -> str: - """Returns a fully-qualified conversion_value_rule_set string.""" - return "customers/{customer_id}/conversionValueRuleSets/{conversion_value_rule_set_id}".format( - customer_id=customer_id, - conversion_value_rule_set_id=conversion_value_rule_set_id, - ) - - @staticmethod - def parse_conversion_value_rule_set_path(path: str) -> Dict[str, str]: - """Parses a conversion_value_rule_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionValueRuleSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def currency_constant_path( - code: str, - ) -> str: - """Returns a fully-qualified currency_constant string.""" - return "currencyConstants/{code}".format( - code=code, - ) - - @staticmethod - def parse_currency_constant_path(path: str) -> Dict[str, str]: - """Parses a currency_constant path into its component segments.""" - m = re.match(r"^currencyConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def custom_audience_path( - customer_id: str, - custom_audience_id: str, - ) -> str: - """Returns a fully-qualified custom_audience string.""" - return "customers/{customer_id}/customAudiences/{custom_audience_id}".format( - customer_id=customer_id, - custom_audience_id=custom_audience_id, - ) - - @staticmethod - def parse_custom_audience_path(path: str) -> Dict[str, str]: - """Parses a custom_audience path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customAudiences/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def custom_conversion_goal_path( - customer_id: str, - goal_id: str, - ) -> str: - """Returns a fully-qualified custom_conversion_goal string.""" - return "customers/{customer_id}/customConversionGoals/{goal_id}".format( - customer_id=customer_id, - goal_id=goal_id, - ) - - @staticmethod - def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: - """Parses a custom_conversion_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def customer_asset_path( - customer_id: str, - asset_id: str, - field_type: str, - ) -> str: - """Returns a fully-qualified customer_asset string.""" - return "customers/{customer_id}/customerAssets/{asset_id}~{field_type}".format( - customer_id=customer_id, - asset_id=asset_id, - field_type=field_type, - ) - - @staticmethod - def parse_customer_asset_path(path: str) -> Dict[str, str]: - """Parses a customer_asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerAssets/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_asset_set_path( - customer_id: str, - asset_set_id: str, - ) -> str: - """Returns a fully-qualified customer_asset_set string.""" - return ( - "customers/{customer_id}/customerAssetSets/{asset_set_id}".format( - customer_id=customer_id, - asset_set_id=asset_set_id, - ) - ) - - @staticmethod - def parse_customer_asset_set_path(path: str) -> Dict[str, str]: - """Parses a customer_asset_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerAssetSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_client_path( - customer_id: str, - client_customer_id: str, - ) -> str: - """Returns a fully-qualified customer_client string.""" - return "customers/{customer_id}/customerClients/{client_customer_id}".format( - customer_id=customer_id, - client_customer_id=client_customer_id, - ) - - @staticmethod - def parse_customer_client_path(path: str) -> Dict[str, str]: - """Parses a customer_client path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerClients/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_client_link_path( - customer_id: str, - client_customer_id: str, - manager_link_id: str, - ) -> str: - """Returns a fully-qualified customer_client_link string.""" - return "customers/{customer_id}/customerClientLinks/{client_customer_id}~{manager_link_id}".format( - customer_id=customer_id, - client_customer_id=client_customer_id, - manager_link_id=manager_link_id, - ) - - @staticmethod - def parse_customer_client_link_path(path: str) -> Dict[str, str]: - """Parses a customer_client_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerClientLinks/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_conversion_goal_path( - customer_id: str, - category: str, - source: str, - ) -> str: - """Returns a fully-qualified customer_conversion_goal string.""" - return "customers/{customer_id}/customerConversionGoals/{category}~{source}".format( - customer_id=customer_id, - category=category, - source=source, - ) - - @staticmethod - def parse_customer_conversion_goal_path(path: str) -> Dict[str, str]: - """Parses a customer_conversion_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerConversionGoals/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_customizer_path( - customer_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified customer_customizer string.""" - return "customers/{customer_id}/customerCustomizers/{customizer_attribute_id}".format( - customer_id=customer_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_customer_customizer_path(path: str) -> Dict[str, str]: - """Parses a customer_customizer path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerCustomizers/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_label_path( - customer_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified customer_label string.""" - return "customers/{customer_id}/customerLabels/{label_id}".format( - customer_id=customer_id, - label_id=label_id, - ) - - @staticmethod - def parse_customer_label_path(path: str) -> Dict[str, str]: - """Parses a customer_label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerLabels/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_lifecycle_goal_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer_lifecycle_goal string.""" - return "customers/{customer_id}/customerLifecycleGoals".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_lifecycle_goal_path(path: str) -> Dict[str, str]: - """Parses a customer_lifecycle_goal path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerLifecycleGoals$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_manager_link_path( - customer_id: str, - manager_customer_id: str, - manager_link_id: str, - ) -> str: - """Returns a fully-qualified customer_manager_link string.""" - return "customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}".format( - customer_id=customer_id, - manager_customer_id=manager_customer_id, - manager_link_id=manager_link_id, - ) - - @staticmethod - def parse_customer_manager_link_path(path: str) -> Dict[str, str]: - """Parses a customer_manager_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerManagerLinks/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_negative_criterion_path( - customer_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified customer_negative_criterion string.""" - return "customers/{customer_id}/customerNegativeCriteria/{criterion_id}".format( - customer_id=customer_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_customer_negative_criterion_path(path: str) -> Dict[str, str]: - """Parses a customer_negative_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerNegativeCriteria/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_search_term_insight_path( - customer_id: str, - cluster_id: str, - ) -> str: - """Returns a fully-qualified customer_search_term_insight string.""" - return "customers/{customer_id}/customerSearchTermInsights/{cluster_id}".format( - customer_id=customer_id, - cluster_id=cluster_id, - ) - - @staticmethod - def parse_customer_search_term_insight_path(path: str) -> Dict[str, str]: - """Parses a customer_search_term_insight path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerSearchTermInsights/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_user_access_path( - customer_id: str, - user_id: str, - ) -> str: - """Returns a fully-qualified customer_user_access string.""" - return "customers/{customer_id}/customerUserAccesses/{user_id}".format( - customer_id=customer_id, - user_id=user_id, - ) - - @staticmethod - def parse_customer_user_access_path(path: str) -> Dict[str, str]: - """Parses a customer_user_access path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerUserAccesses/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customer_user_access_invitation_path( - customer_id: str, - invitation_id: str, - ) -> str: - """Returns a fully-qualified customer_user_access_invitation string.""" - return "customers/{customer_id}/customerUserAccessInvitations/{invitation_id}".format( - customer_id=customer_id, - invitation_id=invitation_id, - ) - - @staticmethod - def parse_customer_user_access_invitation_path(path: str) -> Dict[str, str]: - """Parses a customer_user_access_invitation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customerUserAccessInvitations/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def custom_interest_path( - customer_id: str, - custom_interest_id: str, - ) -> str: - """Returns a fully-qualified custom_interest string.""" - return "customers/{customer_id}/customInterests/{custom_interest_id}".format( - customer_id=customer_id, - custom_interest_id=custom_interest_id, - ) - - @staticmethod - def parse_custom_interest_path(path: str) -> Dict[str, str]: - """Parses a custom_interest path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customInterests/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def customizer_attribute_path( - customer_id: str, - customizer_attribute_id: str, - ) -> str: - """Returns a fully-qualified customizer_attribute string.""" - return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( - customer_id=customer_id, - customizer_attribute_id=customizer_attribute_id, - ) - - @staticmethod - def parse_customizer_attribute_path(path: str) -> Dict[str, str]: - """Parses a customizer_attribute path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def data_link_path( - customer_id: str, - product_link_id: str, - data_link_id: str, - ) -> str: - """Returns a fully-qualified data_link string.""" - return "customers/{customer_id}/dataLinks/{product_link_id}~{data_link_id}".format( - customer_id=customer_id, - product_link_id=product_link_id, - data_link_id=data_link_id, - ) - - @staticmethod - def parse_data_link_path(path: str) -> Dict[str, str]: - """Parses a data_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/dataLinks/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def detailed_demographic_path( - customer_id: str, - detailed_demographic_id: str, - ) -> str: - """Returns a fully-qualified detailed_demographic string.""" - return "customers/{customer_id}/detailedDemographics/{detailed_demographic_id}".format( - customer_id=customer_id, - detailed_demographic_id=detailed_demographic_id, - ) - - @staticmethod - def parse_detailed_demographic_path(path: str) -> Dict[str, str]: - """Parses a detailed_demographic path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/detailedDemographics/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def detail_placement_view_path( - customer_id: str, - ad_group_id: str, - base64_placement: str, - ) -> str: - """Returns a fully-qualified detail_placement_view string.""" - return "customers/{customer_id}/detailPlacementViews/{ad_group_id}~{base64_placement}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - base64_placement=base64_placement, - ) - - @staticmethod - def parse_detail_placement_view_path(path: str) -> Dict[str, str]: - """Parses a detail_placement_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/detailPlacementViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def display_keyword_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified display_keyword_view string.""" - return "customers/{customer_id}/displayKeywordViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_display_keyword_view_path(path: str) -> Dict[str, str]: - """Parses a display_keyword_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/displayKeywordViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def distance_view_path( - customer_id: str, - placeholder_chain_id: str, - distance_bucket: str, - ) -> str: - """Returns a fully-qualified distance_view string.""" - return "customers/{customer_id}/distanceViews/{placeholder_chain_id}~{distance_bucket}".format( - customer_id=customer_id, - placeholder_chain_id=placeholder_chain_id, - distance_bucket=distance_bucket, - ) - - @staticmethod - def parse_distance_view_path(path: str) -> Dict[str, str]: - """Parses a distance_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/distanceViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def domain_category_path( - customer_id: str, - campaign_id: str, - base64_category: str, - language_code: str, - ) -> str: - """Returns a fully-qualified domain_category string.""" - return "customers/{customer_id}/domainCategories/{campaign_id}~{base64_category}~{language_code}".format( - customer_id=customer_id, - campaign_id=campaign_id, - base64_category=base64_category, - language_code=language_code, - ) - - @staticmethod - def parse_domain_category_path(path: str) -> Dict[str, str]: - """Parses a domain_category path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/domainCategories/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def dynamic_search_ads_search_term_view_path( - customer_id: str, - ad_group_id: str, - search_term_fingerprint: str, - headline_fingerprint: str, - landing_page_fingerprint: str, - page_url_fingerprint: str, - ) -> str: - """Returns a fully-qualified dynamic_search_ads_search_term_view string.""" - return "customers/{customer_id}/dynamicSearchAdsSearchTermViews/{ad_group_id}~{search_term_fingerprint}~{headline_fingerprint}~{landing_page_fingerprint}~{page_url_fingerprint}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - search_term_fingerprint=search_term_fingerprint, - headline_fingerprint=headline_fingerprint, - landing_page_fingerprint=landing_page_fingerprint, - page_url_fingerprint=page_url_fingerprint, - ) - - @staticmethod - def parse_dynamic_search_ads_search_term_view_path( - path: str, - ) -> Dict[str, str]: - """Parses a dynamic_search_ads_search_term_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/dynamicSearchAdsSearchTermViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def expanded_landing_page_view_path( - customer_id: str, - expanded_final_url_fingerprint: str, - ) -> str: - """Returns a fully-qualified expanded_landing_page_view string.""" - return "customers/{customer_id}/expandedLandingPageViews/{expanded_final_url_fingerprint}".format( - customer_id=customer_id, - expanded_final_url_fingerprint=expanded_final_url_fingerprint, - ) - - @staticmethod - def parse_expanded_landing_page_view_path(path: str) -> Dict[str, str]: - """Parses a expanded_landing_page_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/expandedLandingPageViews/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def experiment_path( - customer_id: str, - trial_id: str, - ) -> str: - """Returns a fully-qualified experiment string.""" - return "customers/{customer_id}/experiments/{trial_id}".format( - customer_id=customer_id, - trial_id=trial_id, - ) - - @staticmethod - def parse_experiment_path(path: str) -> Dict[str, str]: - """Parses a experiment path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/experiments/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def experiment_arm_path( - customer_id: str, - trial_id: str, - trial_arm_id: str, - ) -> str: - """Returns a fully-qualified experiment_arm string.""" - return "customers/{customer_id}/experimentArms/{trial_id}~{trial_arm_id}".format( - customer_id=customer_id, - trial_id=trial_id, - trial_arm_id=trial_arm_id, - ) - - @staticmethod - def parse_experiment_arm_path(path: str) -> Dict[str, str]: - """Parses a experiment_arm path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/experimentArms/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def gender_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified gender_view string.""" - return "customers/{customer_id}/genderViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_gender_view_path(path: str) -> Dict[str, str]: - """Parses a gender_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/genderViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def geographic_view_path( - customer_id: str, - country_criterion_id: str, - location_type: str, - ) -> str: - """Returns a fully-qualified geographic_view string.""" - return "customers/{customer_id}/geographicViews/{country_criterion_id}~{location_type}".format( - customer_id=customer_id, - country_criterion_id=country_criterion_id, - location_type=location_type, - ) - - @staticmethod - def parse_geographic_view_path(path: str) -> Dict[str, str]: - """Parses a geographic_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/geographicViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def geo_target_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified geo_target_constant string.""" - return "geoTargetConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_geo_target_constant_path(path: str) -> Dict[str, str]: - """Parses a geo_target_constant path into its component segments.""" - m = re.match(r"^geoTargetConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def group_placement_view_path( - customer_id: str, - ad_group_id: str, - base64_placement: str, - ) -> str: - """Returns a fully-qualified group_placement_view string.""" - return "customers/{customer_id}/groupPlacementViews/{ad_group_id}~{base64_placement}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - base64_placement=base64_placement, - ) - - @staticmethod - def parse_group_placement_view_path(path: str) -> Dict[str, str]: - """Parses a group_placement_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/groupPlacementViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def hotel_group_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified hotel_group_view string.""" - return "customers/{customer_id}/hotelGroupViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_hotel_group_view_path(path: str) -> Dict[str, str]: - """Parses a hotel_group_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/hotelGroupViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def hotel_performance_view_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified hotel_performance_view string.""" - return "customers/{customer_id}/hotelPerformanceView".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_hotel_performance_view_path(path: str) -> Dict[str, str]: - """Parses a hotel_performance_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/hotelPerformanceView$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def hotel_reconciliation_path( - customer_id: str, - commission_id: str, - ) -> str: - """Returns a fully-qualified hotel_reconciliation string.""" - return "customers/{customer_id}/hotelReconciliations/{commission_id}".format( - customer_id=customer_id, - commission_id=commission_id, - ) - - @staticmethod - def parse_hotel_reconciliation_path(path: str) -> Dict[str, str]: - """Parses a hotel_reconciliation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/hotelReconciliations/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def income_range_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified income_range_view string.""" - return "customers/{customer_id}/incomeRangeViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_income_range_view_path(path: str) -> Dict[str, str]: - """Parses a income_range_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/incomeRangeViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_path( - customer_id: str, - keyword_plan_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan string.""" - return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( - customer_id=customer_id, - keyword_plan_id=keyword_plan_id, - ) - - @staticmethod - def parse_keyword_plan_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_ad_group_path( - customer_id: str, - keyword_plan_ad_group_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_ad_group string.""" - return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( - customer_id=customer_id, - keyword_plan_ad_group_id=keyword_plan_ad_group_id, - ) - - @staticmethod - def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_ad_group_keyword_path( - customer_id: str, - keyword_plan_ad_group_keyword_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_ad_group_keyword string.""" - return "customers/{customer_id}/keywordPlanAdGroupKeywords/{keyword_plan_ad_group_keyword_id}".format( - customer_id=customer_id, - keyword_plan_ad_group_keyword_id=keyword_plan_ad_group_keyword_id, - ) - - @staticmethod - def parse_keyword_plan_ad_group_keyword_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_ad_group_keyword path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanAdGroupKeywords/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_campaign_path( - customer_id: str, - keyword_plan_campaign_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_campaign string.""" - return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( - customer_id=customer_id, - keyword_plan_campaign_id=keyword_plan_campaign_id, - ) - - @staticmethod - def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_campaign_keyword_path( - customer_id: str, - keyword_plan_campaign_keyword_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_campaign_keyword string.""" - return "customers/{customer_id}/keywordPlanCampaignKeywords/{keyword_plan_campaign_keyword_id}".format( - customer_id=customer_id, - keyword_plan_campaign_keyword_id=keyword_plan_campaign_keyword_id, - ) - - @staticmethod - def parse_keyword_plan_campaign_keyword_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_campaign_keyword path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanCampaignKeywords/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_theme_constant_path( - express_category_id: str, - express_sub_category_id: str, - ) -> str: - """Returns a fully-qualified keyword_theme_constant string.""" - return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( - express_category_id=express_category_id, - express_sub_category_id=express_sub_category_id, - ) - - @staticmethod - def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: - """Parses a keyword_theme_constant path into its component segments.""" - m = re.match( - r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified keyword_view string.""" - return "customers/{customer_id}/keywordViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_keyword_view_path(path: str) -> Dict[str, str]: - """Parses a keyword_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def label_path( - customer_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified label string.""" - return "customers/{customer_id}/labels/{label_id}".format( - customer_id=customer_id, - label_id=label_id, - ) - - @staticmethod - def parse_label_path(path: str) -> Dict[str, str]: - """Parses a label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/labels/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def landing_page_view_path( - customer_id: str, - unexpanded_final_url_fingerprint: str, - ) -> str: - """Returns a fully-qualified landing_page_view string.""" - return "customers/{customer_id}/landingPageViews/{unexpanded_final_url_fingerprint}".format( - customer_id=customer_id, - unexpanded_final_url_fingerprint=unexpanded_final_url_fingerprint, - ) - - @staticmethod - def parse_landing_page_view_path(path: str) -> Dict[str, str]: - """Parses a landing_page_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/landingPageViews/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def language_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified language_constant string.""" - return "languageConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_language_constant_path(path: str) -> Dict[str, str]: - """Parses a language_constant path into its component segments.""" - m = re.match(r"^languageConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def lead_form_submission_data_path( - customer_id: str, - lead_form_user_submission_id: str, - ) -> str: - """Returns a fully-qualified lead_form_submission_data string.""" - return "customers/{customer_id}/leadFormSubmissionData/{lead_form_user_submission_id}".format( - customer_id=customer_id, - lead_form_user_submission_id=lead_form_user_submission_id, - ) - - @staticmethod - def parse_lead_form_submission_data_path(path: str) -> Dict[str, str]: - """Parses a lead_form_submission_data path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/leadFormSubmissionData/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def life_event_path( - customer_id: str, - life_event_id: str, - ) -> str: - """Returns a fully-qualified life_event string.""" - return "customers/{customer_id}/lifeEvents/{life_event_id}".format( - customer_id=customer_id, - life_event_id=life_event_id, - ) - - @staticmethod - def parse_life_event_path(path: str) -> Dict[str, str]: - """Parses a life_event path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/lifeEvents/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def local_services_employee_path( - customer_id: str, - gls_employee_id: str, - ) -> str: - """Returns a fully-qualified local_services_employee string.""" - return "customers/{customer_id}/localServicesEmployees/{gls_employee_id}".format( - customer_id=customer_id, - gls_employee_id=gls_employee_id, - ) - - @staticmethod - def parse_local_services_employee_path(path: str) -> Dict[str, str]: - """Parses a local_services_employee path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/localServicesEmployees/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def local_services_lead_path( - customer_id: str, - local_services_lead_id: str, - ) -> str: - """Returns a fully-qualified local_services_lead string.""" - return "customers/{customer_id}/localServicesLeads/{local_services_lead_id}".format( - customer_id=customer_id, - local_services_lead_id=local_services_lead_id, - ) - - @staticmethod - def parse_local_services_lead_path(path: str) -> Dict[str, str]: - """Parses a local_services_lead path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/localServicesLeads/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def local_services_lead_conversation_path( - customer_id: str, - local_services_lead_conversation_id: str, - ) -> str: - """Returns a fully-qualified local_services_lead_conversation string.""" - return "customers/{customer_id}/localServicesLeadConversations/{local_services_lead_conversation_id}".format( - customer_id=customer_id, - local_services_lead_conversation_id=local_services_lead_conversation_id, - ) - - @staticmethod - def parse_local_services_lead_conversation_path( - path: str, - ) -> Dict[str, str]: - """Parses a local_services_lead_conversation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/localServicesLeadConversations/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def local_services_verification_artifact_path( - customer_id: str, - gls_verification_artifact_id: str, - ) -> str: - """Returns a fully-qualified local_services_verification_artifact string.""" - return "customers/{customer_id}/localServicesVerificationArtifacts/{gls_verification_artifact_id}".format( - customer_id=customer_id, - gls_verification_artifact_id=gls_verification_artifact_id, - ) - - @staticmethod - def parse_local_services_verification_artifact_path( - path: str, - ) -> Dict[str, str]: - """Parses a local_services_verification_artifact path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/localServicesVerificationArtifacts/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def location_view_path( - customer_id: str, - campaign_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified location_view string.""" - return "customers/{customer_id}/locationViews/{campaign_id}~{criterion_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_location_view_path(path: str) -> Dict[str, str]: - """Parses a location_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/locationViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def managed_placement_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified managed_placement_view string.""" - return "customers/{customer_id}/managedPlacementViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_managed_placement_view_path(path: str) -> Dict[str, str]: - """Parses a managed_placement_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/managedPlacementViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def media_file_path( - customer_id: str, - media_file_id: str, - ) -> str: - """Returns a fully-qualified media_file string.""" - return "customers/{customer_id}/mediaFiles/{media_file_id}".format( - customer_id=customer_id, - media_file_id=media_file_id, - ) - - @staticmethod - def parse_media_file_path(path: str) -> Dict[str, str]: - """Parses a media_file path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/mediaFiles/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def mobile_app_category_constant_path( - mobile_app_category_id: str, - ) -> str: - """Returns a fully-qualified mobile_app_category_constant string.""" - return "mobileAppCategoryConstants/{mobile_app_category_id}".format( - mobile_app_category_id=mobile_app_category_id, - ) - - @staticmethod - def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: - """Parses a mobile_app_category_constant path into its component segments.""" - m = re.match( - r"^mobileAppCategoryConstants/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def mobile_device_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified mobile_device_constant string.""" - return "mobileDeviceConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_mobile_device_constant_path(path: str) -> Dict[str, str]: - """Parses a mobile_device_constant path into its component segments.""" - m = re.match(r"^mobileDeviceConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def offline_conversion_upload_client_summary_path( - customer_id: str, - client: str, - ) -> str: - """Returns a fully-qualified offline_conversion_upload_client_summary string.""" - return "customers/{customer_id}/offlineConversionUploadClientSummaries/{client}".format( - customer_id=customer_id, - client=client, - ) - - @staticmethod - def parse_offline_conversion_upload_client_summary_path( - path: str, - ) -> Dict[str, str]: - """Parses a offline_conversion_upload_client_summary path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/offlineConversionUploadClientSummaries/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def offline_conversion_upload_conversion_action_summary_path( - customer_id: str, - conversion_type_id: str, - client: str, - ) -> str: - """Returns a fully-qualified offline_conversion_upload_conversion_action_summary string.""" - return "customers/{customer_id}/offlineConversionUploadConversionActionSummaries/{conversion_type_id}~{client}".format( - customer_id=customer_id, - conversion_type_id=conversion_type_id, - client=client, - ) - - @staticmethod - def parse_offline_conversion_upload_conversion_action_summary_path( - path: str, - ) -> Dict[str, str]: - """Parses a offline_conversion_upload_conversion_action_summary path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/offlineConversionUploadConversionActionSummaries/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def offline_user_data_job_path( - customer_id: str, - offline_user_data_update_id: str, - ) -> str: - """Returns a fully-qualified offline_user_data_job string.""" - return "customers/{customer_id}/offlineUserDataJobs/{offline_user_data_update_id}".format( - customer_id=customer_id, - offline_user_data_update_id=offline_user_data_update_id, - ) - - @staticmethod - def parse_offline_user_data_job_path(path: str) -> Dict[str, str]: - """Parses a offline_user_data_job path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/offlineUserDataJobs/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def operating_system_version_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified operating_system_version_constant string.""" - return "operatingSystemVersionConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_operating_system_version_constant_path( - path: str, - ) -> Dict[str, str]: - """Parses a operating_system_version_constant path into its component segments.""" - m = re.match( - r"^operatingSystemVersionConstants/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def paid_organic_search_term_view_path( - customer_id: str, - campaign_id: str, - ad_group_id: str, - base64_search_term: str, - ) -> str: - """Returns a fully-qualified paid_organic_search_term_view string.""" - return "customers/{customer_id}/paidOrganicSearchTermViews/{campaign_id}~{ad_group_id}~{base64_search_term}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ad_group_id=ad_group_id, - base64_search_term=base64_search_term, - ) - - @staticmethod - def parse_paid_organic_search_term_view_path(path: str) -> Dict[str, str]: - """Parses a paid_organic_search_term_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/paidOrganicSearchTermViews/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def parental_status_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified parental_status_view string.""" - return "customers/{customer_id}/parentalStatusViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_parental_status_view_path(path: str) -> Dict[str, str]: - """Parses a parental_status_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/parentalStatusViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def payments_account_path( - customer_id: str, - payments_account_id: str, - ) -> str: - """Returns a fully-qualified payments_account string.""" - return "customers/{customer_id}/paymentsAccounts/{payments_account_id}".format( - customer_id=customer_id, - payments_account_id=payments_account_id, - ) - - @staticmethod - def parse_payments_account_path(path: str) -> Dict[str, str]: - """Parses a payments_account path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/paymentsAccounts/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def performance_max_placement_view_path( - customer_id: str, - base_64_placement: str, - ) -> str: - """Returns a fully-qualified performance_max_placement_view string.""" - return "customers/{customer_id}/performanceMaxPlacementViews/{base_64_placement}".format( - customer_id=customer_id, - base_64_placement=base_64_placement, - ) - - @staticmethod - def parse_performance_max_placement_view_path(path: str) -> Dict[str, str]: - """Parses a performance_max_placement_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/performanceMaxPlacementViews/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def per_store_view_path( - customer_id: str, - place_id: str, - ) -> str: - """Returns a fully-qualified per_store_view string.""" - return "customers/{customer_id}/perStoreViews/{place_id}".format( - customer_id=customer_id, - place_id=place_id, - ) - - @staticmethod - def parse_per_store_view_path(path: str) -> Dict[str, str]: - """Parses a per_store_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/perStoreViews/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def product_category_constant_path( - level: str, - category_id: str, - ) -> str: - """Returns a fully-qualified product_category_constant string.""" - return "productCategoryConstants/{level}~{category_id}".format( - level=level, - category_id=category_id, - ) - - @staticmethod - def parse_product_category_constant_path(path: str) -> Dict[str, str]: - """Parses a product_category_constant path into its component segments.""" - m = re.match( - r"^productCategoryConstants/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def product_group_view_path( - customer_id: str, - adgroup_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified product_group_view string.""" - return "customers/{customer_id}/productGroupViews/{adgroup_id}~{criterion_id}".format( - customer_id=customer_id, - adgroup_id=adgroup_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_product_group_view_path(path: str) -> Dict[str, str]: - """Parses a product_group_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/productGroupViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def product_link_path( - customer_id: str, - product_link_id: str, - ) -> str: - """Returns a fully-qualified product_link string.""" - return "customers/{customer_id}/productLinks/{product_link_id}".format( - customer_id=customer_id, - product_link_id=product_link_id, - ) - - @staticmethod - def parse_product_link_path(path: str) -> Dict[str, str]: - """Parses a product_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/productLinks/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def product_link_invitation_path( - customer_id: str, - customer_invitation_id: str, - ) -> str: - """Returns a fully-qualified product_link_invitation string.""" - return "customers/{customer_id}/productLinkInvitations/{customer_invitation_id}".format( - customer_id=customer_id, - customer_invitation_id=customer_invitation_id, - ) - - @staticmethod - def parse_product_link_invitation_path(path: str) -> Dict[str, str]: - """Parses a product_link_invitation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/productLinkInvitations/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def qualifying_question_path( - qualifying_question_id: str, - ) -> str: - """Returns a fully-qualified qualifying_question string.""" - return "qualifyingQuestions/{qualifying_question_id}".format( - qualifying_question_id=qualifying_question_id, - ) - - @staticmethod - def parse_qualifying_question_path(path: str) -> Dict[str, str]: - """Parses a qualifying_question path into its component segments.""" - m = re.match( - r"^qualifyingQuestions/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def recommendation_path( - customer_id: str, - recommendation_id: str, - ) -> str: - """Returns a fully-qualified recommendation string.""" - return "customers/{customer_id}/recommendations/{recommendation_id}".format( - customer_id=customer_id, - recommendation_id=recommendation_id, - ) - - @staticmethod - def parse_recommendation_path(path: str) -> Dict[str, str]: - """Parses a recommendation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/recommendations/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def recommendation_subscription_path( - customer_id: str, - recommendation_type: str, - ) -> str: - """Returns a fully-qualified recommendation_subscription string.""" - return "customers/{customer_id}/recommendationSubscriptions/{recommendation_type}".format( - customer_id=customer_id, - recommendation_type=recommendation_type, - ) - - @staticmethod - def parse_recommendation_subscription_path(path: str) -> Dict[str, str]: - """Parses a recommendation_subscription path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/recommendationSubscriptions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def remarketing_action_path( - customer_id: str, - remarketing_action_id: str, - ) -> str: - """Returns a fully-qualified remarketing_action string.""" - return "customers/{customer_id}/remarketingActions/{remarketing_action_id}".format( - customer_id=customer_id, - remarketing_action_id=remarketing_action_id, - ) - - @staticmethod - def parse_remarketing_action_path(path: str) -> Dict[str, str]: - """Parses a remarketing_action path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/remarketingActions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def search_term_view_path( - customer_id: str, - campaign_id: str, - ad_group_id: str, - query: str, - ) -> str: - """Returns a fully-qualified search_term_view string.""" - return "customers/{customer_id}/searchTermViews/{campaign_id}~{ad_group_id}~{query}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ad_group_id=ad_group_id, - query=query, - ) - - @staticmethod - def parse_search_term_view_path(path: str) -> Dict[str, str]: - """Parses a search_term_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/searchTermViews/(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def shared_criterion_path( - customer_id: str, - shared_set_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified shared_criterion string.""" - return "customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}".format( - customer_id=customer_id, - shared_set_id=shared_set_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_shared_criterion_path(path: str) -> Dict[str, str]: - """Parses a shared_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/sharedCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def shared_set_path( - customer_id: str, - shared_set_id: str, - ) -> str: - """Returns a fully-qualified shared_set string.""" - return "customers/{customer_id}/sharedSets/{shared_set_id}".format( - customer_id=customer_id, - shared_set_id=shared_set_id, - ) - - @staticmethod - def parse_shared_set_path(path: str) -> Dict[str, str]: - """Parses a shared_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/sharedSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def shopping_performance_view_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified shopping_performance_view string.""" - return "customers/{customer_id}/shoppingPerformanceView".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_shopping_performance_view_path(path: str) -> Dict[str, str]: - """Parses a shopping_performance_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/shoppingPerformanceView$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def shopping_product_path( - customer_id: str, - merchant_center_id: str, - channel: str, - language_code: str, - feed_label: str, - item_id: str, - ) -> str: - """Returns a fully-qualified shopping_product string.""" - return "customers/{customer_id}/shoppingProducts/{merchant_center_id}~{channel}~{language_code}~{feed_label}~{item_id}".format( - customer_id=customer_id, - merchant_center_id=merchant_center_id, - channel=channel, - language_code=language_code, - feed_label=feed_label, - item_id=item_id, - ) - - @staticmethod - def parse_shopping_product_path(path: str) -> Dict[str, str]: - """Parses a shopping_product path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/shoppingProducts/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def smart_campaign_search_term_view_path( - customer_id: str, - campaign_id: str, - query: str, - ) -> str: - """Returns a fully-qualified smart_campaign_search_term_view string.""" - return "customers/{customer_id}/smartCampaignSearchTermViews/{campaign_id}~{query}".format( - customer_id=customer_id, - campaign_id=campaign_id, - query=query, - ) - - @staticmethod - def parse_smart_campaign_search_term_view_path(path: str) -> Dict[str, str]: - """Parses a smart_campaign_search_term_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/smartCampaignSearchTermViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def smart_campaign_setting_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified smart_campaign_setting string.""" - return "customers/{customer_id}/smartCampaignSettings/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_smart_campaign_setting_path(path: str) -> Dict[str, str]: - """Parses a smart_campaign_setting path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/smartCampaignSettings/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def third_party_app_analytics_link_path( - customer_id: str, - customer_link_id: str, - ) -> str: - """Returns a fully-qualified third_party_app_analytics_link string.""" - return "customers/{customer_id}/thirdPartyAppAnalyticsLinks/{customer_link_id}".format( - customer_id=customer_id, - customer_link_id=customer_link_id, - ) - - @staticmethod - def parse_third_party_app_analytics_link_path(path: str) -> Dict[str, str]: - """Parses a third_party_app_analytics_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/thirdPartyAppAnalyticsLinks/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def topic_constant_path( - topic_id: str, - ) -> str: - """Returns a fully-qualified topic_constant string.""" - return "topicConstants/{topic_id}".format( - topic_id=topic_id, - ) - - @staticmethod - def parse_topic_constant_path(path: str) -> Dict[str, str]: - """Parses a topic_constant path into its component segments.""" - m = re.match(r"^topicConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def topic_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified topic_view string.""" - return "customers/{customer_id}/topicViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_topic_view_path(path: str) -> Dict[str, str]: - """Parses a topic_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/topicViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def travel_activity_group_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified travel_activity_group_view string.""" - return "customers/{customer_id}/travelActivityGroupViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_travel_activity_group_view_path(path: str) -> Dict[str, str]: - """Parses a travel_activity_group_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/travelActivityGroupViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def travel_activity_performance_view_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified travel_activity_performance_view string.""" - return "customers/{customer_id}/travelActivityPerformanceViews".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_travel_activity_performance_view_path( - path: str, - ) -> Dict[str, str]: - """Parses a travel_activity_performance_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/travelActivityPerformanceViews$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def user_interest_path( - customer_id: str, - user_interest_id: str, - ) -> str: - """Returns a fully-qualified user_interest string.""" - return ( - "customers/{customer_id}/userInterests/{user_interest_id}".format( - customer_id=customer_id, - user_interest_id=user_interest_id, - ) - ) - - @staticmethod - def parse_user_interest_path(path: str) -> Dict[str, str]: - """Parses a user_interest path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/userInterests/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def user_list_path( - customer_id: str, - user_list_id: str, - ) -> str: - """Returns a fully-qualified user_list string.""" - return "customers/{customer_id}/userLists/{user_list_id}".format( - customer_id=customer_id, - user_list_id=user_list_id, - ) - - @staticmethod - def parse_user_list_path(path: str) -> Dict[str, str]: - """Parses a user_list path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/userLists/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def user_list_customer_type_path( - customer_id: str, - user_list_id: str, - semantic_label: str, - ) -> str: - """Returns a fully-qualified user_list_customer_type string.""" - return "customers/{customer_id}/userListCustomerTypes/{user_list_id}~{semantic_label}".format( - customer_id=customer_id, - user_list_id=user_list_id, - semantic_label=semantic_label, - ) - - @staticmethod - def parse_user_list_customer_type_path(path: str) -> Dict[str, str]: - """Parses a user_list_customer_type path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/userListCustomerTypes/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def user_location_view_path( - customer_id: str, - country_criterion_id: str, - is_targeting_location: str, - ) -> str: - """Returns a fully-qualified user_location_view string.""" - return "customers/{customer_id}/userLocationViews/{country_criterion_id}~{is_targeting_location}".format( - customer_id=customer_id, - country_criterion_id=country_criterion_id, - is_targeting_location=is_targeting_location, - ) - - @staticmethod - def parse_user_location_view_path(path: str) -> Dict[str, str]: - """Parses a user_location_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/userLocationViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def video_path( - customer_id: str, - video_id: str, - ) -> str: - """Returns a fully-qualified video string.""" - return "customers/{customer_id}/videos/{video_id}".format( - customer_id=customer_id, - video_id=video_id, - ) - - @staticmethod - def parse_video_path(path: str) -> Dict[str, str]: - """Parses a video path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/videos/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def webpage_view_path( - customer_id: str, - ad_group_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified webpage_view string.""" - return "customers/{customer_id}/webpageViews/{ad_group_id}~{criterion_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_webpage_view_path(path: str) -> Dict[str, str]: - """Parses a webpage_view path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/webpageViews/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = GoogleAdsServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = GoogleAdsServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - GoogleAdsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = GoogleAdsServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - GoogleAdsServiceTransport, - Callable[..., GoogleAdsServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the google ads service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,GoogleAdsServiceTransport,Callable[..., GoogleAdsServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the GoogleAdsServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = GoogleAdsServiceClient._read_environment_variables() - self._client_cert_source = ( - GoogleAdsServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = GoogleAdsServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, GoogleAdsServiceTransport) - if transport_provided: - # transport is a GoogleAdsServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(GoogleAdsServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or GoogleAdsServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[GoogleAdsServiceTransport], - Callable[..., GoogleAdsServiceTransport], - ] = ( - GoogleAdsServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., GoogleAdsServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.GoogleAdsServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.GoogleAdsService", - "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.ads.googleads.v19.services.GoogleAdsService", - "credentialsType": None, - } - ), - ) - - def search( - self, - request: Optional[ - Union[google_ads_service.SearchGoogleAdsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - query: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.SearchPager: - r"""Returns all rows that match the search query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ChangeEventError <>`__ - `ChangeStatusError <>`__ `ClickViewError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.SearchGoogleAdsRequest, dict]): - The request object. Request message for - [GoogleAdsService.Search][google.ads.googleads.v19.services.GoogleAdsService.Search]. - customer_id (str): - Required. The ID of the customer - being queried. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - query (str): - Required. The query string. - This corresponds to the ``query`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.google_ads_service.pagers.SearchPager: - Response message for - [GoogleAdsService.Search][google.ads.googleads.v19.services.GoogleAdsService.Search]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, query] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, google_ads_service.SearchGoogleAdsRequest): - request = google_ads_service.SearchGoogleAdsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if query is not None: - request.query = query - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.search] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.SearchPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def search_stream( - self, - request: Optional[ - Union[google_ads_service.SearchGoogleAdsStreamRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - query: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> Iterable[google_ads_service.SearchGoogleAdsStreamResponse]: - r"""Returns all rows that match the search stream query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ChangeEventError <>`__ - `ChangeStatusError <>`__ `ClickViewError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.SearchGoogleAdsStreamRequest, dict]): - The request object. Request message for - [GoogleAdsService.SearchStream][google.ads.googleads.v19.services.GoogleAdsService.SearchStream]. - customer_id (str): - Required. The ID of the customer - being queried. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - query (str): - Required. The query string. - This corresponds to the ``query`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SearchGoogleAdsStreamResponse]: - Response message for - [GoogleAdsService.SearchStream][google.ads.googleads.v19.services.GoogleAdsService.SearchStream]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, query] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, google_ads_service.SearchGoogleAdsStreamRequest - ): - request = google_ads_service.SearchGoogleAdsStreamRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if query is not None: - request.query = query - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.search_stream] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def mutate( - self, - request: Optional[ - Union[google_ads_service.MutateGoogleAdsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - mutate_operations: Optional[ - MutableSequence[google_ads_service.MutateOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> google_ads_service.MutateGoogleAdsResponse: - r"""Creates, updates, or removes resources. This method supports - atomic transactions with multiple types of resources. For - example, you can atomically create a campaign and a campaign - budget, or perform up to thousands of mutates atomically. - - This method is essentially a wrapper around a series of mutate - methods. The only features it offers over calling those methods - directly are: - - - Atomic transactions - - Temp resource names (described below) - - Somewhat reduced latency over making a series of mutate calls - - Note: Only resources that support atomic transactions are - included, so this method can't replace all calls to individual - services. - - Atomic Transaction Benefits - --------------------------- - - Atomicity makes error handling much easier. If you're making a - series of changes and one fails, it can leave your account in an - inconsistent state. With atomicity, you either reach the chosen - state directly, or the request fails and you can retry. - - Temp Resource Names - ------------------- - - Temp resource names are a special type of resource name used to - create a resource and reference that resource in the same - request. For example, if a campaign budget is created with - ``resource_name`` equal to ``customers/123/campaignBudgets/-1``, - that resource name can be reused in the ``Campaign.budget`` - field in the same request. That way, the two resources are - created and linked atomically. - - To create a temp resource name, put a negative number in the - part of the name that the server would normally allocate. - - Note: - - - Resources must be created with a temp name before the name - can be reused. For example, the previous - CampaignBudget+Campaign example would fail if the mutate - order was reversed. - - Temp names are not remembered across requests. - - There's no limit to the number of temp names in a request. - - Each temp name must use a unique negative number, even if the - resource types differ. - - Latency - ------- - - It's important to group mutates by resource type or the request - may time out and fail. Latency is roughly equal to a series of - calls to individual mutate methods, where each change in - resource type is a new call. For example, mutating 10 campaigns - then 10 ad groups is like 2 calls, while mutating 1 campaign, 1 - ad group, 1 campaign, 1 ad group is like 4 calls. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdGroupAdError <>`__ `AdGroupCriterionError <>`__ - `AdGroupError <>`__ `AssetError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `BiddingError <>`__ - `CampaignBudgetError <>`__ `CampaignCriterionError <>`__ - `CampaignError <>`__ `CampaignExperimentError <>`__ - `CampaignSharedSetError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `ConversionActionError <>`__ - `CriterionError <>`__ `CustomerFeedError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ - `DistinctError <>`__ `ExtensionFeedItemError <>`__ - `ExtensionSettingError <>`__ `FeedAttributeReferenceError <>`__ - `FeedError <>`__ `FeedItemError <>`__ `FeedItemSetError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `ImageError <>`__ - `InternalError <>`__ `KeywordPlanAdGroupKeywordError <>`__ - `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ - `LabelError <>`__ `ListOperationError <>`__ - `MediaUploadError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `PolicyFindingError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SharedSetError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ `UserListError <>`__ - `YoutubeVideoRegistrationError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateGoogleAdsRequest, dict]): - The request object. Request message for - [GoogleAdsService.Mutate][google.ads.googleads.v19.services.GoogleAdsService.Mutate]. - customer_id (str): - Required. The ID of the customer - whose resources are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - mutate_operations (MutableSequence[google.ads.googleads.v19.services.types.MutateOperation]): - Required. The list of operations to - perform on individual resources. - - This corresponds to the ``mutate_operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateGoogleAdsResponse: - Response message for - [GoogleAdsService.Mutate][google.ads.googleads.v19.services.GoogleAdsService.Mutate]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, mutate_operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, google_ads_service.MutateGoogleAdsRequest): - request = google_ads_service.MutateGoogleAdsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if mutate_operations is not None: - request.mutate_operations = mutate_operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.mutate] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "GoogleAdsServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("GoogleAdsServiceClient",) diff --git a/google/ads/googleads/v19/services/services/google_ads_service/pagers.py b/google/ads/googleads/v19/services/services/google_ads_service/pagers.py deleted file mode 100644 index 5ff10409f..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_service/pagers.py +++ /dev/null @@ -1,199 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import retry_async as retries_async -from typing import ( - Any, - AsyncIterator, - Awaitable, - Callable, - Sequence, - Tuple, - Iterator, - Union, -) - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] - OptionalAsyncRetry = Union[ - retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import google_ads_service - - -class SearchPager: - """A pager for iterating through ``search`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.SearchGoogleAdsResponse` object, and - provides an ``__iter__`` method to iterate through its - ``results`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``Search`` requests and continue to iterate - through the ``results`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.SearchGoogleAdsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[..., google_ads_service.SearchGoogleAdsResponse], - request: google_ads_service.SearchGoogleAdsRequest, - response: google_ads_service.SearchGoogleAdsResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.SearchGoogleAdsRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.SearchGoogleAdsResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = google_ads_service.SearchGoogleAdsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages(self) -> Iterator[google_ads_service.SearchGoogleAdsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __iter__(self) -> Iterator[google_ads_service.GoogleAdsRow]: - for page in self.pages: - yield from page.results - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) - - -class SearchAsyncPager: - """A pager for iterating through ``search`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.SearchGoogleAdsResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``results`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``Search`` requests and continue to iterate - through the ``results`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.SearchGoogleAdsResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[ - ..., Awaitable[google_ads_service.SearchGoogleAdsResponse] - ], - request: google_ads_service.SearchGoogleAdsRequest, - response: google_ads_service.SearchGoogleAdsResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.SearchGoogleAdsRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.SearchGoogleAdsResponse): - The initial response object. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = google_ads_service.SearchGoogleAdsRequest(request) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages( - self, - ) -> AsyncIterator[google_ads_service.SearchGoogleAdsResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __aiter__(self) -> AsyncIterator[google_ads_service.GoogleAdsRow]: - async def async_generator(): - async for page in self.pages: - for response in page.results: - yield response - - return async_generator() - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/google_ads_service/transports/base.py b/google/ads/googleads/v19/services/services/google_ads_service/transports/base.py deleted file mode 100644 index d54e54d88..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_service/transports/base.py +++ /dev/null @@ -1,206 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import google_ads_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class GoogleAdsServiceTransport(abc.ABC): - """Abstract transport class for GoogleAdsService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.search: gapic_v1.method.wrap_method( - self.search, - default_timeout=None, - client_info=client_info, - ), - self.search_stream: gapic_v1.method.wrap_method( - self.search_stream, - default_timeout=None, - client_info=client_info, - ), - self.mutate: gapic_v1.method.wrap_method( - self.mutate, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def search( - self, - ) -> Callable[ - [google_ads_service.SearchGoogleAdsRequest], - Union[ - google_ads_service.SearchGoogleAdsResponse, - Awaitable[google_ads_service.SearchGoogleAdsResponse], - ], - ]: - raise NotImplementedError() - - @property - def search_stream( - self, - ) -> Callable[ - [google_ads_service.SearchGoogleAdsStreamRequest], - Union[ - google_ads_service.SearchGoogleAdsStreamResponse, - Awaitable[google_ads_service.SearchGoogleAdsStreamResponse], - ], - ]: - raise NotImplementedError() - - @property - def mutate( - self, - ) -> Callable[ - [google_ads_service.MutateGoogleAdsRequest], - Union[ - google_ads_service.MutateGoogleAdsResponse, - Awaitable[google_ads_service.MutateGoogleAdsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("GoogleAdsServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/google_ads_service/transports/grpc.py b/google/ads/googleads/v19/services/services/google_ads_service/transports/grpc.py deleted file mode 100644 index 583726ae6..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_service/transports/grpc.py +++ /dev/null @@ -1,535 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import google_ads_service -from .base import GoogleAdsServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.GoogleAdsService", - "rpcName": str(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.ads.googleads.v19.services.GoogleAdsService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class GoogleAdsServiceGrpcTransport(GoogleAdsServiceTransport): - """gRPC backend transport for GoogleAdsService. - - Service to fetch data and metrics across resources. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def search( - self, - ) -> Callable[ - [google_ads_service.SearchGoogleAdsRequest], - google_ads_service.SearchGoogleAdsResponse, - ]: - r"""Return a callable for the search method over gRPC. - - Returns all rows that match the search query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ChangeEventError <>`__ - `ChangeStatusError <>`__ `ClickViewError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.SearchGoogleAdsRequest], - ~.SearchGoogleAdsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # 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._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.GoogleAdsService/Search", - request_serializer=google_ads_service.SearchGoogleAdsRequest.serialize, - response_deserializer=google_ads_service.SearchGoogleAdsResponse.deserialize, - ) - return self._stubs["search"] - - @property - def search_stream( - self, - ) -> Callable[ - [google_ads_service.SearchGoogleAdsStreamRequest], - google_ads_service.SearchGoogleAdsStreamResponse, - ]: - r"""Return a callable for the search stream method over gRPC. - - Returns all rows that match the search stream query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ChangeEventError <>`__ - `ChangeStatusError <>`__ `ClickViewError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.SearchGoogleAdsStreamRequest], - ~.SearchGoogleAdsStreamResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "search_stream" not in self._stubs: - self._stubs["search_stream"] = self._logged_channel.unary_stream( - "/google.ads.googleads.v19.services.GoogleAdsService/SearchStream", - request_serializer=google_ads_service.SearchGoogleAdsStreamRequest.serialize, - response_deserializer=google_ads_service.SearchGoogleAdsStreamResponse.deserialize, - ) - return self._stubs["search_stream"] - - @property - def mutate( - self, - ) -> Callable[ - [google_ads_service.MutateGoogleAdsRequest], - google_ads_service.MutateGoogleAdsResponse, - ]: - r"""Return a callable for the mutate method over gRPC. - - Creates, updates, or removes resources. This method supports - atomic transactions with multiple types of resources. For - example, you can atomically create a campaign and a campaign - budget, or perform up to thousands of mutates atomically. - - This method is essentially a wrapper around a series of mutate - methods. The only features it offers over calling those methods - directly are: - - - Atomic transactions - - Temp resource names (described below) - - Somewhat reduced latency over making a series of mutate calls - - Note: Only resources that support atomic transactions are - included, so this method can't replace all calls to individual - services. - - Atomic Transaction Benefits - --------------------------- - - Atomicity makes error handling much easier. If you're making a - series of changes and one fails, it can leave your account in an - inconsistent state. With atomicity, you either reach the chosen - state directly, or the request fails and you can retry. - - Temp Resource Names - ------------------- - - Temp resource names are a special type of resource name used to - create a resource and reference that resource in the same - request. For example, if a campaign budget is created with - ``resource_name`` equal to ``customers/123/campaignBudgets/-1``, - that resource name can be reused in the ``Campaign.budget`` - field in the same request. That way, the two resources are - created and linked atomically. - - To create a temp resource name, put a negative number in the - part of the name that the server would normally allocate. - - Note: - - - Resources must be created with a temp name before the name - can be reused. For example, the previous - CampaignBudget+Campaign example would fail if the mutate - order was reversed. - - Temp names are not remembered across requests. - - There's no limit to the number of temp names in a request. - - Each temp name must use a unique negative number, even if the - resource types differ. - - Latency - ------- - - It's important to group mutates by resource type or the request - may time out and fail. Latency is roughly equal to a series of - calls to individual mutate methods, where each change in - resource type is a new call. For example, mutating 10 campaigns - then 10 ad groups is like 2 calls, while mutating 1 campaign, 1 - ad group, 1 campaign, 1 ad group is like 4 calls. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdGroupAdError <>`__ `AdGroupCriterionError <>`__ - `AdGroupError <>`__ `AssetError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `BiddingError <>`__ - `CampaignBudgetError <>`__ `CampaignCriterionError <>`__ - `CampaignError <>`__ `CampaignExperimentError <>`__ - `CampaignSharedSetError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `ConversionActionError <>`__ - `CriterionError <>`__ `CustomerFeedError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ - `DistinctError <>`__ `ExtensionFeedItemError <>`__ - `ExtensionSettingError <>`__ `FeedAttributeReferenceError <>`__ - `FeedError <>`__ `FeedItemError <>`__ `FeedItemSetError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `ImageError <>`__ - `InternalError <>`__ `KeywordPlanAdGroupKeywordError <>`__ - `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ - `LabelError <>`__ `ListOperationError <>`__ - `MediaUploadError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `PolicyFindingError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SharedSetError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ `UserListError <>`__ - `YoutubeVideoRegistrationError <>`__ - - Returns: - Callable[[~.MutateGoogleAdsRequest], - ~.MutateGoogleAdsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate" not in self._stubs: - self._stubs["mutate"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.GoogleAdsService/Mutate", - request_serializer=google_ads_service.MutateGoogleAdsRequest.serialize, - response_deserializer=google_ads_service.MutateGoogleAdsResponse.deserialize, - ) - return self._stubs["mutate"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("GoogleAdsServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/google_ads_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/google_ads_service/transports/grpc_asyncio.py deleted file mode 100644 index 383774c37..000000000 --- a/google/ads/googleads/v19/services/services/google_ads_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,566 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import google_ads_service -from .base import GoogleAdsServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.GoogleAdsService", - "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.ads.googleads.v19.services.GoogleAdsService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class GoogleAdsServiceGrpcAsyncIOTransport(GoogleAdsServiceTransport): - """gRPC AsyncIO backend transport for GoogleAdsService. - - Service to fetch data and metrics across resources. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def search( - self, - ) -> Callable[ - [google_ads_service.SearchGoogleAdsRequest], - Awaitable[google_ads_service.SearchGoogleAdsResponse], - ]: - r"""Return a callable for the search method over gRPC. - - Returns all rows that match the search query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ChangeEventError <>`__ - `ChangeStatusError <>`__ `ClickViewError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.SearchGoogleAdsRequest], - Awaitable[~.SearchGoogleAdsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # 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._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.GoogleAdsService/Search", - request_serializer=google_ads_service.SearchGoogleAdsRequest.serialize, - response_deserializer=google_ads_service.SearchGoogleAdsResponse.deserialize, - ) - return self._stubs["search"] - - @property - def search_stream( - self, - ) -> Callable[ - [google_ads_service.SearchGoogleAdsStreamRequest], - Awaitable[google_ads_service.SearchGoogleAdsStreamResponse], - ]: - r"""Return a callable for the search stream method over gRPC. - - Returns all rows that match the search stream query. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ChangeEventError <>`__ - `ChangeStatusError <>`__ `ClickViewError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.SearchGoogleAdsStreamRequest], - Awaitable[~.SearchGoogleAdsStreamResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "search_stream" not in self._stubs: - self._stubs["search_stream"] = self._logged_channel.unary_stream( - "/google.ads.googleads.v19.services.GoogleAdsService/SearchStream", - request_serializer=google_ads_service.SearchGoogleAdsStreamRequest.serialize, - response_deserializer=google_ads_service.SearchGoogleAdsStreamResponse.deserialize, - ) - return self._stubs["search_stream"] - - @property - def mutate( - self, - ) -> Callable[ - [google_ads_service.MutateGoogleAdsRequest], - Awaitable[google_ads_service.MutateGoogleAdsResponse], - ]: - r"""Return a callable for the mutate method over gRPC. - - Creates, updates, or removes resources. This method supports - atomic transactions with multiple types of resources. For - example, you can atomically create a campaign and a campaign - budget, or perform up to thousands of mutates atomically. - - This method is essentially a wrapper around a series of mutate - methods. The only features it offers over calling those methods - directly are: - - - Atomic transactions - - Temp resource names (described below) - - Somewhat reduced latency over making a series of mutate calls - - Note: Only resources that support atomic transactions are - included, so this method can't replace all calls to individual - services. - - Atomic Transaction Benefits - --------------------------- - - Atomicity makes error handling much easier. If you're making a - series of changes and one fails, it can leave your account in an - inconsistent state. With atomicity, you either reach the chosen - state directly, or the request fails and you can retry. - - Temp Resource Names - ------------------- - - Temp resource names are a special type of resource name used to - create a resource and reference that resource in the same - request. For example, if a campaign budget is created with - ``resource_name`` equal to ``customers/123/campaignBudgets/-1``, - that resource name can be reused in the ``Campaign.budget`` - field in the same request. That way, the two resources are - created and linked atomically. - - To create a temp resource name, put a negative number in the - part of the name that the server would normally allocate. - - Note: - - - Resources must be created with a temp name before the name - can be reused. For example, the previous - CampaignBudget+Campaign example would fail if the mutate - order was reversed. - - Temp names are not remembered across requests. - - There's no limit to the number of temp names in a request. - - Each temp name must use a unique negative number, even if the - resource types differ. - - Latency - ------- - - It's important to group mutates by resource type or the request - may time out and fail. Latency is roughly equal to a series of - calls to individual mutate methods, where each change in - resource type is a new call. For example, mutating 10 campaigns - then 10 ad groups is like 2 calls, while mutating 1 campaign, 1 - ad group, 1 campaign, 1 ad group is like 4 calls. - - List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ - `AdGroupAdError <>`__ `AdGroupCriterionError <>`__ - `AdGroupError <>`__ `AssetError <>`__ `AuthenticationError <>`__ - `AuthorizationError <>`__ `BiddingError <>`__ - `CampaignBudgetError <>`__ `CampaignCriterionError <>`__ - `CampaignError <>`__ `CampaignExperimentError <>`__ - `CampaignSharedSetError <>`__ `CollectionSizeError <>`__ - `ContextError <>`__ `ConversionActionError <>`__ - `CriterionError <>`__ `CustomerFeedError <>`__ - `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ - `DistinctError <>`__ `ExtensionFeedItemError <>`__ - `ExtensionSettingError <>`__ `FeedAttributeReferenceError <>`__ - `FeedError <>`__ `FeedItemError <>`__ `FeedItemSetError <>`__ - `FieldError <>`__ `FieldMaskError <>`__ - `FunctionParsingError <>`__ `HeaderError <>`__ `ImageError <>`__ - `InternalError <>`__ `KeywordPlanAdGroupKeywordError <>`__ - `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ - `LabelError <>`__ `ListOperationError <>`__ - `MediaUploadError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NullError <>`__ - `OperationAccessDeniedError <>`__ `PolicyFindingError <>`__ - `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SettingError <>`__ `SharedSetError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - `UrlFieldError <>`__ `UserListError <>`__ - `YoutubeVideoRegistrationError <>`__ - - Returns: - Callable[[~.MutateGoogleAdsRequest], - Awaitable[~.MutateGoogleAdsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate" not in self._stubs: - self._stubs["mutate"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.GoogleAdsService/Mutate", - request_serializer=google_ads_service.MutateGoogleAdsRequest.serialize, - response_deserializer=google_ads_service.MutateGoogleAdsResponse.deserialize, - ) - return self._stubs["mutate"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.search: self._wrap_method( - self.search, - default_timeout=None, - client_info=client_info, - ), - self.search_stream: self._wrap_method( - self.search_stream, - default_timeout=None, - client_info=client_info, - ), - self.mutate: self._wrap_method( - self.mutate, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("GoogleAdsServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/identity_verification_service/async_client.py b/google/ads/googleads/v19/services/services/identity_verification_service/async_client.py deleted file mode 100644 index 71d963180..000000000 --- a/google/ads/googleads/v19/services/services/identity_verification_service/async_client.py +++ /dev/null @@ -1,527 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.enums.types import identity_verification_program -from google.ads.googleads.v19.services.types import ( - identity_verification_service, -) -from .transports.base import ( - IdentityVerificationServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import IdentityVerificationServiceClient - -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 IdentityVerificationServiceAsyncClient: - """A service for managing Identity Verification Service.""" - - _client: IdentityVerificationServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = IdentityVerificationServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - IdentityVerificationServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - IdentityVerificationServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = IdentityVerificationServiceClient._DEFAULT_UNIVERSE - - common_billing_account_path = staticmethod( - IdentityVerificationServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - IdentityVerificationServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - IdentityVerificationServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - IdentityVerificationServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - IdentityVerificationServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - IdentityVerificationServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - IdentityVerificationServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - IdentityVerificationServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - IdentityVerificationServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - IdentityVerificationServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - IdentityVerificationServiceAsyncClient: The constructed client. - """ - return IdentityVerificationServiceClient.from_service_account_info.__func__(IdentityVerificationServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - IdentityVerificationServiceAsyncClient: The constructed client. - """ - return IdentityVerificationServiceClient.from_service_account_file.__func__(IdentityVerificationServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return IdentityVerificationServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> IdentityVerificationServiceTransport: - """Returns the transport used by the client instance. - - Returns: - IdentityVerificationServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = IdentityVerificationServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - IdentityVerificationServiceTransport, - Callable[..., IdentityVerificationServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the identity verification service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,IdentityVerificationServiceTransport,Callable[..., IdentityVerificationServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the IdentityVerificationServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = IdentityVerificationServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.IdentityVerificationServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.IdentityVerificationService", - "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.ads.googleads.v19.services.IdentityVerificationService", - "credentialsType": None, - } - ), - ) - - async def start_identity_verification( - self, - request: Optional[ - Union[ - identity_verification_service.StartIdentityVerificationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - verification_program: Optional[ - identity_verification_program.IdentityVerificationProgramEnum.IdentityVerificationProgram - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> None: - r"""Starts Identity Verification for a given verification program - type. Statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.StartIdentityVerificationRequest, dict]]): - The request object. Request message for - [IdentityVerificationService.StartIdentityVerification]. - customer_id (:class:`str`): - Required. The Id of the customer for - whom we are creating this verification. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - verification_program (:class:`google.ads.googleads.v19.enums.types.IdentityVerificationProgramEnum.IdentityVerificationProgram`): - Required. The verification program - type for which we want to start the - verification. - - This corresponds to the ``verification_program`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, verification_program] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - identity_verification_service.StartIdentityVerificationRequest, - ): - request = ( - identity_verification_service.StartIdentityVerificationRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if verification_program is not None: - request.verification_program = verification_program - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.start_identity_verification - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - async def get_identity_verification( - self, - request: Optional[ - Union[ - identity_verification_service.GetIdentityVerificationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> identity_verification_service.GetIdentityVerificationResponse: - r"""Returns Identity Verification information. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GetIdentityVerificationRequest, dict]]): - The request object. Request message for - [IdentityVerificationService.GetIdentityVerification]. - customer_id (:class:`str`): - Required. The ID of the customer for - whom we are requesting verification - information. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GetIdentityVerificationResponse: - Response message for - [IdentityVerificationService.GetIdentityVerification]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - identity_verification_service.GetIdentityVerificationRequest, - ): - request = ( - identity_verification_service.GetIdentityVerificationRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.get_identity_verification - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "IdentityVerificationServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("IdentityVerificationServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/identity_verification_service/client.py b/google/ads/googleads/v19/services/services/identity_verification_service/client.py deleted file mode 100644 index e9707b700..000000000 --- a/google/ads/googleads/v19/services/services/identity_verification_service/client.py +++ /dev/null @@ -1,965 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.enums.types import identity_verification_program -from google.ads.googleads.v19.services.types import ( - identity_verification_service, -) -from .transports.base import ( - IdentityVerificationServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import IdentityVerificationServiceGrpcTransport -from .transports.grpc_asyncio import ( - IdentityVerificationServiceGrpcAsyncIOTransport, -) - - -class IdentityVerificationServiceClientMeta(type): - """Metaclass for the IdentityVerificationService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[IdentityVerificationServiceTransport]] - _transport_registry["grpc"] = IdentityVerificationServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - IdentityVerificationServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[IdentityVerificationServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class IdentityVerificationServiceClient( - metaclass=IdentityVerificationServiceClientMeta -): - """A service for managing Identity Verification Service.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - IdentityVerificationServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - IdentityVerificationServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> IdentityVerificationServiceTransport: - """Returns the transport used by the client instance. - - Returns: - IdentityVerificationServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - IdentityVerificationServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - IdentityVerificationServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = IdentityVerificationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = IdentityVerificationServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - IdentityVerificationServiceTransport, - Callable[..., IdentityVerificationServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the identity verification service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,IdentityVerificationServiceTransport,Callable[..., IdentityVerificationServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the IdentityVerificationServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = IdentityVerificationServiceClient._read_environment_variables() - self._client_cert_source = ( - IdentityVerificationServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - IdentityVerificationServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, IdentityVerificationServiceTransport - ) - if transport_provided: - # transport is a IdentityVerificationServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - IdentityVerificationServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or IdentityVerificationServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[IdentityVerificationServiceTransport], - Callable[..., IdentityVerificationServiceTransport], - ] = ( - IdentityVerificationServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., IdentityVerificationServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.IdentityVerificationServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.IdentityVerificationService", - "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.ads.googleads.v19.services.IdentityVerificationService", - "credentialsType": None, - } - ), - ) - - def start_identity_verification( - self, - request: Optional[ - Union[ - identity_verification_service.StartIdentityVerificationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - verification_program: Optional[ - identity_verification_program.IdentityVerificationProgramEnum.IdentityVerificationProgram - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> None: - r"""Starts Identity Verification for a given verification program - type. Statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.StartIdentityVerificationRequest, dict]): - The request object. Request message for - [IdentityVerificationService.StartIdentityVerification]. - customer_id (str): - Required. The Id of the customer for - whom we are creating this verification. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - verification_program (google.ads.googleads.v19.enums.types.IdentityVerificationProgramEnum.IdentityVerificationProgram): - Required. The verification program - type for which we want to start the - verification. - - This corresponds to the ``verification_program`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, verification_program] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - identity_verification_service.StartIdentityVerificationRequest, - ): - request = ( - identity_verification_service.StartIdentityVerificationRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if verification_program is not None: - request.verification_program = verification_program - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.start_identity_verification - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - def get_identity_verification( - self, - request: Optional[ - Union[ - identity_verification_service.GetIdentityVerificationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> identity_verification_service.GetIdentityVerificationResponse: - r"""Returns Identity Verification information. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GetIdentityVerificationRequest, dict]): - The request object. Request message for - [IdentityVerificationService.GetIdentityVerification]. - customer_id (str): - Required. The ID of the customer for - whom we are requesting verification - information. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GetIdentityVerificationResponse: - Response message for - [IdentityVerificationService.GetIdentityVerification]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - identity_verification_service.GetIdentityVerificationRequest, - ): - request = ( - identity_verification_service.GetIdentityVerificationRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.get_identity_verification - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "IdentityVerificationServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("IdentityVerificationServiceClient",) diff --git a/google/ads/googleads/v19/services/services/identity_verification_service/transports/base.py b/google/ads/googleads/v19/services/services/identity_verification_service/transports/base.py deleted file mode 100644 index ea59ed07c..000000000 --- a/google/ads/googleads/v19/services/services/identity_verification_service/transports/base.py +++ /dev/null @@ -1,191 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - identity_verification_service, -) -from google.protobuf import empty_pb2 # type: ignore - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class IdentityVerificationServiceTransport(abc.ABC): - """Abstract transport class for IdentityVerificationService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.start_identity_verification: gapic_v1.method.wrap_method( - self.start_identity_verification, - default_timeout=None, - client_info=client_info, - ), - self.get_identity_verification: gapic_v1.method.wrap_method( - self.get_identity_verification, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def start_identity_verification( - self, - ) -> Callable[ - [identity_verification_service.StartIdentityVerificationRequest], - Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], - ]: - raise NotImplementedError() - - @property - def get_identity_verification( - self, - ) -> Callable[ - [identity_verification_service.GetIdentityVerificationRequest], - Union[ - identity_verification_service.GetIdentityVerificationResponse, - Awaitable[ - identity_verification_service.GetIdentityVerificationResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("IdentityVerificationServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/identity_verification_service/transports/grpc.py b/google/ads/googleads/v19/services/services/identity_verification_service/transports/grpc.py deleted file mode 100644 index e5082f560..000000000 --- a/google/ads/googleads/v19/services/services/identity_verification_service/transports/grpc.py +++ /dev/null @@ -1,426 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - identity_verification_service, -) -from google.protobuf import empty_pb2 # type: ignore -from .base import IdentityVerificationServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.IdentityVerificationService", - "rpcName": str(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.ads.googleads.v19.services.IdentityVerificationService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class IdentityVerificationServiceGrpcTransport( - IdentityVerificationServiceTransport -): - """gRPC backend transport for IdentityVerificationService. - - A service for managing Identity Verification Service. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def start_identity_verification( - self, - ) -> Callable[ - [identity_verification_service.StartIdentityVerificationRequest], - empty_pb2.Empty, - ]: - r"""Return a callable for the start identity verification method over gRPC. - - Starts Identity Verification for a given verification program - type. Statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.StartIdentityVerificationRequest], - ~.Empty]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "start_identity_verification" not in self._stubs: - self._stubs["start_identity_verification"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.IdentityVerificationService/StartIdentityVerification", - request_serializer=identity_verification_service.StartIdentityVerificationRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - ) - return self._stubs["start_identity_verification"] - - @property - def get_identity_verification( - self, - ) -> Callable[ - [identity_verification_service.GetIdentityVerificationRequest], - identity_verification_service.GetIdentityVerificationResponse, - ]: - r"""Return a callable for the get identity verification method over gRPC. - - Returns Identity Verification information. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GetIdentityVerificationRequest], - ~.GetIdentityVerificationResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_identity_verification" not in self._stubs: - self._stubs["get_identity_verification"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.IdentityVerificationService/GetIdentityVerification", - request_serializer=identity_verification_service.GetIdentityVerificationRequest.serialize, - response_deserializer=identity_verification_service.GetIdentityVerificationResponse.deserialize, - ) - ) - return self._stubs["get_identity_verification"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("IdentityVerificationServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/identity_verification_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/identity_verification_service/transports/grpc_asyncio.py deleted file mode 100644 index bf0a746a0..000000000 --- a/google/ads/googleads/v19/services/services/identity_verification_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,454 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - identity_verification_service, -) -from google.protobuf import empty_pb2 # type: ignore -from .base import IdentityVerificationServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.IdentityVerificationService", - "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.ads.googleads.v19.services.IdentityVerificationService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class IdentityVerificationServiceGrpcAsyncIOTransport( - IdentityVerificationServiceTransport -): - """gRPC AsyncIO backend transport for IdentityVerificationService. - - A service for managing Identity Verification Service. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def start_identity_verification( - self, - ) -> Callable[ - [identity_verification_service.StartIdentityVerificationRequest], - Awaitable[empty_pb2.Empty], - ]: - r"""Return a callable for the start identity verification method over gRPC. - - Starts Identity Verification for a given verification program - type. Statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.StartIdentityVerificationRequest], - Awaitable[~.Empty]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "start_identity_verification" not in self._stubs: - self._stubs["start_identity_verification"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.IdentityVerificationService/StartIdentityVerification", - request_serializer=identity_verification_service.StartIdentityVerificationRequest.serialize, - response_deserializer=empty_pb2.Empty.FromString, - ) - ) - return self._stubs["start_identity_verification"] - - @property - def get_identity_verification( - self, - ) -> Callable[ - [identity_verification_service.GetIdentityVerificationRequest], - Awaitable[ - identity_verification_service.GetIdentityVerificationResponse - ], - ]: - r"""Return a callable for the get identity verification method over gRPC. - - Returns Identity Verification information. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GetIdentityVerificationRequest], - Awaitable[~.GetIdentityVerificationResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_identity_verification" not in self._stubs: - self._stubs["get_identity_verification"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.IdentityVerificationService/GetIdentityVerification", - request_serializer=identity_verification_service.GetIdentityVerificationRequest.serialize, - response_deserializer=identity_verification_service.GetIdentityVerificationResponse.deserialize, - ) - ) - return self._stubs["get_identity_verification"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.start_identity_verification: self._wrap_method( - self.start_identity_verification, - default_timeout=None, - client_info=client_info, - ), - self.get_identity_verification: self._wrap_method( - self.get_identity_verification, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("IdentityVerificationServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/invoice_service/async_client.py b/google/ads/googleads/v19/services/services/invoice_service/async_client.py deleted file mode 100644 index e4d487110..000000000 --- a/google/ads/googleads/v19/services/services/invoice_service/async_client.py +++ /dev/null @@ -1,436 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.enums.types import month_of_year -from google.ads.googleads.v19.services.types import invoice_service -from .transports.base import InvoiceServiceTransport, DEFAULT_CLIENT_INFO -from .client import InvoiceServiceClient - -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 InvoiceServiceAsyncClient: - """A service to fetch invoices issued for a billing setup during - a given month. - """ - - _client: InvoiceServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = InvoiceServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = InvoiceServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = InvoiceServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = InvoiceServiceClient._DEFAULT_UNIVERSE - - invoice_path = staticmethod(InvoiceServiceClient.invoice_path) - parse_invoice_path = staticmethod(InvoiceServiceClient.parse_invoice_path) - common_billing_account_path = staticmethod( - InvoiceServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - InvoiceServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(InvoiceServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - InvoiceServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - InvoiceServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - InvoiceServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod(InvoiceServiceClient.common_project_path) - parse_common_project_path = staticmethod( - InvoiceServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - InvoiceServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - InvoiceServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - InvoiceServiceAsyncClient: The constructed client. - """ - return InvoiceServiceClient.from_service_account_info.__func__(InvoiceServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - InvoiceServiceAsyncClient: The constructed client. - """ - return InvoiceServiceClient.from_service_account_file.__func__(InvoiceServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return InvoiceServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> InvoiceServiceTransport: - """Returns the transport used by the client instance. - - Returns: - InvoiceServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = InvoiceServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - InvoiceServiceTransport, - Callable[..., InvoiceServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the invoice service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,InvoiceServiceTransport,Callable[..., InvoiceServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the InvoiceServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = InvoiceServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.InvoiceServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.InvoiceService", - "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.ads.googleads.v19.services.InvoiceService", - "credentialsType": None, - } - ), - ) - - async def list_invoices( - self, - request: Optional[ - Union[invoice_service.ListInvoicesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - billing_setup: Optional[str] = None, - issue_year: Optional[str] = None, - issue_month: Optional[month_of_year.MonthOfYearEnum.MonthOfYear] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> invoice_service.ListInvoicesResponse: - r"""Returns all invoices associated with a billing setup, for a - given month. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `InvoiceError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ListInvoicesRequest, dict]]): - The request object. Request message for fetching the - invoices of a given billing setup that - were issued during a given month. - customer_id (:class:`str`): - Required. The ID of the customer to - fetch invoices for. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - billing_setup (:class:`str`): - Required. The billing setup resource name of the - requested invoices. - - ``customers/{customer_id}/billingSetups/{billing_setup_id}`` - - This corresponds to the ``billing_setup`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - issue_year (:class:`str`): - Required. The issue year to retrieve - invoices, in yyyy format. Only invoices - issued in 2019 or later can be - retrieved. - - This corresponds to the ``issue_year`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - issue_month (:class:`google.ads.googleads.v19.enums.types.MonthOfYearEnum.MonthOfYear`): - Required. The issue month to retrieve - invoices. - - This corresponds to the ``issue_month`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListInvoicesResponse: - Response message for - [InvoiceService.ListInvoices][google.ads.googleads.v19.services.InvoiceService.ListInvoices]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, billing_setup, issue_year, issue_month] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, invoice_service.ListInvoicesRequest): - request = invoice_service.ListInvoicesRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if billing_setup is not None: - request.billing_setup = billing_setup - if issue_year is not None: - request.issue_year = issue_year - if issue_month is not None: - request.issue_month = issue_month - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_invoices - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "InvoiceServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("InvoiceServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/invoice_service/client.py b/google/ads/googleads/v19/services/services/invoice_service/client.py deleted file mode 100644 index 987335876..000000000 --- a/google/ads/googleads/v19/services/services/invoice_service/client.py +++ /dev/null @@ -1,880 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.enums.types import month_of_year -from google.ads.googleads.v19.services.types import invoice_service -from .transports.base import InvoiceServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import InvoiceServiceGrpcTransport -from .transports.grpc_asyncio import InvoiceServiceGrpcAsyncIOTransport - - -class InvoiceServiceClientMeta(type): - """Metaclass for the InvoiceService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[InvoiceServiceTransport]] - _transport_registry["grpc"] = InvoiceServiceGrpcTransport - _transport_registry["grpc_asyncio"] = InvoiceServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[InvoiceServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class InvoiceServiceClient(metaclass=InvoiceServiceClientMeta): - """A service to fetch invoices issued for a billing setup during - a given month. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - InvoiceServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - InvoiceServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> InvoiceServiceTransport: - """Returns the transport used by the client instance. - - Returns: - InvoiceServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def invoice_path( - customer_id: str, - invoice_id: str, - ) -> str: - """Returns a fully-qualified invoice string.""" - return "customers/{customer_id}/invoices/{invoice_id}".format( - customer_id=customer_id, - invoice_id=invoice_id, - ) - - @staticmethod - def parse_invoice_path(path: str) -> Dict[str, str]: - """Parses a invoice path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/invoices/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = InvoiceServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = InvoiceServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - InvoiceServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = InvoiceServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - InvoiceServiceTransport, - Callable[..., InvoiceServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the invoice service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,InvoiceServiceTransport,Callable[..., InvoiceServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the InvoiceServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = InvoiceServiceClient._read_environment_variables() - self._client_cert_source = InvoiceServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - self._universe_domain = InvoiceServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, InvoiceServiceTransport) - if transport_provided: - # transport is a InvoiceServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(InvoiceServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or InvoiceServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[InvoiceServiceTransport], - Callable[..., InvoiceServiceTransport], - ] = ( - InvoiceServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., InvoiceServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.InvoiceServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.InvoiceService", - "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.ads.googleads.v19.services.InvoiceService", - "credentialsType": None, - } - ), - ) - - def list_invoices( - self, - request: Optional[ - Union[invoice_service.ListInvoicesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - billing_setup: Optional[str] = None, - issue_year: Optional[str] = None, - issue_month: Optional[month_of_year.MonthOfYearEnum.MonthOfYear] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> invoice_service.ListInvoicesResponse: - r"""Returns all invoices associated with a billing setup, for a - given month. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `InvoiceError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ListInvoicesRequest, dict]): - The request object. Request message for fetching the - invoices of a given billing setup that - were issued during a given month. - customer_id (str): - Required. The ID of the customer to - fetch invoices for. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - billing_setup (str): - Required. The billing setup resource name of the - requested invoices. - - ``customers/{customer_id}/billingSetups/{billing_setup_id}`` - - This corresponds to the ``billing_setup`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - issue_year (str): - Required. The issue year to retrieve - invoices, in yyyy format. Only invoices - issued in 2019 or later can be - retrieved. - - This corresponds to the ``issue_year`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - issue_month (google.ads.googleads.v19.enums.types.MonthOfYearEnum.MonthOfYear): - Required. The issue month to retrieve - invoices. - - This corresponds to the ``issue_month`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListInvoicesResponse: - Response message for - [InvoiceService.ListInvoices][google.ads.googleads.v19.services.InvoiceService.ListInvoices]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, billing_setup, issue_year, issue_month] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, invoice_service.ListInvoicesRequest): - request = invoice_service.ListInvoicesRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if billing_setup is not None: - request.billing_setup = billing_setup - if issue_year is not None: - request.issue_year = issue_year - if issue_month is not None: - request.issue_month = issue_month - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.list_invoices] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "InvoiceServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("InvoiceServiceClient",) diff --git a/google/ads/googleads/v19/services/services/invoice_service/transports/base.py b/google/ads/googleads/v19/services/services/invoice_service/transports/base.py deleted file mode 100644 index c9fe771d2..000000000 --- a/google/ads/googleads/v19/services/services/invoice_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import invoice_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class InvoiceServiceTransport(abc.ABC): - """Abstract transport class for InvoiceService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.list_invoices: gapic_v1.method.wrap_method( - self.list_invoices, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def list_invoices( - self, - ) -> Callable[ - [invoice_service.ListInvoicesRequest], - Union[ - invoice_service.ListInvoicesResponse, - Awaitable[invoice_service.ListInvoicesResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("InvoiceServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/invoice_service/transports/grpc.py b/google/ads/googleads/v19/services/services/invoice_service/transports/grpc.py deleted file mode 100644 index 38cdd82ff..000000000 --- a/google/ads/googleads/v19/services/services/invoice_service/transports/grpc.py +++ /dev/null @@ -1,386 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import invoice_service -from .base import InvoiceServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.InvoiceService", - "rpcName": str(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.ads.googleads.v19.services.InvoiceService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class InvoiceServiceGrpcTransport(InvoiceServiceTransport): - """gRPC backend transport for InvoiceService. - - A service to fetch invoices issued for a billing setup during - a given month. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def list_invoices( - self, - ) -> Callable[ - [invoice_service.ListInvoicesRequest], - invoice_service.ListInvoicesResponse, - ]: - r"""Return a callable for the list invoices method over gRPC. - - Returns all invoices associated with a billing setup, for a - given month. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `InvoiceError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.ListInvoicesRequest], - ~.ListInvoicesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_invoices" not in self._stubs: - self._stubs["list_invoices"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.InvoiceService/ListInvoices", - request_serializer=invoice_service.ListInvoicesRequest.serialize, - response_deserializer=invoice_service.ListInvoicesResponse.deserialize, - ) - return self._stubs["list_invoices"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("InvoiceServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/invoice_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/invoice_service/transports/grpc_asyncio.py deleted file mode 100644 index a2f0fae0e..000000000 --- a/google/ads/googleads/v19/services/services/invoice_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,407 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import invoice_service -from .base import InvoiceServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.InvoiceService", - "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.ads.googleads.v19.services.InvoiceService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class InvoiceServiceGrpcAsyncIOTransport(InvoiceServiceTransport): - """gRPC AsyncIO backend transport for InvoiceService. - - A service to fetch invoices issued for a billing setup during - a given month. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def list_invoices( - self, - ) -> Callable[ - [invoice_service.ListInvoicesRequest], - Awaitable[invoice_service.ListInvoicesResponse], - ]: - r"""Return a callable for the list invoices method over gRPC. - - Returns all invoices associated with a billing setup, for a - given month. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `InvoiceError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.ListInvoicesRequest], - Awaitable[~.ListInvoicesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_invoices" not in self._stubs: - self._stubs["list_invoices"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.InvoiceService/ListInvoices", - request_serializer=invoice_service.ListInvoicesRequest.serialize, - response_deserializer=invoice_service.ListInvoicesResponse.deserialize, - ) - return self._stubs["list_invoices"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.list_invoices: self._wrap_method( - self.list_invoices, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("InvoiceServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/async_client.py b/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/async_client.py deleted file mode 100644 index 55d6b9e06..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/async_client.py +++ /dev/null @@ -1,459 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - keyword_plan_ad_group_keyword_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - KeywordPlanAdGroupKeywordServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import KeywordPlanAdGroupKeywordServiceClient - -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 KeywordPlanAdGroupKeywordServiceAsyncClient: - """Service to manage Keyword Plan ad group keywords. - KeywordPlanAdGroup is required to add ad group keywords. - Positive and negative keywords are supported. A maximum of - 10,000 positive keywords are allowed per keyword plan. A maximum - of 1,000 negative keywords are allower per keyword plan. This - includes campaign negative keywords and ad group negative - keywords. - """ - - _client: KeywordPlanAdGroupKeywordServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = KeywordPlanAdGroupKeywordServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - KeywordPlanAdGroupKeywordServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - KeywordPlanAdGroupKeywordServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = KeywordPlanAdGroupKeywordServiceClient._DEFAULT_UNIVERSE - - keyword_plan_ad_group_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.keyword_plan_ad_group_path - ) - parse_keyword_plan_ad_group_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.parse_keyword_plan_ad_group_path - ) - keyword_plan_ad_group_keyword_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.keyword_plan_ad_group_keyword_path - ) - parse_keyword_plan_ad_group_keyword_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.parse_keyword_plan_ad_group_keyword_path - ) - common_billing_account_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - KeywordPlanAdGroupKeywordServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanAdGroupKeywordServiceAsyncClient: The constructed client. - """ - return KeywordPlanAdGroupKeywordServiceClient.from_service_account_info.__func__(KeywordPlanAdGroupKeywordServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanAdGroupKeywordServiceAsyncClient: The constructed client. - """ - return KeywordPlanAdGroupKeywordServiceClient.from_service_account_file.__func__(KeywordPlanAdGroupKeywordServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return KeywordPlanAdGroupKeywordServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> KeywordPlanAdGroupKeywordServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanAdGroupKeywordServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - KeywordPlanAdGroupKeywordServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanAdGroupKeywordServiceTransport, - Callable[..., KeywordPlanAdGroupKeywordServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan ad group keyword service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanAdGroupKeywordServiceTransport,Callable[..., KeywordPlanAdGroupKeywordServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanAdGroupKeywordServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = KeywordPlanAdGroupKeywordServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.KeywordPlanAdGroupKeywordServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService", - "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.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService", - "credentialsType": None, - } - ), - ) - - async def mutate_keyword_plan_ad_group_keywords( - self, - request: Optional[ - Union[ - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - keyword_plan_ad_group_keyword_service.KeywordPlanAdGroupKeywordOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse - ): - r"""Creates, updates, or removes Keyword Plan ad group keywords. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupKeywordError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupKeywordsRequest, dict]]): - The request object. Request message for - [KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords][google.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords]. - customer_id (:class:`str`): - Required. The ID of the customer - whose Keyword Plan ad group keywords are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanAdGroupKeywordOperation]`): - Required. The list of operations to - perform on individual Keyword Plan ad - group keywords. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupKeywordsResponse: - Response message for a Keyword Plan - ad group keyword mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest, - ): - request = keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_keyword_plan_ad_group_keywords - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "KeywordPlanAdGroupKeywordServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("KeywordPlanAdGroupKeywordServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/client.py b/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/client.py deleted file mode 100644 index cee094689..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/client.py +++ /dev/null @@ -1,938 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - keyword_plan_ad_group_keyword_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - KeywordPlanAdGroupKeywordServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import KeywordPlanAdGroupKeywordServiceGrpcTransport -from .transports.grpc_asyncio import ( - KeywordPlanAdGroupKeywordServiceGrpcAsyncIOTransport, -) - - -class KeywordPlanAdGroupKeywordServiceClientMeta(type): - """Metaclass for the KeywordPlanAdGroupKeywordService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[KeywordPlanAdGroupKeywordServiceTransport]] - _transport_registry["grpc"] = KeywordPlanAdGroupKeywordServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - KeywordPlanAdGroupKeywordServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[KeywordPlanAdGroupKeywordServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class KeywordPlanAdGroupKeywordServiceClient( - metaclass=KeywordPlanAdGroupKeywordServiceClientMeta -): - """Service to manage Keyword Plan ad group keywords. - KeywordPlanAdGroup is required to add ad group keywords. - Positive and negative keywords are supported. A maximum of - 10,000 positive keywords are allowed per keyword plan. A maximum - of 1,000 negative keywords are allower per keyword plan. This - includes campaign negative keywords and ad group negative - keywords. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanAdGroupKeywordServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanAdGroupKeywordServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> KeywordPlanAdGroupKeywordServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanAdGroupKeywordServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def keyword_plan_ad_group_path( - customer_id: str, - keyword_plan_ad_group_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_ad_group string.""" - return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( - customer_id=customer_id, - keyword_plan_ad_group_id=keyword_plan_ad_group_id, - ) - - @staticmethod - def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_ad_group_keyword_path( - customer_id: str, - keyword_plan_ad_group_keyword_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_ad_group_keyword string.""" - return "customers/{customer_id}/keywordPlanAdGroupKeywords/{keyword_plan_ad_group_keyword_id}".format( - customer_id=customer_id, - keyword_plan_ad_group_keyword_id=keyword_plan_ad_group_keyword_id, - ) - - @staticmethod - def parse_keyword_plan_ad_group_keyword_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_ad_group_keyword path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanAdGroupKeywords/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - KeywordPlanAdGroupKeywordServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - KeywordPlanAdGroupKeywordServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = KeywordPlanAdGroupKeywordServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - KeywordPlanAdGroupKeywordServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanAdGroupKeywordServiceTransport, - Callable[..., KeywordPlanAdGroupKeywordServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan ad group keyword service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanAdGroupKeywordServiceTransport,Callable[..., KeywordPlanAdGroupKeywordServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanAdGroupKeywordServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = KeywordPlanAdGroupKeywordServiceClient._read_environment_variables() - self._client_cert_source = ( - KeywordPlanAdGroupKeywordServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - KeywordPlanAdGroupKeywordServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, KeywordPlanAdGroupKeywordServiceTransport - ) - if transport_provided: - # transport is a KeywordPlanAdGroupKeywordServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - KeywordPlanAdGroupKeywordServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or KeywordPlanAdGroupKeywordServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[KeywordPlanAdGroupKeywordServiceTransport], - Callable[..., KeywordPlanAdGroupKeywordServiceTransport], - ] = ( - KeywordPlanAdGroupKeywordServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., KeywordPlanAdGroupKeywordServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.KeywordPlanAdGroupKeywordServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService", - "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.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService", - "credentialsType": None, - } - ), - ) - - def mutate_keyword_plan_ad_group_keywords( - self, - request: Optional[ - Union[ - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - keyword_plan_ad_group_keyword_service.KeywordPlanAdGroupKeywordOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse - ): - r"""Creates, updates, or removes Keyword Plan ad group keywords. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupKeywordError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupKeywordsRequest, dict]): - The request object. Request message for - [KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords][google.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords]. - customer_id (str): - Required. The ID of the customer - whose Keyword Plan ad group keywords are - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanAdGroupKeywordOperation]): - Required. The list of operations to - perform on individual Keyword Plan ad - group keywords. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupKeywordsResponse: - Response message for a Keyword Plan - ad group keyword mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest, - ): - request = keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_keyword_plan_ad_group_keywords - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "KeywordPlanAdGroupKeywordServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("KeywordPlanAdGroupKeywordServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/base.py b/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/base.py deleted file mode 100644 index a04cf8d3e..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - keyword_plan_ad_group_keyword_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class KeywordPlanAdGroupKeywordServiceTransport(abc.ABC): - """Abstract transport class for KeywordPlanAdGroupKeywordService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_keyword_plan_ad_group_keywords: gapic_v1.method.wrap_method( - self.mutate_keyword_plan_ad_group_keywords, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_keyword_plan_ad_group_keywords( - self, - ) -> Callable[ - [ - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest - ], - Union[ - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse, - Awaitable[ - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("KeywordPlanAdGroupKeywordServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/grpc.py b/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/grpc.py deleted file mode 100644 index 7ea9bb158..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/grpc.py +++ /dev/null @@ -1,402 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - keyword_plan_ad_group_keyword_service, -) -from .base import KeywordPlanAdGroupKeywordServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService", - "rpcName": str(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.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanAdGroupKeywordServiceGrpcTransport( - KeywordPlanAdGroupKeywordServiceTransport -): - """gRPC backend transport for KeywordPlanAdGroupKeywordService. - - Service to manage Keyword Plan ad group keywords. - KeywordPlanAdGroup is required to add ad group keywords. - Positive and negative keywords are supported. A maximum of - 10,000 positive keywords are allowed per keyword plan. A maximum - of 1,000 negative keywords are allower per keyword plan. This - includes campaign negative keywords and ad group negative - keywords. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_keyword_plan_ad_group_keywords( - self, - ) -> Callable[ - [ - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest - ], - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse, - ]: - r"""Return a callable for the mutate keyword plan ad group - keywords method over gRPC. - - Creates, updates, or removes Keyword Plan ad group keywords. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupKeywordError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.MutateKeywordPlanAdGroupKeywordsRequest], - ~.MutateKeywordPlanAdGroupKeywordsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_keyword_plan_ad_group_keywords" not in self._stubs: - self._stubs["mutate_keyword_plan_ad_group_keywords"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService/MutateKeywordPlanAdGroupKeywords", - request_serializer=keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest.serialize, - response_deserializer=keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse.deserialize, - ) - ) - return self._stubs["mutate_keyword_plan_ad_group_keywords"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("KeywordPlanAdGroupKeywordServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/grpc_asyncio.py deleted file mode 100644 index 170ac1035..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,425 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - keyword_plan_ad_group_keyword_service, -) -from .base import KeywordPlanAdGroupKeywordServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService", - "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.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanAdGroupKeywordServiceGrpcAsyncIOTransport( - KeywordPlanAdGroupKeywordServiceTransport -): - """gRPC AsyncIO backend transport for KeywordPlanAdGroupKeywordService. - - Service to manage Keyword Plan ad group keywords. - KeywordPlanAdGroup is required to add ad group keywords. - Positive and negative keywords are supported. A maximum of - 10,000 positive keywords are allowed per keyword plan. A maximum - of 1,000 negative keywords are allower per keyword plan. This - includes campaign negative keywords and ad group negative - keywords. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_keyword_plan_ad_group_keywords( - self, - ) -> Callable[ - [ - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest - ], - Awaitable[ - keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse - ], - ]: - r"""Return a callable for the mutate keyword plan ad group - keywords method over gRPC. - - Creates, updates, or removes Keyword Plan ad group keywords. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupKeywordError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.MutateKeywordPlanAdGroupKeywordsRequest], - Awaitable[~.MutateKeywordPlanAdGroupKeywordsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_keyword_plan_ad_group_keywords" not in self._stubs: - self._stubs["mutate_keyword_plan_ad_group_keywords"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService/MutateKeywordPlanAdGroupKeywords", - request_serializer=keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest.serialize, - response_deserializer=keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse.deserialize, - ) - ) - return self._stubs["mutate_keyword_plan_ad_group_keywords"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_keyword_plan_ad_group_keywords: self._wrap_method( - self.mutate_keyword_plan_ad_group_keywords, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("KeywordPlanAdGroupKeywordServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/async_client.py b/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/async_client.py deleted file mode 100644 index 404e6eeaa..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/async_client.py +++ /dev/null @@ -1,451 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - keyword_plan_ad_group_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - KeywordPlanAdGroupServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import KeywordPlanAdGroupServiceClient - -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 KeywordPlanAdGroupServiceAsyncClient: - """Service to manage Keyword Plan ad groups.""" - - _client: KeywordPlanAdGroupServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = KeywordPlanAdGroupServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - KeywordPlanAdGroupServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - KeywordPlanAdGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = KeywordPlanAdGroupServiceClient._DEFAULT_UNIVERSE - - keyword_plan_ad_group_path = staticmethod( - KeywordPlanAdGroupServiceClient.keyword_plan_ad_group_path - ) - parse_keyword_plan_ad_group_path = staticmethod( - KeywordPlanAdGroupServiceClient.parse_keyword_plan_ad_group_path - ) - keyword_plan_campaign_path = staticmethod( - KeywordPlanAdGroupServiceClient.keyword_plan_campaign_path - ) - parse_keyword_plan_campaign_path = staticmethod( - KeywordPlanAdGroupServiceClient.parse_keyword_plan_campaign_path - ) - common_billing_account_path = staticmethod( - KeywordPlanAdGroupServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - KeywordPlanAdGroupServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - KeywordPlanAdGroupServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - KeywordPlanAdGroupServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - KeywordPlanAdGroupServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - KeywordPlanAdGroupServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - KeywordPlanAdGroupServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - KeywordPlanAdGroupServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - KeywordPlanAdGroupServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - KeywordPlanAdGroupServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanAdGroupServiceAsyncClient: The constructed client. - """ - return KeywordPlanAdGroupServiceClient.from_service_account_info.__func__(KeywordPlanAdGroupServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanAdGroupServiceAsyncClient: The constructed client. - """ - return KeywordPlanAdGroupServiceClient.from_service_account_file.__func__(KeywordPlanAdGroupServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return KeywordPlanAdGroupServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> KeywordPlanAdGroupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanAdGroupServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = KeywordPlanAdGroupServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanAdGroupServiceTransport, - Callable[..., KeywordPlanAdGroupServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan ad group service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanAdGroupServiceTransport,Callable[..., KeywordPlanAdGroupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanAdGroupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = KeywordPlanAdGroupServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.KeywordPlanAdGroupServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanAdGroupService", - "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.ads.googleads.v19.services.KeywordPlanAdGroupService", - "credentialsType": None, - } - ), - ) - - async def mutate_keyword_plan_ad_groups( - self, - request: Optional[ - Union[ - keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - keyword_plan_ad_group_service.KeywordPlanAdGroupOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse: - r"""Creates, updates, or removes Keyword Plan ad groups. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupsRequest, dict]]): - The request object. Request message for - [KeywordPlanAdGroupService.MutateKeywordPlanAdGroups][google.ads.googleads.v19.services.KeywordPlanAdGroupService.MutateKeywordPlanAdGroups]. - customer_id (:class:`str`): - Required. The ID of the customer - whose Keyword Plan ad groups are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanAdGroupOperation]`): - Required. The list of operations to - perform on individual Keyword Plan ad - groups. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupsResponse: - Response message for a Keyword Plan - ad group mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest, - ): - request = ( - keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_keyword_plan_ad_groups - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "KeywordPlanAdGroupServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("KeywordPlanAdGroupServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/client.py b/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/client.py deleted file mode 100644 index 6aa5eec7c..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/client.py +++ /dev/null @@ -1,925 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - keyword_plan_ad_group_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - KeywordPlanAdGroupServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import KeywordPlanAdGroupServiceGrpcTransport -from .transports.grpc_asyncio import ( - KeywordPlanAdGroupServiceGrpcAsyncIOTransport, -) - - -class KeywordPlanAdGroupServiceClientMeta(type): - """Metaclass for the KeywordPlanAdGroupService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[KeywordPlanAdGroupServiceTransport]] - _transport_registry["grpc"] = KeywordPlanAdGroupServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - KeywordPlanAdGroupServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[KeywordPlanAdGroupServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class KeywordPlanAdGroupServiceClient( - metaclass=KeywordPlanAdGroupServiceClientMeta -): - """Service to manage Keyword Plan ad groups.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanAdGroupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanAdGroupServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> KeywordPlanAdGroupServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanAdGroupServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def keyword_plan_ad_group_path( - customer_id: str, - keyword_plan_ad_group_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_ad_group string.""" - return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( - customer_id=customer_id, - keyword_plan_ad_group_id=keyword_plan_ad_group_id, - ) - - @staticmethod - def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_campaign_path( - customer_id: str, - keyword_plan_campaign_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_campaign string.""" - return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( - customer_id=customer_id, - keyword_plan_campaign_id=keyword_plan_campaign_id, - ) - - @staticmethod - def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - KeywordPlanAdGroupServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = KeywordPlanAdGroupServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = KeywordPlanAdGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = KeywordPlanAdGroupServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanAdGroupServiceTransport, - Callable[..., KeywordPlanAdGroupServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan ad group service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanAdGroupServiceTransport,Callable[..., KeywordPlanAdGroupServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanAdGroupServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = KeywordPlanAdGroupServiceClient._read_environment_variables() - self._client_cert_source = ( - KeywordPlanAdGroupServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - KeywordPlanAdGroupServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, KeywordPlanAdGroupServiceTransport - ) - if transport_provided: - # transport is a KeywordPlanAdGroupServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - KeywordPlanAdGroupServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or KeywordPlanAdGroupServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[KeywordPlanAdGroupServiceTransport], - Callable[..., KeywordPlanAdGroupServiceTransport], - ] = ( - KeywordPlanAdGroupServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., KeywordPlanAdGroupServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.KeywordPlanAdGroupServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanAdGroupService", - "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.ads.googleads.v19.services.KeywordPlanAdGroupService", - "credentialsType": None, - } - ), - ) - - def mutate_keyword_plan_ad_groups( - self, - request: Optional[ - Union[ - keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - keyword_plan_ad_group_service.KeywordPlanAdGroupOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse: - r"""Creates, updates, or removes Keyword Plan ad groups. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupsRequest, dict]): - The request object. Request message for - [KeywordPlanAdGroupService.MutateKeywordPlanAdGroups][google.ads.googleads.v19.services.KeywordPlanAdGroupService.MutateKeywordPlanAdGroups]. - customer_id (str): - Required. The ID of the customer - whose Keyword Plan ad groups are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanAdGroupOperation]): - Required. The list of operations to - perform on individual Keyword Plan ad - groups. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupsResponse: - Response message for a Keyword Plan - ad group mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest, - ): - request = ( - keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_keyword_plan_ad_groups - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "KeywordPlanAdGroupServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("KeywordPlanAdGroupServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/base.py b/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/base.py deleted file mode 100644 index f9d9673d0..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - keyword_plan_ad_group_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class KeywordPlanAdGroupServiceTransport(abc.ABC): - """Abstract transport class for KeywordPlanAdGroupService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_keyword_plan_ad_groups: gapic_v1.method.wrap_method( - self.mutate_keyword_plan_ad_groups, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_keyword_plan_ad_groups( - self, - ) -> Callable[ - [keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest], - Union[ - keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse, - Awaitable[ - keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("KeywordPlanAdGroupServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/grpc.py b/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/grpc.py deleted file mode 100644 index 4ac566578..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/grpc.py +++ /dev/null @@ -1,394 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - keyword_plan_ad_group_service, -) -from .base import KeywordPlanAdGroupServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.KeywordPlanAdGroupService", - "rpcName": str(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.ads.googleads.v19.services.KeywordPlanAdGroupService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanAdGroupServiceGrpcTransport( - KeywordPlanAdGroupServiceTransport -): - """gRPC backend transport for KeywordPlanAdGroupService. - - Service to manage Keyword Plan ad groups. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_keyword_plan_ad_groups( - self, - ) -> Callable[ - [keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest], - keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse, - ]: - r"""Return a callable for the mutate keyword plan ad groups method over gRPC. - - Creates, updates, or removes Keyword Plan ad groups. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.MutateKeywordPlanAdGroupsRequest], - ~.MutateKeywordPlanAdGroupsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_keyword_plan_ad_groups" not in self._stubs: - self._stubs["mutate_keyword_plan_ad_groups"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanAdGroupService/MutateKeywordPlanAdGroups", - request_serializer=keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest.serialize, - response_deserializer=keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse.deserialize, - ) - ) - return self._stubs["mutate_keyword_plan_ad_groups"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("KeywordPlanAdGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/grpc_asyncio.py deleted file mode 100644 index 6a618dc79..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,417 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - keyword_plan_ad_group_service, -) -from .base import KeywordPlanAdGroupServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.KeywordPlanAdGroupService", - "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.ads.googleads.v19.services.KeywordPlanAdGroupService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanAdGroupServiceGrpcAsyncIOTransport( - KeywordPlanAdGroupServiceTransport -): - """gRPC AsyncIO backend transport for KeywordPlanAdGroupService. - - Service to manage Keyword Plan ad groups. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_keyword_plan_ad_groups( - self, - ) -> Callable[ - [keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest], - Awaitable[ - keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse - ], - ]: - r"""Return a callable for the mutate keyword plan ad groups method over gRPC. - - Creates, updates, or removes Keyword Plan ad groups. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.MutateKeywordPlanAdGroupsRequest], - Awaitable[~.MutateKeywordPlanAdGroupsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_keyword_plan_ad_groups" not in self._stubs: - self._stubs["mutate_keyword_plan_ad_groups"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanAdGroupService/MutateKeywordPlanAdGroups", - request_serializer=keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest.serialize, - response_deserializer=keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse.deserialize, - ) - ) - return self._stubs["mutate_keyword_plan_ad_groups"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_keyword_plan_ad_groups: self._wrap_method( - self.mutate_keyword_plan_ad_groups, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("KeywordPlanAdGroupServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/async_client.py b/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/async_client.py deleted file mode 100644 index 4a21b4fda..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/async_client.py +++ /dev/null @@ -1,461 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - keyword_plan_campaign_keyword_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - KeywordPlanCampaignKeywordServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import KeywordPlanCampaignKeywordServiceClient - -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 KeywordPlanCampaignKeywordServiceAsyncClient: - """Service to manage Keyword Plan campaign keywords. - KeywordPlanCampaign is required to add the campaign keywords. - Only negative keywords are supported. A maximum of 1000 negative - keywords are allowed per plan. This includes both campaign - negative keywords and ad group negative keywords. - """ - - _client: KeywordPlanCampaignKeywordServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = KeywordPlanCampaignKeywordServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - KeywordPlanCampaignKeywordServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - KeywordPlanCampaignKeywordServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ( - KeywordPlanCampaignKeywordServiceClient._DEFAULT_UNIVERSE - ) - - keyword_plan_campaign_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.keyword_plan_campaign_path - ) - parse_keyword_plan_campaign_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.parse_keyword_plan_campaign_path - ) - keyword_plan_campaign_keyword_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.keyword_plan_campaign_keyword_path - ) - parse_keyword_plan_campaign_keyword_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.parse_keyword_plan_campaign_keyword_path - ) - common_billing_account_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - KeywordPlanCampaignKeywordServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanCampaignKeywordServiceAsyncClient: The constructed client. - """ - return KeywordPlanCampaignKeywordServiceClient.from_service_account_info.__func__(KeywordPlanCampaignKeywordServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanCampaignKeywordServiceAsyncClient: The constructed client. - """ - return KeywordPlanCampaignKeywordServiceClient.from_service_account_file.__func__(KeywordPlanCampaignKeywordServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return KeywordPlanCampaignKeywordServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> KeywordPlanCampaignKeywordServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanCampaignKeywordServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - KeywordPlanCampaignKeywordServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanCampaignKeywordServiceTransport, - Callable[..., KeywordPlanCampaignKeywordServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan campaign keyword service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanCampaignKeywordServiceTransport,Callable[..., KeywordPlanCampaignKeywordServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanCampaignKeywordServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = KeywordPlanCampaignKeywordServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.KeywordPlanCampaignKeywordServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanCampaignKeywordService", - "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.ads.googleads.v19.services.KeywordPlanCampaignKeywordService", - "credentialsType": None, - } - ), - ) - - async def mutate_keyword_plan_campaign_keywords( - self, - request: Optional[ - Union[ - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - keyword_plan_campaign_keyword_service.KeywordPlanCampaignKeywordOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse - ): - r"""Creates, updates, or removes Keyword Plan campaign keywords. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupKeywordError <>`__ - `KeywordPlanCampaignKeywordError <>`__ `QuotaError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateKeywordPlanCampaignKeywordsRequest, dict]]): - The request object. Request message for - [KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords][google.ads.googleads.v19.services.KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords]. - customer_id (:class:`str`): - Required. The ID of the customer - whose campaign keywords are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanCampaignKeywordOperation]`): - Required. The list of operations to - perform on individual Keyword Plan - campaign keywords. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateKeywordPlanCampaignKeywordsResponse: - Response message for a Keyword Plan - campaign keyword mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest, - ): - request = keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_keyword_plan_campaign_keywords - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__( - self, - ) -> "KeywordPlanCampaignKeywordServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("KeywordPlanCampaignKeywordServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/client.py b/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/client.py deleted file mode 100644 index ed9c136e1..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/client.py +++ /dev/null @@ -1,938 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - keyword_plan_campaign_keyword_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - KeywordPlanCampaignKeywordServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import KeywordPlanCampaignKeywordServiceGrpcTransport -from .transports.grpc_asyncio import ( - KeywordPlanCampaignKeywordServiceGrpcAsyncIOTransport, -) - - -class KeywordPlanCampaignKeywordServiceClientMeta(type): - """Metaclass for the KeywordPlanCampaignKeywordService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[KeywordPlanCampaignKeywordServiceTransport]] - _transport_registry["grpc"] = KeywordPlanCampaignKeywordServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - KeywordPlanCampaignKeywordServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[KeywordPlanCampaignKeywordServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class KeywordPlanCampaignKeywordServiceClient( - metaclass=KeywordPlanCampaignKeywordServiceClientMeta -): - """Service to manage Keyword Plan campaign keywords. - KeywordPlanCampaign is required to add the campaign keywords. - Only negative keywords are supported. A maximum of 1000 negative - keywords are allowed per plan. This includes both campaign - negative keywords and ad group negative keywords. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanCampaignKeywordServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanCampaignKeywordServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> KeywordPlanCampaignKeywordServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanCampaignKeywordServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def keyword_plan_campaign_path( - customer_id: str, - keyword_plan_campaign_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_campaign string.""" - return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( - customer_id=customer_id, - keyword_plan_campaign_id=keyword_plan_campaign_id, - ) - - @staticmethod - def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_campaign_keyword_path( - customer_id: str, - keyword_plan_campaign_keyword_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_campaign_keyword string.""" - return "customers/{customer_id}/keywordPlanCampaignKeywords/{keyword_plan_campaign_keyword_id}".format( - customer_id=customer_id, - keyword_plan_campaign_keyword_id=keyword_plan_campaign_keyword_id, - ) - - @staticmethod - def parse_keyword_plan_campaign_keyword_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_campaign_keyword path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanCampaignKeywords/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - KeywordPlanCampaignKeywordServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - KeywordPlanCampaignKeywordServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = KeywordPlanCampaignKeywordServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - KeywordPlanCampaignKeywordServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanCampaignKeywordServiceTransport, - Callable[..., KeywordPlanCampaignKeywordServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan campaign keyword service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanCampaignKeywordServiceTransport,Callable[..., KeywordPlanCampaignKeywordServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanCampaignKeywordServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ( - KeywordPlanCampaignKeywordServiceClient._read_environment_variables() - ) - self._client_cert_source = ( - KeywordPlanCampaignKeywordServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - KeywordPlanCampaignKeywordServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, KeywordPlanCampaignKeywordServiceTransport - ) - if transport_provided: - # transport is a KeywordPlanCampaignKeywordServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - KeywordPlanCampaignKeywordServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or KeywordPlanCampaignKeywordServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[KeywordPlanCampaignKeywordServiceTransport], - Callable[..., KeywordPlanCampaignKeywordServiceTransport], - ] = ( - KeywordPlanCampaignKeywordServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., KeywordPlanCampaignKeywordServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.KeywordPlanCampaignKeywordServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanCampaignKeywordService", - "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.ads.googleads.v19.services.KeywordPlanCampaignKeywordService", - "credentialsType": None, - } - ), - ) - - def mutate_keyword_plan_campaign_keywords( - self, - request: Optional[ - Union[ - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - keyword_plan_campaign_keyword_service.KeywordPlanCampaignKeywordOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse - ): - r"""Creates, updates, or removes Keyword Plan campaign keywords. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupKeywordError <>`__ - `KeywordPlanCampaignKeywordError <>`__ `QuotaError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateKeywordPlanCampaignKeywordsRequest, dict]): - The request object. Request message for - [KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords][google.ads.googleads.v19.services.KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords]. - customer_id (str): - Required. The ID of the customer - whose campaign keywords are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanCampaignKeywordOperation]): - Required. The list of operations to - perform on individual Keyword Plan - campaign keywords. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateKeywordPlanCampaignKeywordsResponse: - Response message for a Keyword Plan - campaign keyword mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest, - ): - request = keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_keyword_plan_campaign_keywords - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "KeywordPlanCampaignKeywordServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("KeywordPlanCampaignKeywordServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/base.py b/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/base.py deleted file mode 100644 index 13500aaf0..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - keyword_plan_campaign_keyword_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class KeywordPlanCampaignKeywordServiceTransport(abc.ABC): - """Abstract transport class for KeywordPlanCampaignKeywordService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_keyword_plan_campaign_keywords: gapic_v1.method.wrap_method( - self.mutate_keyword_plan_campaign_keywords, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_keyword_plan_campaign_keywords( - self, - ) -> Callable[ - [ - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest - ], - Union[ - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse, - Awaitable[ - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("KeywordPlanCampaignKeywordServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/grpc.py b/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/grpc.py deleted file mode 100644 index f0d25388b..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/grpc.py +++ /dev/null @@ -1,403 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - keyword_plan_campaign_keyword_service, -) -from .base import ( - KeywordPlanCampaignKeywordServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.KeywordPlanCampaignKeywordService", - "rpcName": str(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.ads.googleads.v19.services.KeywordPlanCampaignKeywordService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanCampaignKeywordServiceGrpcTransport( - KeywordPlanCampaignKeywordServiceTransport -): - """gRPC backend transport for KeywordPlanCampaignKeywordService. - - Service to manage Keyword Plan campaign keywords. - KeywordPlanCampaign is required to add the campaign keywords. - Only negative keywords are supported. A maximum of 1000 negative - keywords are allowed per plan. This includes both campaign - negative keywords and ad group negative keywords. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_keyword_plan_campaign_keywords( - self, - ) -> Callable[ - [ - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest - ], - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse, - ]: - r"""Return a callable for the mutate keyword plan campaign - keywords method over gRPC. - - Creates, updates, or removes Keyword Plan campaign keywords. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupKeywordError <>`__ - `KeywordPlanCampaignKeywordError <>`__ `QuotaError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.MutateKeywordPlanCampaignKeywordsRequest], - ~.MutateKeywordPlanCampaignKeywordsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_keyword_plan_campaign_keywords" not in self._stubs: - self._stubs["mutate_keyword_plan_campaign_keywords"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanCampaignKeywordService/MutateKeywordPlanCampaignKeywords", - request_serializer=keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest.serialize, - response_deserializer=keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse.deserialize, - ) - ) - return self._stubs["mutate_keyword_plan_campaign_keywords"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("KeywordPlanCampaignKeywordServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/grpc_asyncio.py deleted file mode 100644 index 3e8a877a7..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,426 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - keyword_plan_campaign_keyword_service, -) -from .base import ( - KeywordPlanCampaignKeywordServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.KeywordPlanCampaignKeywordService", - "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.ads.googleads.v19.services.KeywordPlanCampaignKeywordService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanCampaignKeywordServiceGrpcAsyncIOTransport( - KeywordPlanCampaignKeywordServiceTransport -): - """gRPC AsyncIO backend transport for KeywordPlanCampaignKeywordService. - - Service to manage Keyword Plan campaign keywords. - KeywordPlanCampaign is required to add the campaign keywords. - Only negative keywords are supported. A maximum of 1000 negative - keywords are allowed per plan. This includes both campaign - negative keywords and ad group negative keywords. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_keyword_plan_campaign_keywords( - self, - ) -> Callable[ - [ - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest - ], - Awaitable[ - keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse - ], - ]: - r"""Return a callable for the mutate keyword plan campaign - keywords method over gRPC. - - Creates, updates, or removes Keyword Plan campaign keywords. - Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanAdGroupKeywordError <>`__ - `KeywordPlanCampaignKeywordError <>`__ `QuotaError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.MutateKeywordPlanCampaignKeywordsRequest], - Awaitable[~.MutateKeywordPlanCampaignKeywordsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_keyword_plan_campaign_keywords" not in self._stubs: - self._stubs["mutate_keyword_plan_campaign_keywords"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanCampaignKeywordService/MutateKeywordPlanCampaignKeywords", - request_serializer=keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest.serialize, - response_deserializer=keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse.deserialize, - ) - ) - return self._stubs["mutate_keyword_plan_campaign_keywords"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_keyword_plan_campaign_keywords: self._wrap_method( - self.mutate_keyword_plan_campaign_keywords, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("KeywordPlanCampaignKeywordServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/async_client.py b/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/async_client.py deleted file mode 100644 index 8eac69278..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/async_client.py +++ /dev/null @@ -1,463 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - keyword_plan_campaign_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - KeywordPlanCampaignServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import KeywordPlanCampaignServiceClient - -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 KeywordPlanCampaignServiceAsyncClient: - """Service to manage Keyword Plan campaigns.""" - - _client: KeywordPlanCampaignServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = KeywordPlanCampaignServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - KeywordPlanCampaignServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - KeywordPlanCampaignServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = KeywordPlanCampaignServiceClient._DEFAULT_UNIVERSE - - geo_target_constant_path = staticmethod( - KeywordPlanCampaignServiceClient.geo_target_constant_path - ) - parse_geo_target_constant_path = staticmethod( - KeywordPlanCampaignServiceClient.parse_geo_target_constant_path - ) - keyword_plan_path = staticmethod( - KeywordPlanCampaignServiceClient.keyword_plan_path - ) - parse_keyword_plan_path = staticmethod( - KeywordPlanCampaignServiceClient.parse_keyword_plan_path - ) - keyword_plan_campaign_path = staticmethod( - KeywordPlanCampaignServiceClient.keyword_plan_campaign_path - ) - parse_keyword_plan_campaign_path = staticmethod( - KeywordPlanCampaignServiceClient.parse_keyword_plan_campaign_path - ) - language_constant_path = staticmethod( - KeywordPlanCampaignServiceClient.language_constant_path - ) - parse_language_constant_path = staticmethod( - KeywordPlanCampaignServiceClient.parse_language_constant_path - ) - common_billing_account_path = staticmethod( - KeywordPlanCampaignServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - KeywordPlanCampaignServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - KeywordPlanCampaignServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - KeywordPlanCampaignServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - KeywordPlanCampaignServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - KeywordPlanCampaignServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - KeywordPlanCampaignServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - KeywordPlanCampaignServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - KeywordPlanCampaignServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - KeywordPlanCampaignServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanCampaignServiceAsyncClient: The constructed client. - """ - return KeywordPlanCampaignServiceClient.from_service_account_info.__func__(KeywordPlanCampaignServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanCampaignServiceAsyncClient: The constructed client. - """ - return KeywordPlanCampaignServiceClient.from_service_account_file.__func__(KeywordPlanCampaignServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return KeywordPlanCampaignServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> KeywordPlanCampaignServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanCampaignServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = KeywordPlanCampaignServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanCampaignServiceTransport, - Callable[..., KeywordPlanCampaignServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan campaign service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanCampaignServiceTransport,Callable[..., KeywordPlanCampaignServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanCampaignServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = KeywordPlanCampaignServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.KeywordPlanCampaignServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanCampaignService", - "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.ads.googleads.v19.services.KeywordPlanCampaignService", - "credentialsType": None, - } - ), - ) - - async def mutate_keyword_plan_campaigns( - self, - request: Optional[ - Union[ - keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - keyword_plan_campaign_service.KeywordPlanCampaignOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse: - r"""Creates, updates, or removes Keyword Plan campaigns. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ - `ListOperationError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateKeywordPlanCampaignsRequest, dict]]): - The request object. Request message for - [KeywordPlanCampaignService.MutateKeywordPlanCampaigns][google.ads.googleads.v19.services.KeywordPlanCampaignService.MutateKeywordPlanCampaigns]. - customer_id (:class:`str`): - Required. The ID of the customer - whose Keyword Plan campaigns are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanCampaignOperation]`): - Required. The list of operations to - perform on individual Keyword Plan - campaigns. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateKeywordPlanCampaignsResponse: - Response message for a Keyword Plan - campaign mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest, - ): - request = ( - keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_keyword_plan_campaigns - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "KeywordPlanCampaignServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("KeywordPlanCampaignServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/client.py b/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/client.py deleted file mode 100644 index fc42a96d1..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/client.py +++ /dev/null @@ -1,958 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - keyword_plan_campaign_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - KeywordPlanCampaignServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import KeywordPlanCampaignServiceGrpcTransport -from .transports.grpc_asyncio import ( - KeywordPlanCampaignServiceGrpcAsyncIOTransport, -) - - -class KeywordPlanCampaignServiceClientMeta(type): - """Metaclass for the KeywordPlanCampaignService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[KeywordPlanCampaignServiceTransport]] - _transport_registry["grpc"] = KeywordPlanCampaignServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - KeywordPlanCampaignServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[KeywordPlanCampaignServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class KeywordPlanCampaignServiceClient( - metaclass=KeywordPlanCampaignServiceClientMeta -): - """Service to manage Keyword Plan campaigns.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanCampaignServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanCampaignServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> KeywordPlanCampaignServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanCampaignServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def geo_target_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified geo_target_constant string.""" - return "geoTargetConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_geo_target_constant_path(path: str) -> Dict[str, str]: - """Parses a geo_target_constant path into its component segments.""" - m = re.match(r"^geoTargetConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_path( - customer_id: str, - keyword_plan_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan string.""" - return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( - customer_id=customer_id, - keyword_plan_id=keyword_plan_id, - ) - - @staticmethod - def parse_keyword_plan_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_plan_campaign_path( - customer_id: str, - keyword_plan_campaign_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan_campaign string.""" - return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( - customer_id=customer_id, - keyword_plan_campaign_id=keyword_plan_campaign_id, - ) - - @staticmethod - def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan_campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def language_constant_path( - criterion_id: str, - ) -> str: - """Returns a fully-qualified language_constant string.""" - return "languageConstants/{criterion_id}".format( - criterion_id=criterion_id, - ) - - @staticmethod - def parse_language_constant_path(path: str) -> Dict[str, str]: - """Parses a language_constant path into its component segments.""" - m = re.match(r"^languageConstants/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - KeywordPlanCampaignServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - KeywordPlanCampaignServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = KeywordPlanCampaignServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = KeywordPlanCampaignServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanCampaignServiceTransport, - Callable[..., KeywordPlanCampaignServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan campaign service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanCampaignServiceTransport,Callable[..., KeywordPlanCampaignServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanCampaignServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = KeywordPlanCampaignServiceClient._read_environment_variables() - self._client_cert_source = ( - KeywordPlanCampaignServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - KeywordPlanCampaignServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, KeywordPlanCampaignServiceTransport - ) - if transport_provided: - # transport is a KeywordPlanCampaignServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - KeywordPlanCampaignServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or KeywordPlanCampaignServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[KeywordPlanCampaignServiceTransport], - Callable[..., KeywordPlanCampaignServiceTransport], - ] = ( - KeywordPlanCampaignServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., KeywordPlanCampaignServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.KeywordPlanCampaignServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanCampaignService", - "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.ads.googleads.v19.services.KeywordPlanCampaignService", - "credentialsType": None, - } - ), - ) - - def mutate_keyword_plan_campaigns( - self, - request: Optional[ - Union[ - keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - keyword_plan_campaign_service.KeywordPlanCampaignOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse: - r"""Creates, updates, or removes Keyword Plan campaigns. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ - `ListOperationError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateKeywordPlanCampaignsRequest, dict]): - The request object. Request message for - [KeywordPlanCampaignService.MutateKeywordPlanCampaigns][google.ads.googleads.v19.services.KeywordPlanCampaignService.MutateKeywordPlanCampaigns]. - customer_id (str): - Required. The ID of the customer - whose Keyword Plan campaigns are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanCampaignOperation]): - Required. The list of operations to - perform on individual Keyword Plan - campaigns. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateKeywordPlanCampaignsResponse: - Response message for a Keyword Plan - campaign mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest, - ): - request = ( - keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_keyword_plan_campaigns - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "KeywordPlanCampaignServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("KeywordPlanCampaignServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/base.py b/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/base.py deleted file mode 100644 index 67ea8c4ac..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - keyword_plan_campaign_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class KeywordPlanCampaignServiceTransport(abc.ABC): - """Abstract transport class for KeywordPlanCampaignService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_keyword_plan_campaigns: gapic_v1.method.wrap_method( - self.mutate_keyword_plan_campaigns, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_keyword_plan_campaigns( - self, - ) -> Callable[ - [keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest], - Union[ - keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse, - Awaitable[ - keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("KeywordPlanCampaignServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/grpc.py b/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/grpc.py deleted file mode 100644 index d022081a2..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/grpc.py +++ /dev/null @@ -1,394 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - keyword_plan_campaign_service, -) -from .base import KeywordPlanCampaignServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.KeywordPlanCampaignService", - "rpcName": str(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.ads.googleads.v19.services.KeywordPlanCampaignService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanCampaignServiceGrpcTransport( - KeywordPlanCampaignServiceTransport -): - """gRPC backend transport for KeywordPlanCampaignService. - - Service to manage Keyword Plan campaigns. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_keyword_plan_campaigns( - self, - ) -> Callable[ - [keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest], - keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse, - ]: - r"""Return a callable for the mutate keyword plan campaigns method over gRPC. - - Creates, updates, or removes Keyword Plan campaigns. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ - `ListOperationError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.MutateKeywordPlanCampaignsRequest], - ~.MutateKeywordPlanCampaignsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_keyword_plan_campaigns" not in self._stubs: - self._stubs["mutate_keyword_plan_campaigns"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanCampaignService/MutateKeywordPlanCampaigns", - request_serializer=keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest.serialize, - response_deserializer=keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse.deserialize, - ) - ) - return self._stubs["mutate_keyword_plan_campaigns"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("KeywordPlanCampaignServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/grpc_asyncio.py deleted file mode 100644 index e99cec753..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,417 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - keyword_plan_campaign_service, -) -from .base import KeywordPlanCampaignServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.KeywordPlanCampaignService", - "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.ads.googleads.v19.services.KeywordPlanCampaignService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanCampaignServiceGrpcAsyncIOTransport( - KeywordPlanCampaignServiceTransport -): - """gRPC AsyncIO backend transport for KeywordPlanCampaignService. - - Service to manage Keyword Plan campaigns. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_keyword_plan_campaigns( - self, - ) -> Callable[ - [keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest], - Awaitable[ - keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse - ], - ]: - r"""Return a callable for the mutate keyword plan campaigns method over gRPC. - - Creates, updates, or removes Keyword Plan campaigns. Operation - statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ - `ListOperationError <>`__ `MutateError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ - - Returns: - Callable[[~.MutateKeywordPlanCampaignsRequest], - Awaitable[~.MutateKeywordPlanCampaignsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_keyword_plan_campaigns" not in self._stubs: - self._stubs["mutate_keyword_plan_campaigns"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanCampaignService/MutateKeywordPlanCampaigns", - request_serializer=keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest.serialize, - response_deserializer=keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse.deserialize, - ) - ) - return self._stubs["mutate_keyword_plan_campaigns"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_keyword_plan_campaigns: self._wrap_method( - self.mutate_keyword_plan_campaigns, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("KeywordPlanCampaignServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/async_client.py b/google/ads/googleads/v19/services/services/keyword_plan_idea_service/async_client.py deleted file mode 100644 index bade505e7..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/async_client.py +++ /dev/null @@ -1,701 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.services.keyword_plan_idea_service import ( - pagers, -) -from google.ads.googleads.v19.services.types import keyword_plan_idea_service -from .transports.base import ( - KeywordPlanIdeaServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import KeywordPlanIdeaServiceClient - -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 KeywordPlanIdeaServiceAsyncClient: - """Service to generate keyword ideas.""" - - _client: KeywordPlanIdeaServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = KeywordPlanIdeaServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = KeywordPlanIdeaServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - KeywordPlanIdeaServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = KeywordPlanIdeaServiceClient._DEFAULT_UNIVERSE - - common_billing_account_path = staticmethod( - KeywordPlanIdeaServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - KeywordPlanIdeaServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - KeywordPlanIdeaServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - KeywordPlanIdeaServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - KeywordPlanIdeaServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - KeywordPlanIdeaServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - KeywordPlanIdeaServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - KeywordPlanIdeaServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - KeywordPlanIdeaServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - KeywordPlanIdeaServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanIdeaServiceAsyncClient: The constructed client. - """ - return KeywordPlanIdeaServiceClient.from_service_account_info.__func__(KeywordPlanIdeaServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanIdeaServiceAsyncClient: The constructed client. - """ - return KeywordPlanIdeaServiceClient.from_service_account_file.__func__(KeywordPlanIdeaServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return KeywordPlanIdeaServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> KeywordPlanIdeaServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanIdeaServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = KeywordPlanIdeaServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanIdeaServiceTransport, - Callable[..., KeywordPlanIdeaServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan idea service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanIdeaServiceTransport,Callable[..., KeywordPlanIdeaServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanIdeaServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = KeywordPlanIdeaServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.KeywordPlanIdeaServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanIdeaService", - "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.ads.googleads.v19.services.KeywordPlanIdeaService", - "credentialsType": None, - } - ), - ) - - async def generate_keyword_ideas( - self, - request: Optional[ - Union[keyword_plan_idea_service.GenerateKeywordIdeasRequest, dict] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.GenerateKeywordIdeasAsyncPager: - r"""Returns a list of keyword ideas. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanIdeaError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateKeywordIdeasRequest, dict]]): - The request object. Request message for - [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.keyword_plan_idea_service.pagers.GenerateKeywordIdeasAsyncPager: - Response message for - [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, keyword_plan_idea_service.GenerateKeywordIdeasRequest - ): - request = keyword_plan_idea_service.GenerateKeywordIdeasRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_keyword_ideas - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__aiter__` convenience method. - response = pagers.GenerateKeywordIdeasAsyncPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def generate_keyword_historical_metrics( - self, - request: Optional[ - Union[ - keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse: - r"""Returns a list of keyword historical metrics. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateKeywordHistoricalMetricsRequest, dict]]): - The request object. Request message for - [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateKeywordHistoricalMetricsResponse: - Response message for - [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest, - ): - request = keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_keyword_historical_metrics - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def generate_ad_group_themes( - self, - request: Optional[ - Union[keyword_plan_idea_service.GenerateAdGroupThemesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - keywords: Optional[MutableSequence[str]] = None, - ad_groups: Optional[MutableSequence[str]] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_idea_service.GenerateAdGroupThemesResponse: - r"""Returns a list of suggested AdGroups and suggested modifications - (text, match type) for the given keywords. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateAdGroupThemesRequest, dict]]): - The request object. Request message for - [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. - customer_id (:class:`str`): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - keywords (:class:`MutableSequence[str]`): - Required. A list of keywords to group - into the provided AdGroups. - - This corresponds to the ``keywords`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - ad_groups (:class:`MutableSequence[str]`): - Required. A list of resource names of AdGroups to group - keywords into. Resource name format: - ``customers/{customer_id}/adGroups/{ad_group_id}`` - - This corresponds to the ``ad_groups`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateAdGroupThemesResponse: - Response message for - [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, keywords, ad_groups] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, keyword_plan_idea_service.GenerateAdGroupThemesRequest - ): - request = keyword_plan_idea_service.GenerateAdGroupThemesRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if keywords: - request.keywords.extend(keywords) - if ad_groups: - request.ad_groups.extend(ad_groups) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_ad_group_themes - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def generate_keyword_forecast_metrics( - self, - request: Optional[ - Union[ - keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest, - dict, - ] - ] = None, - *, - campaign: Optional[keyword_plan_idea_service.CampaignToForecast] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse: - r"""Returns metrics (such as impressions, clicks, total cost) of a - keyword forecast for the given campaign. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateKeywordForecastMetricsRequest, dict]]): - The request object. Request message for - [KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. - campaign (:class:`google.ads.googleads.v19.services.types.CampaignToForecast`): - Required. The campaign used in the - forecast. - - This corresponds to the ``campaign`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateKeywordForecastMetricsResponse: - Response message for - [KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [campaign] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest, - ): - request = ( - keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if campaign is not None: - request.campaign = campaign - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_keyword_forecast_metrics - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "KeywordPlanIdeaServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("KeywordPlanIdeaServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/client.py b/google/ads/googleads/v19/services/services/keyword_plan_idea_service/client.py deleted file mode 100644 index f55a012ce..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/client.py +++ /dev/null @@ -1,1142 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.services.keyword_plan_idea_service import ( - pagers, -) -from google.ads.googleads.v19.services.types import keyword_plan_idea_service -from .transports.base import ( - KeywordPlanIdeaServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import KeywordPlanIdeaServiceGrpcTransport -from .transports.grpc_asyncio import KeywordPlanIdeaServiceGrpcAsyncIOTransport - - -class KeywordPlanIdeaServiceClientMeta(type): - """Metaclass for the KeywordPlanIdeaService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[KeywordPlanIdeaServiceTransport]] - _transport_registry["grpc"] = KeywordPlanIdeaServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - KeywordPlanIdeaServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[KeywordPlanIdeaServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class KeywordPlanIdeaServiceClient(metaclass=KeywordPlanIdeaServiceClientMeta): - """Service to generate keyword ideas.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanIdeaServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanIdeaServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> KeywordPlanIdeaServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanIdeaServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = KeywordPlanIdeaServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = KeywordPlanIdeaServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - KeywordPlanIdeaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = KeywordPlanIdeaServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanIdeaServiceTransport, - Callable[..., KeywordPlanIdeaServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan idea service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanIdeaServiceTransport,Callable[..., KeywordPlanIdeaServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanIdeaServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = KeywordPlanIdeaServiceClient._read_environment_variables() - self._client_cert_source = ( - KeywordPlanIdeaServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - KeywordPlanIdeaServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, KeywordPlanIdeaServiceTransport - ) - if transport_provided: - # transport is a KeywordPlanIdeaServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(KeywordPlanIdeaServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or KeywordPlanIdeaServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[KeywordPlanIdeaServiceTransport], - Callable[..., KeywordPlanIdeaServiceTransport], - ] = ( - KeywordPlanIdeaServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., KeywordPlanIdeaServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.KeywordPlanIdeaServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanIdeaService", - "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.ads.googleads.v19.services.KeywordPlanIdeaService", - "credentialsType": None, - } - ), - ) - - def generate_keyword_ideas( - self, - request: Optional[ - Union[keyword_plan_idea_service.GenerateKeywordIdeasRequest, dict] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> pagers.GenerateKeywordIdeasPager: - r"""Returns a list of keyword ideas. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanIdeaError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateKeywordIdeasRequest, dict]): - The request object. Request message for - [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.services.keyword_plan_idea_service.pagers.GenerateKeywordIdeasPager: - Response message for - [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. - - Iterating over this object will yield results and - resolve additional pages automatically. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, keyword_plan_idea_service.GenerateKeywordIdeasRequest - ): - request = keyword_plan_idea_service.GenerateKeywordIdeasRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_keyword_ideas - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # This method is paged; wrap the response in a pager, which provides - # an `__iter__` convenience method. - response = pagers.GenerateKeywordIdeasPager( - method=rpc, - request=request, - response=response, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def generate_keyword_historical_metrics( - self, - request: Optional[ - Union[ - keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse: - r"""Returns a list of keyword historical metrics. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateKeywordHistoricalMetricsRequest, dict]): - The request object. Request message for - [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateKeywordHistoricalMetricsResponse: - Response message for - [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest, - ): - request = keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_keyword_historical_metrics - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def generate_ad_group_themes( - self, - request: Optional[ - Union[keyword_plan_idea_service.GenerateAdGroupThemesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - keywords: Optional[MutableSequence[str]] = None, - ad_groups: Optional[MutableSequence[str]] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_idea_service.GenerateAdGroupThemesResponse: - r"""Returns a list of suggested AdGroups and suggested modifications - (text, match type) for the given keywords. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateAdGroupThemesRequest, dict]): - The request object. Request message for - [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. - customer_id (str): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - keywords (MutableSequence[str]): - Required. A list of keywords to group - into the provided AdGroups. - - This corresponds to the ``keywords`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - ad_groups (MutableSequence[str]): - Required. A list of resource names of AdGroups to group - keywords into. Resource name format: - ``customers/{customer_id}/adGroups/{ad_group_id}`` - - This corresponds to the ``ad_groups`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateAdGroupThemesResponse: - Response message for - [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, keywords, ad_groups] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, keyword_plan_idea_service.GenerateAdGroupThemesRequest - ): - request = keyword_plan_idea_service.GenerateAdGroupThemesRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if keywords is not None: - request.keywords = keywords - if ad_groups is not None: - request.ad_groups = ad_groups - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_ad_group_themes - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def generate_keyword_forecast_metrics( - self, - request: Optional[ - Union[ - keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest, - dict, - ] - ] = None, - *, - campaign: Optional[keyword_plan_idea_service.CampaignToForecast] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse: - r"""Returns metrics (such as impressions, clicks, total cost) of a - keyword forecast for the given campaign. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateKeywordForecastMetricsRequest, dict]): - The request object. Request message for - [KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. - campaign (google.ads.googleads.v19.services.types.CampaignToForecast): - Required. The campaign used in the - forecast. - - This corresponds to the ``campaign`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateKeywordForecastMetricsResponse: - Response message for - [KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [campaign] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest, - ): - request = ( - keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if campaign is not None: - request.campaign = campaign - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_keyword_forecast_metrics - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "KeywordPlanIdeaServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("KeywordPlanIdeaServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/pagers.py b/google/ads/googleads/v19/services/services/keyword_plan_idea_service/pagers.py deleted file mode 100644 index 7f5cf7750..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/pagers.py +++ /dev/null @@ -1,212 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.api_core import retry_async as retries_async -from typing import ( - Any, - AsyncIterator, - Awaitable, - Callable, - Sequence, - Tuple, - Iterator, - Union, -) - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] - OptionalAsyncRetry = Union[ - retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.Retry, object, None] # type: ignore - OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import keyword_plan_idea_service - - -class GenerateKeywordIdeasPager: - """A pager for iterating through ``generate_keyword_ideas`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.GenerateKeywordIdeaResponse` object, and - provides an ``__iter__`` method to iterate through its - ``results`` field. - - If there are more pages, the ``__iter__`` method will make additional - ``GenerateKeywordIdeas`` requests and continue to iterate - through the ``results`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.GenerateKeywordIdeaResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[ - ..., keyword_plan_idea_service.GenerateKeywordIdeaResponse - ], - request: keyword_plan_idea_service.GenerateKeywordIdeasRequest, - response: keyword_plan_idea_service.GenerateKeywordIdeaResponse, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiate the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.GenerateKeywordIdeasRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.GenerateKeywordIdeaResponse): - The initial response object. - retry (google.api_core.retry.Retry): Designation of what errors, - if any, should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = keyword_plan_idea_service.GenerateKeywordIdeasRequest( - request - ) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - def pages( - self, - ) -> Iterator[keyword_plan_idea_service.GenerateKeywordIdeaResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __iter__( - self, - ) -> Iterator[keyword_plan_idea_service.GenerateKeywordIdeaResult]: - for page in self.pages: - yield from page.results - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) - - -class GenerateKeywordIdeasAsyncPager: - """A pager for iterating through ``generate_keyword_ideas`` requests. - - This class thinly wraps an initial - :class:`google.ads.googleads.v19.services.types.GenerateKeywordIdeaResponse` object, and - provides an ``__aiter__`` method to iterate through its - ``results`` field. - - If there are more pages, the ``__aiter__`` method will make additional - ``GenerateKeywordIdeas`` requests and continue to iterate - through the ``results`` field on the - corresponding responses. - - All the usual :class:`google.ads.googleads.v19.services.types.GenerateKeywordIdeaResponse` - attributes are available on the pager. If multiple requests are made, only - the most recent response is retained, and thus used for attribute lookup. - """ - - def __init__( - self, - method: Callable[ - ..., - Awaitable[keyword_plan_idea_service.GenerateKeywordIdeaResponse], - ], - request: keyword_plan_idea_service.GenerateKeywordIdeasRequest, - response: keyword_plan_idea_service.GenerateKeywordIdeaResponse, - *, - retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ): - """Instantiates the pager. - - Args: - method (Callable): The method that was originally called, and - which instantiated this pager. - request (google.ads.googleads.v19.services.types.GenerateKeywordIdeasRequest): - The initial request object. - response (google.ads.googleads.v19.services.types.GenerateKeywordIdeaResponse): - The initial response object. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, 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 = keyword_plan_idea_service.GenerateKeywordIdeasRequest( - request - ) - self._response = response - self._retry = retry - self._timeout = timeout - self._metadata = metadata - - def __getattr__(self, name: str) -> Any: - return getattr(self._response, name) - - @property - async def pages( - self, - ) -> AsyncIterator[keyword_plan_idea_service.GenerateKeywordIdeaResponse]: - yield self._response - while self._response.next_page_token: - self._request.page_token = self._response.next_page_token - self._response = await self._method( - self._request, - retry=self._retry, - timeout=self._timeout, - metadata=self._metadata, - ) - yield self._response - - def __aiter__( - self, - ) -> AsyncIterator[keyword_plan_idea_service.GenerateKeywordIdeaResult]: - async def async_generator(): - async for page in self.pages: - for response in page.results: - yield response - - return async_generator() - - def __repr__(self) -> str: - return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/base.py b/google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/base.py deleted file mode 100644 index 763471e50..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/base.py +++ /dev/null @@ -1,227 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import keyword_plan_idea_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class KeywordPlanIdeaServiceTransport(abc.ABC): - """Abstract transport class for KeywordPlanIdeaService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.generate_keyword_ideas: gapic_v1.method.wrap_method( - self.generate_keyword_ideas, - default_timeout=None, - client_info=client_info, - ), - self.generate_keyword_historical_metrics: gapic_v1.method.wrap_method( - self.generate_keyword_historical_metrics, - default_timeout=None, - client_info=client_info, - ), - self.generate_ad_group_themes: gapic_v1.method.wrap_method( - self.generate_ad_group_themes, - default_timeout=None, - client_info=client_info, - ), - self.generate_keyword_forecast_metrics: gapic_v1.method.wrap_method( - self.generate_keyword_forecast_metrics, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def generate_keyword_ideas( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateKeywordIdeasRequest], - Union[ - keyword_plan_idea_service.GenerateKeywordIdeaResponse, - Awaitable[keyword_plan_idea_service.GenerateKeywordIdeaResponse], - ], - ]: - raise NotImplementedError() - - @property - def generate_keyword_historical_metrics( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest], - Union[ - keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse, - Awaitable[ - keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def generate_ad_group_themes( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateAdGroupThemesRequest], - Union[ - keyword_plan_idea_service.GenerateAdGroupThemesResponse, - Awaitable[keyword_plan_idea_service.GenerateAdGroupThemesResponse], - ], - ]: - raise NotImplementedError() - - @property - def generate_keyword_forecast_metrics( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest], - Union[ - keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse, - Awaitable[ - keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("KeywordPlanIdeaServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/grpc.py b/google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/grpc.py deleted file mode 100644 index d427b36fc..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/grpc.py +++ /dev/null @@ -1,499 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import keyword_plan_idea_service -from .base import KeywordPlanIdeaServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.KeywordPlanIdeaService", - "rpcName": str(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.ads.googleads.v19.services.KeywordPlanIdeaService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanIdeaServiceGrpcTransport(KeywordPlanIdeaServiceTransport): - """gRPC backend transport for KeywordPlanIdeaService. - - Service to generate keyword ideas. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def generate_keyword_ideas( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateKeywordIdeasRequest], - keyword_plan_idea_service.GenerateKeywordIdeaResponse, - ]: - r"""Return a callable for the generate keyword ideas method over gRPC. - - Returns a list of keyword ideas. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanIdeaError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateKeywordIdeasRequest], - ~.GenerateKeywordIdeaResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_keyword_ideas" not in self._stubs: - self._stubs["generate_keyword_ideas"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanIdeaService/GenerateKeywordIdeas", - request_serializer=keyword_plan_idea_service.GenerateKeywordIdeasRequest.serialize, - response_deserializer=keyword_plan_idea_service.GenerateKeywordIdeaResponse.deserialize, - ) - ) - return self._stubs["generate_keyword_ideas"] - - @property - def generate_keyword_historical_metrics( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest], - keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse, - ]: - r"""Return a callable for the generate keyword historical - metrics method over gRPC. - - Returns a list of keyword historical metrics. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateKeywordHistoricalMetricsRequest], - ~.GenerateKeywordHistoricalMetricsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_keyword_historical_metrics" not in self._stubs: - self._stubs["generate_keyword_historical_metrics"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanIdeaService/GenerateKeywordHistoricalMetrics", - request_serializer=keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest.serialize, - response_deserializer=keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse.deserialize, - ) - ) - return self._stubs["generate_keyword_historical_metrics"] - - @property - def generate_ad_group_themes( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateAdGroupThemesRequest], - keyword_plan_idea_service.GenerateAdGroupThemesResponse, - ]: - r"""Return a callable for the generate ad group themes method over gRPC. - - Returns a list of suggested AdGroups and suggested modifications - (text, match type) for the given keywords. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateAdGroupThemesRequest], - ~.GenerateAdGroupThemesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_ad_group_themes" not in self._stubs: - self._stubs["generate_ad_group_themes"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanIdeaService/GenerateAdGroupThemes", - request_serializer=keyword_plan_idea_service.GenerateAdGroupThemesRequest.serialize, - response_deserializer=keyword_plan_idea_service.GenerateAdGroupThemesResponse.deserialize, - ) - ) - return self._stubs["generate_ad_group_themes"] - - @property - def generate_keyword_forecast_metrics( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest], - keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse, - ]: - r"""Return a callable for the generate keyword forecast - metrics method over gRPC. - - Returns metrics (such as impressions, clicks, total cost) of a - keyword forecast for the given campaign. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateKeywordForecastMetricsRequest], - ~.GenerateKeywordForecastMetricsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_keyword_forecast_metrics" not in self._stubs: - self._stubs["generate_keyword_forecast_metrics"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanIdeaService/GenerateKeywordForecastMetrics", - request_serializer=keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest.serialize, - response_deserializer=keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse.deserialize, - ) - ) - return self._stubs["generate_keyword_forecast_metrics"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("KeywordPlanIdeaServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/grpc_asyncio.py deleted file mode 100644 index 1be12807a..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,541 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import keyword_plan_idea_service -from .base import KeywordPlanIdeaServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.KeywordPlanIdeaService", - "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.ads.googleads.v19.services.KeywordPlanIdeaService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanIdeaServiceGrpcAsyncIOTransport( - KeywordPlanIdeaServiceTransport -): - """gRPC AsyncIO backend transport for KeywordPlanIdeaService. - - Service to generate keyword ideas. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def generate_keyword_ideas( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateKeywordIdeasRequest], - Awaitable[keyword_plan_idea_service.GenerateKeywordIdeaResponse], - ]: - r"""Return a callable for the generate keyword ideas method over gRPC. - - Returns a list of keyword ideas. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `KeywordPlanIdeaError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateKeywordIdeasRequest], - Awaitable[~.GenerateKeywordIdeaResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_keyword_ideas" not in self._stubs: - self._stubs["generate_keyword_ideas"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanIdeaService/GenerateKeywordIdeas", - request_serializer=keyword_plan_idea_service.GenerateKeywordIdeasRequest.serialize, - response_deserializer=keyword_plan_idea_service.GenerateKeywordIdeaResponse.deserialize, - ) - ) - return self._stubs["generate_keyword_ideas"] - - @property - def generate_keyword_historical_metrics( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest], - Awaitable[ - keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse - ], - ]: - r"""Return a callable for the generate keyword historical - metrics method over gRPC. - - Returns a list of keyword historical metrics. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateKeywordHistoricalMetricsRequest], - Awaitable[~.GenerateKeywordHistoricalMetricsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_keyword_historical_metrics" not in self._stubs: - self._stubs["generate_keyword_historical_metrics"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanIdeaService/GenerateKeywordHistoricalMetrics", - request_serializer=keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest.serialize, - response_deserializer=keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse.deserialize, - ) - ) - return self._stubs["generate_keyword_historical_metrics"] - - @property - def generate_ad_group_themes( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateAdGroupThemesRequest], - Awaitable[keyword_plan_idea_service.GenerateAdGroupThemesResponse], - ]: - r"""Return a callable for the generate ad group themes method over gRPC. - - Returns a list of suggested AdGroups and suggested modifications - (text, match type) for the given keywords. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateAdGroupThemesRequest], - Awaitable[~.GenerateAdGroupThemesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_ad_group_themes" not in self._stubs: - self._stubs["generate_ad_group_themes"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanIdeaService/GenerateAdGroupThemes", - request_serializer=keyword_plan_idea_service.GenerateAdGroupThemesRequest.serialize, - response_deserializer=keyword_plan_idea_service.GenerateAdGroupThemesResponse.deserialize, - ) - ) - return self._stubs["generate_ad_group_themes"] - - @property - def generate_keyword_forecast_metrics( - self, - ) -> Callable[ - [keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest], - Awaitable[ - keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse - ], - ]: - r"""Return a callable for the generate keyword forecast - metrics method over gRPC. - - Returns metrics (such as impressions, clicks, total cost) of a - keyword forecast for the given campaign. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.GenerateKeywordForecastMetricsRequest], - Awaitable[~.GenerateKeywordForecastMetricsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_keyword_forecast_metrics" not in self._stubs: - self._stubs["generate_keyword_forecast_metrics"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanIdeaService/GenerateKeywordForecastMetrics", - request_serializer=keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest.serialize, - response_deserializer=keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse.deserialize, - ) - ) - return self._stubs["generate_keyword_forecast_metrics"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.generate_keyword_ideas: self._wrap_method( - self.generate_keyword_ideas, - default_timeout=None, - client_info=client_info, - ), - self.generate_keyword_historical_metrics: self._wrap_method( - self.generate_keyword_historical_metrics, - default_timeout=None, - client_info=client_info, - ), - self.generate_ad_group_themes: self._wrap_method( - self.generate_ad_group_themes, - default_timeout=None, - client_info=client_info, - ), - self.generate_keyword_forecast_metrics: self._wrap_method( - self.generate_keyword_forecast_metrics, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("KeywordPlanIdeaServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_service/async_client.py b/google/ads/googleads/v19/services/services/keyword_plan_service/async_client.py deleted file mode 100644 index b34b684e0..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_service/async_client.py +++ /dev/null @@ -1,423 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import keyword_plan_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import KeywordPlanServiceTransport, DEFAULT_CLIENT_INFO -from .client import KeywordPlanServiceClient - -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 KeywordPlanServiceAsyncClient: - """Service to manage keyword plans.""" - - _client: KeywordPlanServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = KeywordPlanServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = KeywordPlanServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - KeywordPlanServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = KeywordPlanServiceClient._DEFAULT_UNIVERSE - - keyword_plan_path = staticmethod(KeywordPlanServiceClient.keyword_plan_path) - parse_keyword_plan_path = staticmethod( - KeywordPlanServiceClient.parse_keyword_plan_path - ) - common_billing_account_path = staticmethod( - KeywordPlanServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - KeywordPlanServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - KeywordPlanServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - KeywordPlanServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - KeywordPlanServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - KeywordPlanServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - KeywordPlanServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - KeywordPlanServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - KeywordPlanServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - KeywordPlanServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanServiceAsyncClient: The constructed client. - """ - return KeywordPlanServiceClient.from_service_account_info.__func__(KeywordPlanServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanServiceAsyncClient: The constructed client. - """ - return KeywordPlanServiceClient.from_service_account_file.__func__(KeywordPlanServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return KeywordPlanServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> KeywordPlanServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = KeywordPlanServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanServiceTransport, - Callable[..., KeywordPlanServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanServiceTransport,Callable[..., KeywordPlanServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = KeywordPlanServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.KeywordPlanServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanService", - "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.ads.googleads.v19.services.KeywordPlanService", - "credentialsType": None, - } - ), - ) - - async def mutate_keyword_plans( - self, - request: Optional[ - Union[keyword_plan_service.MutateKeywordPlansRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[keyword_plan_service.KeywordPlanOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_service.MutateKeywordPlansResponse: - r"""Creates, updates, or removes keyword plans. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateKeywordPlansRequest, dict]]): - The request object. Request message for - [KeywordPlanService.MutateKeywordPlans][google.ads.googleads.v19.services.KeywordPlanService.MutateKeywordPlans]. - customer_id (:class:`str`): - Required. The ID of the customer - whose keyword plans are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanOperation]`): - Required. The list of operations to - perform on individual keyword plans. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateKeywordPlansResponse: - Response message for a keyword plan - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, keyword_plan_service.MutateKeywordPlansRequest - ): - request = keyword_plan_service.MutateKeywordPlansRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_keyword_plans - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "KeywordPlanServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("KeywordPlanServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_service/client.py b/google/ads/googleads/v19/services/services/keyword_plan_service/client.py deleted file mode 100644 index 53b9cf759..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_service/client.py +++ /dev/null @@ -1,873 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import keyword_plan_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import KeywordPlanServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import KeywordPlanServiceGrpcTransport -from .transports.grpc_asyncio import KeywordPlanServiceGrpcAsyncIOTransport - - -class KeywordPlanServiceClientMeta(type): - """Metaclass for the KeywordPlanService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[KeywordPlanServiceTransport]] - _transport_registry["grpc"] = KeywordPlanServiceGrpcTransport - _transport_registry["grpc_asyncio"] = KeywordPlanServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[KeywordPlanServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class KeywordPlanServiceClient(metaclass=KeywordPlanServiceClientMeta): - """Service to manage keyword plans.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordPlanServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> KeywordPlanServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordPlanServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def keyword_plan_path( - customer_id: str, - keyword_plan_id: str, - ) -> str: - """Returns a fully-qualified keyword_plan string.""" - return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( - customer_id=customer_id, - keyword_plan_id=keyword_plan_id, - ) - - @staticmethod - def parse_keyword_plan_path(path: str) -> Dict[str, str]: - """Parses a keyword_plan path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = KeywordPlanServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = KeywordPlanServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - KeywordPlanServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = KeywordPlanServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordPlanServiceTransport, - Callable[..., KeywordPlanServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword plan service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordPlanServiceTransport,Callable[..., KeywordPlanServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordPlanServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = KeywordPlanServiceClient._read_environment_variables() - self._client_cert_source = ( - KeywordPlanServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = KeywordPlanServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, KeywordPlanServiceTransport) - if transport_provided: - # transport is a KeywordPlanServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(KeywordPlanServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or KeywordPlanServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[KeywordPlanServiceTransport], - Callable[..., KeywordPlanServiceTransport], - ] = ( - KeywordPlanServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., KeywordPlanServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.KeywordPlanServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordPlanService", - "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.ads.googleads.v19.services.KeywordPlanService", - "credentialsType": None, - } - ), - ) - - def mutate_keyword_plans( - self, - request: Optional[ - Union[keyword_plan_service.MutateKeywordPlansRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[keyword_plan_service.KeywordPlanOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_plan_service.MutateKeywordPlansResponse: - r"""Creates, updates, or removes keyword plans. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateKeywordPlansRequest, dict]): - The request object. Request message for - [KeywordPlanService.MutateKeywordPlans][google.ads.googleads.v19.services.KeywordPlanService.MutateKeywordPlans]. - customer_id (str): - Required. The ID of the customer - whose keyword plans are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanOperation]): - Required. The list of operations to - perform on individual keyword plans. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateKeywordPlansResponse: - Response message for a keyword plan - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, keyword_plan_service.MutateKeywordPlansRequest - ): - request = keyword_plan_service.MutateKeywordPlansRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_keyword_plans - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "KeywordPlanServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("KeywordPlanServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_service/transports/base.py b/google/ads/googleads/v19/services/services/keyword_plan_service/transports/base.py deleted file mode 100644 index e92fb5520..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import keyword_plan_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class KeywordPlanServiceTransport(abc.ABC): - """Abstract transport class for KeywordPlanService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_keyword_plans: gapic_v1.method.wrap_method( - self.mutate_keyword_plans, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_keyword_plans( - self, - ) -> Callable[ - [keyword_plan_service.MutateKeywordPlansRequest], - Union[ - keyword_plan_service.MutateKeywordPlansResponse, - Awaitable[keyword_plan_service.MutateKeywordPlansResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("KeywordPlanServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_service/transports/grpc.py b/google/ads/googleads/v19/services/services/keyword_plan_service/transports/grpc.py deleted file mode 100644 index 11dc27679..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_service/transports/grpc.py +++ /dev/null @@ -1,389 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import keyword_plan_service -from .base import KeywordPlanServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.KeywordPlanService", - "rpcName": str(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.ads.googleads.v19.services.KeywordPlanService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanServiceGrpcTransport(KeywordPlanServiceTransport): - """gRPC backend transport for KeywordPlanService. - - Service to manage keyword plans. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_keyword_plans( - self, - ) -> Callable[ - [keyword_plan_service.MutateKeywordPlansRequest], - keyword_plan_service.MutateKeywordPlansResponse, - ]: - r"""Return a callable for the mutate keyword plans method over gRPC. - - Creates, updates, or removes keyword plans. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateKeywordPlansRequest], - ~.MutateKeywordPlansResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_keyword_plans" not in self._stubs: - self._stubs["mutate_keyword_plans"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanService/MutateKeywordPlans", - request_serializer=keyword_plan_service.MutateKeywordPlansRequest.serialize, - response_deserializer=keyword_plan_service.MutateKeywordPlansResponse.deserialize, - ) - ) - return self._stubs["mutate_keyword_plans"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("KeywordPlanServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/keyword_plan_service/transports/grpc_asyncio.py deleted file mode 100644 index 003c57436..000000000 --- a/google/ads/googleads/v19/services/services/keyword_plan_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,410 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import keyword_plan_service -from .base import KeywordPlanServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.KeywordPlanService", - "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.ads.googleads.v19.services.KeywordPlanService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordPlanServiceGrpcAsyncIOTransport(KeywordPlanServiceTransport): - """gRPC AsyncIO backend transport for KeywordPlanService. - - Service to manage keyword plans. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_keyword_plans( - self, - ) -> Callable[ - [keyword_plan_service.MutateKeywordPlansRequest], - Awaitable[keyword_plan_service.MutateKeywordPlansResponse], - ]: - r"""Return a callable for the mutate keyword plans method over gRPC. - - Creates, updates, or removes keyword plans. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `KeywordPlanError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `QuotaError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateKeywordPlansRequest], - Awaitable[~.MutateKeywordPlansResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_keyword_plans" not in self._stubs: - self._stubs["mutate_keyword_plans"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordPlanService/MutateKeywordPlans", - request_serializer=keyword_plan_service.MutateKeywordPlansRequest.serialize, - response_deserializer=keyword_plan_service.MutateKeywordPlansResponse.deserialize, - ) - ) - return self._stubs["mutate_keyword_plans"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_keyword_plans: self._wrap_method( - self.mutate_keyword_plans, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("KeywordPlanServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/async_client.py b/google/ads/googleads/v19/services/services/keyword_theme_constant_service/async_client.py deleted file mode 100644 index 9a21950b3..000000000 --- a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/async_client.py +++ /dev/null @@ -1,388 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - keyword_theme_constant_service, -) -from .transports.base import ( - KeywordThemeConstantServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import KeywordThemeConstantServiceClient - -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 KeywordThemeConstantServiceAsyncClient: - """Service to fetch Smart Campaign keyword themes.""" - - _client: KeywordThemeConstantServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = KeywordThemeConstantServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - KeywordThemeConstantServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - KeywordThemeConstantServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = KeywordThemeConstantServiceClient._DEFAULT_UNIVERSE - - keyword_theme_constant_path = staticmethod( - KeywordThemeConstantServiceClient.keyword_theme_constant_path - ) - parse_keyword_theme_constant_path = staticmethod( - KeywordThemeConstantServiceClient.parse_keyword_theme_constant_path - ) - common_billing_account_path = staticmethod( - KeywordThemeConstantServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - KeywordThemeConstantServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - KeywordThemeConstantServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - KeywordThemeConstantServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - KeywordThemeConstantServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - KeywordThemeConstantServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - KeywordThemeConstantServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - KeywordThemeConstantServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - KeywordThemeConstantServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - KeywordThemeConstantServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordThemeConstantServiceAsyncClient: The constructed client. - """ - return KeywordThemeConstantServiceClient.from_service_account_info.__func__(KeywordThemeConstantServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordThemeConstantServiceAsyncClient: The constructed client. - """ - return KeywordThemeConstantServiceClient.from_service_account_file.__func__(KeywordThemeConstantServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return KeywordThemeConstantServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> KeywordThemeConstantServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordThemeConstantServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = KeywordThemeConstantServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordThemeConstantServiceTransport, - Callable[..., KeywordThemeConstantServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword theme constant service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordThemeConstantServiceTransport,Callable[..., KeywordThemeConstantServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordThemeConstantServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = KeywordThemeConstantServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.KeywordThemeConstantServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordThemeConstantService", - "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.ads.googleads.v19.services.KeywordThemeConstantService", - "credentialsType": None, - } - ), - ) - - async def suggest_keyword_theme_constants( - self, - request: Optional[ - Union[ - keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse: - r"""Returns KeywordThemeConstant suggestions by keyword themes. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.SuggestKeywordThemeConstantsRequest, dict]]): - The request object. Request message for - [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v19.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestKeywordThemeConstantsResponse: - Response message for - [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v19.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest, - ): - request = keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.suggest_keyword_theme_constants - ] - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "KeywordThemeConstantServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("KeywordThemeConstantServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/client.py b/google/ads/googleads/v19/services/services/keyword_theme_constant_service/client.py deleted file mode 100644 index 2f62b5b55..000000000 --- a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/client.py +++ /dev/null @@ -1,842 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - keyword_theme_constant_service, -) -from .transports.base import ( - KeywordThemeConstantServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import KeywordThemeConstantServiceGrpcTransport -from .transports.grpc_asyncio import ( - KeywordThemeConstantServiceGrpcAsyncIOTransport, -) - - -class KeywordThemeConstantServiceClientMeta(type): - """Metaclass for the KeywordThemeConstantService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[KeywordThemeConstantServiceTransport]] - _transport_registry["grpc"] = KeywordThemeConstantServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - KeywordThemeConstantServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[KeywordThemeConstantServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class KeywordThemeConstantServiceClient( - metaclass=KeywordThemeConstantServiceClientMeta -): - """Service to fetch Smart Campaign keyword themes.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordThemeConstantServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - KeywordThemeConstantServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> KeywordThemeConstantServiceTransport: - """Returns the transport used by the client instance. - - Returns: - KeywordThemeConstantServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def keyword_theme_constant_path( - express_category_id: str, - express_sub_category_id: str, - ) -> str: - """Returns a fully-qualified keyword_theme_constant string.""" - return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( - express_category_id=express_category_id, - express_sub_category_id=express_sub_category_id, - ) - - @staticmethod - def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: - """Parses a keyword_theme_constant path into its component segments.""" - m = re.match( - r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - KeywordThemeConstantServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - KeywordThemeConstantServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = KeywordThemeConstantServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = KeywordThemeConstantServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - KeywordThemeConstantServiceTransport, - Callable[..., KeywordThemeConstantServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the keyword theme constant service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,KeywordThemeConstantServiceTransport,Callable[..., KeywordThemeConstantServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the KeywordThemeConstantServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = KeywordThemeConstantServiceClient._read_environment_variables() - self._client_cert_source = ( - KeywordThemeConstantServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - KeywordThemeConstantServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, KeywordThemeConstantServiceTransport - ) - if transport_provided: - # transport is a KeywordThemeConstantServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - KeywordThemeConstantServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or KeywordThemeConstantServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[KeywordThemeConstantServiceTransport], - Callable[..., KeywordThemeConstantServiceTransport], - ] = ( - KeywordThemeConstantServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., KeywordThemeConstantServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.KeywordThemeConstantServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.KeywordThemeConstantService", - "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.ads.googleads.v19.services.KeywordThemeConstantService", - "credentialsType": None, - } - ), - ) - - def suggest_keyword_theme_constants( - self, - request: Optional[ - Union[ - keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse: - r"""Returns KeywordThemeConstant suggestions by keyword themes. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.SuggestKeywordThemeConstantsRequest, dict]): - The request object. Request message for - [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v19.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestKeywordThemeConstantsResponse: - Response message for - [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v19.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest, - ): - request = keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.suggest_keyword_theme_constants - ] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "KeywordThemeConstantServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("KeywordThemeConstantServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/base.py b/google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/base.py deleted file mode 100644 index 4ac658c71..000000000 --- a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - keyword_theme_constant_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class KeywordThemeConstantServiceTransport(abc.ABC): - """Abstract transport class for KeywordThemeConstantService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.suggest_keyword_theme_constants: gapic_v1.method.wrap_method( - self.suggest_keyword_theme_constants, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def suggest_keyword_theme_constants( - self, - ) -> Callable[ - [keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest], - Union[ - keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse, - Awaitable[ - keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("KeywordThemeConstantServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/grpc.py b/google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/grpc.py deleted file mode 100644 index b369de593..000000000 --- a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/grpc.py +++ /dev/null @@ -1,390 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - keyword_theme_constant_service, -) -from .base import KeywordThemeConstantServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.KeywordThemeConstantService", - "rpcName": str(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.ads.googleads.v19.services.KeywordThemeConstantService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordThemeConstantServiceGrpcTransport( - KeywordThemeConstantServiceTransport -): - """gRPC backend transport for KeywordThemeConstantService. - - Service to fetch Smart Campaign keyword themes. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def suggest_keyword_theme_constants( - self, - ) -> Callable[ - [keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest], - keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse, - ]: - r"""Return a callable for the suggest keyword theme - constants method over gRPC. - - Returns KeywordThemeConstant suggestions by keyword themes. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.SuggestKeywordThemeConstantsRequest], - ~.SuggestKeywordThemeConstantsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_keyword_theme_constants" not in self._stubs: - self._stubs["suggest_keyword_theme_constants"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordThemeConstantService/SuggestKeywordThemeConstants", - request_serializer=keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest.serialize, - response_deserializer=keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse.deserialize, - ) - ) - return self._stubs["suggest_keyword_theme_constants"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("KeywordThemeConstantServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/grpc_asyncio.py deleted file mode 100644 index 6b053198a..000000000 --- a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,413 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - keyword_theme_constant_service, -) -from .base import KeywordThemeConstantServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.KeywordThemeConstantService", - "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.ads.googleads.v19.services.KeywordThemeConstantService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class KeywordThemeConstantServiceGrpcAsyncIOTransport( - KeywordThemeConstantServiceTransport -): - """gRPC AsyncIO backend transport for KeywordThemeConstantService. - - Service to fetch Smart Campaign keyword themes. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def suggest_keyword_theme_constants( - self, - ) -> Callable[ - [keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest], - Awaitable[ - keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse - ], - ]: - r"""Return a callable for the suggest keyword theme - constants method over gRPC. - - Returns KeywordThemeConstant suggestions by keyword themes. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.SuggestKeywordThemeConstantsRequest], - Awaitable[~.SuggestKeywordThemeConstantsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_keyword_theme_constants" not in self._stubs: - self._stubs["suggest_keyword_theme_constants"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.KeywordThemeConstantService/SuggestKeywordThemeConstants", - request_serializer=keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest.serialize, - response_deserializer=keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse.deserialize, - ) - ) - return self._stubs["suggest_keyword_theme_constants"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.suggest_keyword_theme_constants: self._wrap_method( - self.suggest_keyword_theme_constants, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("KeywordThemeConstantServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/label_service/async_client.py b/google/ads/googleads/v19/services/services/label_service/async_client.py deleted file mode 100644 index 7afd31a28..000000000 --- a/google/ads/googleads/v19/services/services/label_service/async_client.py +++ /dev/null @@ -1,411 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import label_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import LabelServiceTransport, DEFAULT_CLIENT_INFO -from .client import LabelServiceClient - -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 LabelServiceAsyncClient: - """Service to manage labels.""" - - _client: LabelServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = LabelServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = LabelServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = LabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE - _DEFAULT_UNIVERSE = LabelServiceClient._DEFAULT_UNIVERSE - - label_path = staticmethod(LabelServiceClient.label_path) - parse_label_path = staticmethod(LabelServiceClient.parse_label_path) - common_billing_account_path = staticmethod( - LabelServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - LabelServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(LabelServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - LabelServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - LabelServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - LabelServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod(LabelServiceClient.common_project_path) - parse_common_project_path = staticmethod( - LabelServiceClient.parse_common_project_path - ) - common_location_path = staticmethod(LabelServiceClient.common_location_path) - parse_common_location_path = staticmethod( - LabelServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - LabelServiceAsyncClient: The constructed client. - """ - return LabelServiceClient.from_service_account_info.__func__(LabelServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - LabelServiceAsyncClient: The constructed client. - """ - return LabelServiceClient.from_service_account_file.__func__(LabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return LabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> LabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - LabelServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = LabelServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, LabelServiceTransport, Callable[..., LabelServiceTransport] - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the label service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,LabelServiceTransport,Callable[..., LabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the LabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = LabelServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.LabelServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.LabelService", - "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.ads.googleads.v19.services.LabelService", - "credentialsType": None, - } - ), - ) - - async def mutate_labels( - self, - request: Optional[ - Union[label_service.MutateLabelsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[label_service.LabelOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> label_service.MutateLabelsResponse: - r"""Creates, updates, or removes labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `LabelError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateLabelsRequest, dict]]): - The request object. Request message for - [LabelService.MutateLabels][google.ads.googleads.v19.services.LabelService.MutateLabels]. - customer_id (:class:`str`): - Required. ID of the customer whose - labels are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.LabelOperation]`): - Required. The list of operations to - perform on labels. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateLabelsResponse: - Response message for a labels mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, label_service.MutateLabelsRequest): - request = label_service.MutateLabelsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_labels - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "LabelServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("LabelServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/label_service/client.py b/google/ads/googleads/v19/services/services/label_service/client.py deleted file mode 100644 index 5c8eaed8a..000000000 --- a/google/ads/googleads/v19/services/services/label_service/client.py +++ /dev/null @@ -1,864 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import label_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import LabelServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import LabelServiceGrpcTransport -from .transports.grpc_asyncio import LabelServiceGrpcAsyncIOTransport - - -class LabelServiceClientMeta(type): - """Metaclass for the LabelService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[LabelServiceTransport]] - _transport_registry["grpc"] = LabelServiceGrpcTransport - _transport_registry["grpc_asyncio"] = LabelServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[LabelServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class LabelServiceClient(metaclass=LabelServiceClientMeta): - """Service to manage labels.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - LabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - LabelServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> LabelServiceTransport: - """Returns the transport used by the client instance. - - Returns: - LabelServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def label_path( - customer_id: str, - label_id: str, - ) -> str: - """Returns a fully-qualified label string.""" - return "customers/{customer_id}/labels/{label_id}".format( - customer_id=customer_id, - label_id=label_id, - ) - - @staticmethod - def parse_label_path(path: str) -> Dict[str, str]: - """Parses a label path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/labels/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = LabelServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = LabelServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = LabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = LabelServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, LabelServiceTransport, Callable[..., LabelServiceTransport] - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the label service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,LabelServiceTransport,Callable[..., LabelServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the LabelServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = LabelServiceClient._read_environment_variables() - self._client_cert_source = LabelServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - self._universe_domain = LabelServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, LabelServiceTransport) - if transport_provided: - # transport is a LabelServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(LabelServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or LabelServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[LabelServiceTransport], - Callable[..., LabelServiceTransport], - ] = ( - LabelServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., LabelServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.LabelServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.LabelService", - "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.ads.googleads.v19.services.LabelService", - "credentialsType": None, - } - ), - ) - - def mutate_labels( - self, - request: Optional[ - Union[label_service.MutateLabelsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[label_service.LabelOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> label_service.MutateLabelsResponse: - r"""Creates, updates, or removes labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `LabelError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateLabelsRequest, dict]): - The request object. Request message for - [LabelService.MutateLabels][google.ads.googleads.v19.services.LabelService.MutateLabels]. - customer_id (str): - Required. ID of the customer whose - labels are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.LabelOperation]): - Required. The list of operations to - perform on labels. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateLabelsResponse: - Response message for a labels mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, label_service.MutateLabelsRequest): - request = label_service.MutateLabelsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.mutate_labels] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "LabelServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("LabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/label_service/transports/base.py b/google/ads/googleads/v19/services/services/label_service/transports/base.py deleted file mode 100644 index 4a5676452..000000000 --- a/google/ads/googleads/v19/services/services/label_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import label_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class LabelServiceTransport(abc.ABC): - """Abstract transport class for LabelService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_labels: gapic_v1.method.wrap_method( - self.mutate_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_labels( - self, - ) -> Callable[ - [label_service.MutateLabelsRequest], - Union[ - label_service.MutateLabelsResponse, - Awaitable[label_service.MutateLabelsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("LabelServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/label_service/transports/grpc.py b/google/ads/googleads/v19/services/services/label_service/transports/grpc.py deleted file mode 100644 index afab281f1..000000000 --- a/google/ads/googleads/v19/services/services/label_service/transports/grpc.py +++ /dev/null @@ -1,390 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import label_service -from .base import LabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.LabelService", - "rpcName": str(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.ads.googleads.v19.services.LabelService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class LabelServiceGrpcTransport(LabelServiceTransport): - """gRPC backend transport for LabelService. - - Service to manage labels. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_labels( - self, - ) -> Callable[ - [label_service.MutateLabelsRequest], label_service.MutateLabelsResponse - ]: - r"""Return a callable for the mutate labels method over gRPC. - - Creates, updates, or removes labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `LabelError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateLabelsRequest], - ~.MutateLabelsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_labels" not in self._stubs: - self._stubs["mutate_labels"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.LabelService/MutateLabels", - request_serializer=label_service.MutateLabelsRequest.serialize, - response_deserializer=label_service.MutateLabelsResponse.deserialize, - ) - return self._stubs["mutate_labels"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("LabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/label_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/label_service/transports/grpc_asyncio.py deleted file mode 100644 index b2bd36298..000000000 --- a/google/ads/googleads/v19/services/services/label_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,412 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import label_service -from .base import LabelServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.LabelService", - "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.ads.googleads.v19.services.LabelService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class LabelServiceGrpcAsyncIOTransport(LabelServiceTransport): - """gRPC AsyncIO backend transport for LabelService. - - Service to manage labels. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_labels( - self, - ) -> Callable[ - [label_service.MutateLabelsRequest], - Awaitable[label_service.MutateLabelsResponse], - ]: - r"""Return a callable for the mutate labels method over gRPC. - - Creates, updates, or removes labels. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `LabelError <>`__ `MutateError <>`__ - `NewResourceCreationError <>`__ `NotEmptyError <>`__ - `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ - `StringFormatError <>`__ `StringLengthError <>`__ - - Returns: - Callable[[~.MutateLabelsRequest], - Awaitable[~.MutateLabelsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_labels" not in self._stubs: - self._stubs["mutate_labels"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.LabelService/MutateLabels", - request_serializer=label_service.MutateLabelsRequest.serialize, - response_deserializer=label_service.MutateLabelsResponse.deserialize, - ) - return self._stubs["mutate_labels"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_labels: self._wrap_method( - self.mutate_labels, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("LabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/local_services_lead_service/async_client.py b/google/ads/googleads/v19/services/services/local_services_lead_service/async_client.py deleted file mode 100644 index 81c674843..000000000 --- a/google/ads/googleads/v19/services/services/local_services_lead_service/async_client.py +++ /dev/null @@ -1,496 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import local_services_lead_service -from .transports.base import ( - LocalServicesLeadServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import LocalServicesLeadServiceClient - -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 LocalServicesLeadServiceAsyncClient: - """This service allows management of LocalServicesLead - resources. - """ - - _client: LocalServicesLeadServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = LocalServicesLeadServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = LocalServicesLeadServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - LocalServicesLeadServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = LocalServicesLeadServiceClient._DEFAULT_UNIVERSE - - local_services_lead_path = staticmethod( - LocalServicesLeadServiceClient.local_services_lead_path - ) - parse_local_services_lead_path = staticmethod( - LocalServicesLeadServiceClient.parse_local_services_lead_path - ) - common_billing_account_path = staticmethod( - LocalServicesLeadServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - LocalServicesLeadServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - LocalServicesLeadServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - LocalServicesLeadServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - LocalServicesLeadServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - LocalServicesLeadServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - LocalServicesLeadServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - LocalServicesLeadServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - LocalServicesLeadServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - LocalServicesLeadServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - LocalServicesLeadServiceAsyncClient: The constructed client. - """ - return LocalServicesLeadServiceClient.from_service_account_info.__func__(LocalServicesLeadServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - LocalServicesLeadServiceAsyncClient: The constructed client. - """ - return LocalServicesLeadServiceClient.from_service_account_file.__func__(LocalServicesLeadServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return LocalServicesLeadServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> LocalServicesLeadServiceTransport: - """Returns the transport used by the client instance. - - Returns: - LocalServicesLeadServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = LocalServicesLeadServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - LocalServicesLeadServiceTransport, - Callable[..., LocalServicesLeadServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the local services lead service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,LocalServicesLeadServiceTransport,Callable[..., LocalServicesLeadServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the LocalServicesLeadServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = LocalServicesLeadServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.LocalServicesLeadServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.LocalServicesLeadService", - "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.ads.googleads.v19.services.LocalServicesLeadService", - "credentialsType": None, - } - ), - ) - - async def append_lead_conversation( - self, - request: Optional[ - Union[ - local_services_lead_service.AppendLeadConversationRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - conversations: Optional[ - MutableSequence[local_services_lead_service.Conversation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> local_services_lead_service.AppendLeadConversationResponse: - r"""RPC to append Local Services Lead Conversation - resources to Local Services Lead resources. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.AppendLeadConversationRequest, dict]]): - The request object. Request message for - [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v19.services.LocalServicesLeadService.AppendLeadConversation]. - customer_id (:class:`str`): - Required. The Id of the customer - which owns the leads onto which the - conversations will be appended. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - conversations (:class:`MutableSequence[google.ads.googleads.v19.services.types.Conversation]`): - Required. Conversations that are - being appended. - - This corresponds to the ``conversations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.AppendLeadConversationResponse: - Response message for - [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v19.services.LocalServicesLeadService.AppendLeadConversation]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, conversations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, local_services_lead_service.AppendLeadConversationRequest - ): - request = local_services_lead_service.AppendLeadConversationRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if conversations: - request.conversations.extend(conversations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.append_lead_conversation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def provide_lead_feedback( - self, - request: Optional[ - Union[local_services_lead_service.ProvideLeadFeedbackRequest, dict] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> local_services_lead_service.ProvideLeadFeedbackResponse: - r"""RPC to provide feedback on Local Services Lead - resources. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ProvideLeadFeedbackRequest, dict]]): - The request object. Request message for - [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v19.services.LocalServicesLeadService.ProvideLeadFeedback]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ProvideLeadFeedbackResponse: - Response message for - [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v19.services.LocalServicesLeadService.ProvideLeadFeedback]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, local_services_lead_service.ProvideLeadFeedbackRequest - ): - request = local_services_lead_service.ProvideLeadFeedbackRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.provide_lead_feedback - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "LocalServicesLeadServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("LocalServicesLeadServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/local_services_lead_service/client.py b/google/ads/googleads/v19/services/services/local_services_lead_service/client.py deleted file mode 100644 index 1a3cc69ca..000000000 --- a/google/ads/googleads/v19/services/services/local_services_lead_service/client.py +++ /dev/null @@ -1,954 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import local_services_lead_service -from .transports.base import ( - LocalServicesLeadServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import LocalServicesLeadServiceGrpcTransport -from .transports.grpc_asyncio import ( - LocalServicesLeadServiceGrpcAsyncIOTransport, -) - - -class LocalServicesLeadServiceClientMeta(type): - """Metaclass for the LocalServicesLeadService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[LocalServicesLeadServiceTransport]] - _transport_registry["grpc"] = LocalServicesLeadServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - LocalServicesLeadServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[LocalServicesLeadServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class LocalServicesLeadServiceClient( - metaclass=LocalServicesLeadServiceClientMeta -): - """This service allows management of LocalServicesLead - resources. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - LocalServicesLeadServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - LocalServicesLeadServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> LocalServicesLeadServiceTransport: - """Returns the transport used by the client instance. - - Returns: - LocalServicesLeadServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def local_services_lead_path( - customer_id: str, - local_services_lead_id: str, - ) -> str: - """Returns a fully-qualified local_services_lead string.""" - return "customers/{customer_id}/localServicesLeads/{local_services_lead_id}".format( - customer_id=customer_id, - local_services_lead_id=local_services_lead_id, - ) - - @staticmethod - def parse_local_services_lead_path(path: str) -> Dict[str, str]: - """Parses a local_services_lead path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/localServicesLeads/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = LocalServicesLeadServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = LocalServicesLeadServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = LocalServicesLeadServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = LocalServicesLeadServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - LocalServicesLeadServiceTransport, - Callable[..., LocalServicesLeadServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the local services lead service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,LocalServicesLeadServiceTransport,Callable[..., LocalServicesLeadServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the LocalServicesLeadServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = LocalServicesLeadServiceClient._read_environment_variables() - self._client_cert_source = ( - LocalServicesLeadServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - LocalServicesLeadServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, LocalServicesLeadServiceTransport - ) - if transport_provided: - # transport is a LocalServicesLeadServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(LocalServicesLeadServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or LocalServicesLeadServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[LocalServicesLeadServiceTransport], - Callable[..., LocalServicesLeadServiceTransport], - ] = ( - LocalServicesLeadServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., LocalServicesLeadServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.LocalServicesLeadServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.LocalServicesLeadService", - "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.ads.googleads.v19.services.LocalServicesLeadService", - "credentialsType": None, - } - ), - ) - - def append_lead_conversation( - self, - request: Optional[ - Union[ - local_services_lead_service.AppendLeadConversationRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - conversations: Optional[ - MutableSequence[local_services_lead_service.Conversation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> local_services_lead_service.AppendLeadConversationResponse: - r"""RPC to append Local Services Lead Conversation - resources to Local Services Lead resources. - - Args: - request (Union[google.ads.googleads.v19.services.types.AppendLeadConversationRequest, dict]): - The request object. Request message for - [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v19.services.LocalServicesLeadService.AppendLeadConversation]. - customer_id (str): - Required. The Id of the customer - which owns the leads onto which the - conversations will be appended. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - conversations (MutableSequence[google.ads.googleads.v19.services.types.Conversation]): - Required. Conversations that are - being appended. - - This corresponds to the ``conversations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.AppendLeadConversationResponse: - Response message for - [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v19.services.LocalServicesLeadService.AppendLeadConversation]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, conversations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, local_services_lead_service.AppendLeadConversationRequest - ): - request = local_services_lead_service.AppendLeadConversationRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if conversations is not None: - request.conversations = conversations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.append_lead_conversation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def provide_lead_feedback( - self, - request: Optional[ - Union[local_services_lead_service.ProvideLeadFeedbackRequest, dict] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> local_services_lead_service.ProvideLeadFeedbackResponse: - r"""RPC to provide feedback on Local Services Lead - resources. - - Args: - request (Union[google.ads.googleads.v19.services.types.ProvideLeadFeedbackRequest, dict]): - The request object. Request message for - [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v19.services.LocalServicesLeadService.ProvideLeadFeedback]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ProvideLeadFeedbackResponse: - Response message for - [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v19.services.LocalServicesLeadService.ProvideLeadFeedback]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, local_services_lead_service.ProvideLeadFeedbackRequest - ): - request = local_services_lead_service.ProvideLeadFeedbackRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.provide_lead_feedback - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "LocalServicesLeadServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("LocalServicesLeadServiceClient",) diff --git a/google/ads/googleads/v19/services/services/local_services_lead_service/transports/base.py b/google/ads/googleads/v19/services/services/local_services_lead_service/transports/base.py deleted file mode 100644 index a5b0583ae..000000000 --- a/google/ads/googleads/v19/services/services/local_services_lead_service/transports/base.py +++ /dev/null @@ -1,191 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import local_services_lead_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class LocalServicesLeadServiceTransport(abc.ABC): - """Abstract transport class for LocalServicesLeadService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.append_lead_conversation: gapic_v1.method.wrap_method( - self.append_lead_conversation, - default_timeout=None, - client_info=client_info, - ), - self.provide_lead_feedback: gapic_v1.method.wrap_method( - self.provide_lead_feedback, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def append_lead_conversation( - self, - ) -> Callable[ - [local_services_lead_service.AppendLeadConversationRequest], - Union[ - local_services_lead_service.AppendLeadConversationResponse, - Awaitable[ - local_services_lead_service.AppendLeadConversationResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def provide_lead_feedback( - self, - ) -> Callable[ - [local_services_lead_service.ProvideLeadFeedbackRequest], - Union[ - local_services_lead_service.ProvideLeadFeedbackResponse, - Awaitable[local_services_lead_service.ProvideLeadFeedbackResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("LocalServicesLeadServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/local_services_lead_service/transports/grpc.py b/google/ads/googleads/v19/services/services/local_services_lead_service/transports/grpc.py deleted file mode 100644 index c00a32a1b..000000000 --- a/google/ads/googleads/v19/services/services/local_services_lead_service/transports/grpc.py +++ /dev/null @@ -1,415 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import local_services_lead_service -from .base import LocalServicesLeadServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.LocalServicesLeadService", - "rpcName": str(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.ads.googleads.v19.services.LocalServicesLeadService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class LocalServicesLeadServiceGrpcTransport(LocalServicesLeadServiceTransport): - """gRPC backend transport for LocalServicesLeadService. - - This service allows management of LocalServicesLead - resources. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def append_lead_conversation( - self, - ) -> Callable[ - [local_services_lead_service.AppendLeadConversationRequest], - local_services_lead_service.AppendLeadConversationResponse, - ]: - r"""Return a callable for the append lead conversation method over gRPC. - - RPC to append Local Services Lead Conversation - resources to Local Services Lead resources. - - Returns: - Callable[[~.AppendLeadConversationRequest], - ~.AppendLeadConversationResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "append_lead_conversation" not in self._stubs: - self._stubs["append_lead_conversation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.LocalServicesLeadService/AppendLeadConversation", - request_serializer=local_services_lead_service.AppendLeadConversationRequest.serialize, - response_deserializer=local_services_lead_service.AppendLeadConversationResponse.deserialize, - ) - ) - return self._stubs["append_lead_conversation"] - - @property - def provide_lead_feedback( - self, - ) -> Callable[ - [local_services_lead_service.ProvideLeadFeedbackRequest], - local_services_lead_service.ProvideLeadFeedbackResponse, - ]: - r"""Return a callable for the provide lead feedback method over gRPC. - - RPC to provide feedback on Local Services Lead - resources. - - Returns: - Callable[[~.ProvideLeadFeedbackRequest], - ~.ProvideLeadFeedbackResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "provide_lead_feedback" not in self._stubs: - self._stubs["provide_lead_feedback"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.LocalServicesLeadService/ProvideLeadFeedback", - request_serializer=local_services_lead_service.ProvideLeadFeedbackRequest.serialize, - response_deserializer=local_services_lead_service.ProvideLeadFeedbackResponse.deserialize, - ) - ) - return self._stubs["provide_lead_feedback"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("LocalServicesLeadServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/local_services_lead_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/local_services_lead_service/transports/grpc_asyncio.py deleted file mode 100644 index 8eab4297d..000000000 --- a/google/ads/googleads/v19/services/services/local_services_lead_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,443 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import local_services_lead_service -from .base import LocalServicesLeadServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.LocalServicesLeadService", - "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.ads.googleads.v19.services.LocalServicesLeadService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class LocalServicesLeadServiceGrpcAsyncIOTransport( - LocalServicesLeadServiceTransport -): - """gRPC AsyncIO backend transport for LocalServicesLeadService. - - This service allows management of LocalServicesLead - resources. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def append_lead_conversation( - self, - ) -> Callable[ - [local_services_lead_service.AppendLeadConversationRequest], - Awaitable[local_services_lead_service.AppendLeadConversationResponse], - ]: - r"""Return a callable for the append lead conversation method over gRPC. - - RPC to append Local Services Lead Conversation - resources to Local Services Lead resources. - - Returns: - Callable[[~.AppendLeadConversationRequest], - Awaitable[~.AppendLeadConversationResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "append_lead_conversation" not in self._stubs: - self._stubs["append_lead_conversation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.LocalServicesLeadService/AppendLeadConversation", - request_serializer=local_services_lead_service.AppendLeadConversationRequest.serialize, - response_deserializer=local_services_lead_service.AppendLeadConversationResponse.deserialize, - ) - ) - return self._stubs["append_lead_conversation"] - - @property - def provide_lead_feedback( - self, - ) -> Callable[ - [local_services_lead_service.ProvideLeadFeedbackRequest], - Awaitable[local_services_lead_service.ProvideLeadFeedbackResponse], - ]: - r"""Return a callable for the provide lead feedback method over gRPC. - - RPC to provide feedback on Local Services Lead - resources. - - Returns: - Callable[[~.ProvideLeadFeedbackRequest], - Awaitable[~.ProvideLeadFeedbackResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "provide_lead_feedback" not in self._stubs: - self._stubs["provide_lead_feedback"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.LocalServicesLeadService/ProvideLeadFeedback", - request_serializer=local_services_lead_service.ProvideLeadFeedbackRequest.serialize, - response_deserializer=local_services_lead_service.ProvideLeadFeedbackResponse.deserialize, - ) - ) - return self._stubs["provide_lead_feedback"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.append_lead_conversation: self._wrap_method( - self.append_lead_conversation, - default_timeout=None, - client_info=client_info, - ), - self.provide_lead_feedback: self._wrap_method( - self.provide_lead_feedback, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("LocalServicesLeadServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/offline_user_data_job_service/async_client.py b/google/ads/googleads/v19/services/services/offline_user_data_job_service/async_client.py deleted file mode 100644 index f92567a89..000000000 --- a/google/ads/googleads/v19/services/services/offline_user_data_job_service/async_client.py +++ /dev/null @@ -1,682 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.resources.types import offline_user_data_job -from google.ads.googleads.v19.services.types import ( - offline_user_data_job_service, -) -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - OfflineUserDataJobServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import OfflineUserDataJobServiceClient - -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 OfflineUserDataJobServiceAsyncClient: - """Service to manage offline user data jobs.""" - - _client: OfflineUserDataJobServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = OfflineUserDataJobServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - OfflineUserDataJobServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - OfflineUserDataJobServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = OfflineUserDataJobServiceClient._DEFAULT_UNIVERSE - - offline_user_data_job_path = staticmethod( - OfflineUserDataJobServiceClient.offline_user_data_job_path - ) - parse_offline_user_data_job_path = staticmethod( - OfflineUserDataJobServiceClient.parse_offline_user_data_job_path - ) - common_billing_account_path = staticmethod( - OfflineUserDataJobServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - OfflineUserDataJobServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - OfflineUserDataJobServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - OfflineUserDataJobServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - OfflineUserDataJobServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - OfflineUserDataJobServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - OfflineUserDataJobServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - OfflineUserDataJobServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - OfflineUserDataJobServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - OfflineUserDataJobServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - OfflineUserDataJobServiceAsyncClient: The constructed client. - """ - return OfflineUserDataJobServiceClient.from_service_account_info.__func__(OfflineUserDataJobServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - OfflineUserDataJobServiceAsyncClient: The constructed client. - """ - return OfflineUserDataJobServiceClient.from_service_account_file.__func__(OfflineUserDataJobServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return OfflineUserDataJobServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> OfflineUserDataJobServiceTransport: - """Returns the transport used by the client instance. - - Returns: - OfflineUserDataJobServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = OfflineUserDataJobServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - OfflineUserDataJobServiceTransport, - Callable[..., OfflineUserDataJobServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the offline user data job service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,OfflineUserDataJobServiceTransport,Callable[..., OfflineUserDataJobServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the OfflineUserDataJobServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = OfflineUserDataJobServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.OfflineUserDataJobServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.OfflineUserDataJobService", - "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.ads.googleads.v19.services.OfflineUserDataJobService", - "credentialsType": None, - } - ), - ) - - async def create_offline_user_data_job( - self, - request: Optional[ - Union[ - offline_user_data_job_service.CreateOfflineUserDataJobRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - job: Optional[offline_user_data_job.OfflineUserDataJob] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> offline_user_data_job_service.CreateOfflineUserDataJobResponse: - r"""Creates an offline user data job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `NotAllowlistedError <>`__ `OfflineUserDataJobError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.CreateOfflineUserDataJobRequest, dict]]): - The request object. Request message for - [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v19.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. - customer_id (:class:`str`): - Required. The ID of the customer for - which to create an offline user data - job. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - job (:class:`google.ads.googleads.v19.resources.types.OfflineUserDataJob`): - Required. The offline user data job - to be created. - - This corresponds to the ``job`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateOfflineUserDataJobResponse: - Response message for - [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v19.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, job] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - offline_user_data_job_service.CreateOfflineUserDataJobRequest, - ): - request = ( - offline_user_data_job_service.CreateOfflineUserDataJobRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if job is not None: - request.job = job - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.create_offline_user_data_job - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def add_offline_user_data_job_operations( - self, - request: Optional[ - Union[ - offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest, - dict, - ] - ] = None, - *, - resource_name: Optional[str] = None, - operations: Optional[ - MutableSequence[ - offline_user_data_job_service.OfflineUserDataJobOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse: - r"""Adds operations to the offline user data job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `OfflineUserDataJobError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.AddOfflineUserDataJobOperationsRequest, dict]]): - The request object. Request message for - [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v19.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. - resource_name (:class:`str`): - Required. The resource name of the - OfflineUserDataJob. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.OfflineUserDataJobOperation]`): - Required. The list of operations to - be done. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.AddOfflineUserDataJobOperationsResponse: - Response message for - [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v19.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest, - ): - request = offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.add_offline_user_data_job_operations - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def run_offline_user_data_job( - self, - request: Optional[ - Union[ - offline_user_data_job_service.RunOfflineUserDataJobRequest, dict - ] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operation_async.AsyncOperation: - r"""Runs the offline user data job. - - When finished, the long running operation will contain the - processing result or failure information, if any. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `OfflineUserDataJobError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.RunOfflineUserDataJobRequest, dict]]): - The request object. Request message for - [OfflineUserDataJobService.RunOfflineUserDataJob][google.ads.googleads.v19.services.OfflineUserDataJobService.RunOfflineUserDataJob]. - resource_name (:class:`str`): - Required. The resource name of the - OfflineUserDataJob to run. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, offline_user_data_job_service.RunOfflineUserDataJobRequest - ): - request = ( - offline_user_data_job_service.RunOfflineUserDataJobRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.run_offline_user_data_job - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation_async.from_gapic( - response, - self._client._transport.operations_client, - empty_pb2.Empty, - metadata_type=offline_user_data_job.OfflineUserDataJobMetadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "OfflineUserDataJobServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("OfflineUserDataJobServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/offline_user_data_job_service/client.py b/google/ads/googleads/v19/services/services/offline_user_data_job_service/client.py deleted file mode 100644 index 972176407..000000000 --- a/google/ads/googleads/v19/services/services/offline_user_data_job_service/client.py +++ /dev/null @@ -1,1140 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.resources.types import offline_user_data_job -from google.ads.googleads.v19.services.types import ( - offline_user_data_job_service, -) -from google.api_core import operation # type: ignore -from google.api_core import operation_async # type: ignore -from google.protobuf import empty_pb2 # type: ignore -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - OfflineUserDataJobServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import OfflineUserDataJobServiceGrpcTransport -from .transports.grpc_asyncio import ( - OfflineUserDataJobServiceGrpcAsyncIOTransport, -) - - -class OfflineUserDataJobServiceClientMeta(type): - """Metaclass for the OfflineUserDataJobService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[OfflineUserDataJobServiceTransport]] - _transport_registry["grpc"] = OfflineUserDataJobServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - OfflineUserDataJobServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[OfflineUserDataJobServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class OfflineUserDataJobServiceClient( - metaclass=OfflineUserDataJobServiceClientMeta -): - """Service to manage offline user data jobs.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - OfflineUserDataJobServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - OfflineUserDataJobServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> OfflineUserDataJobServiceTransport: - """Returns the transport used by the client instance. - - Returns: - OfflineUserDataJobServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def offline_user_data_job_path( - customer_id: str, - offline_user_data_update_id: str, - ) -> str: - """Returns a fully-qualified offline_user_data_job string.""" - return "customers/{customer_id}/offlineUserDataJobs/{offline_user_data_update_id}".format( - customer_id=customer_id, - offline_user_data_update_id=offline_user_data_update_id, - ) - - @staticmethod - def parse_offline_user_data_job_path(path: str) -> Dict[str, str]: - """Parses a offline_user_data_job path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/offlineUserDataJobs/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - OfflineUserDataJobServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = OfflineUserDataJobServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = OfflineUserDataJobServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = OfflineUserDataJobServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - OfflineUserDataJobServiceTransport, - Callable[..., OfflineUserDataJobServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the offline user data job service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,OfflineUserDataJobServiceTransport,Callable[..., OfflineUserDataJobServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the OfflineUserDataJobServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = OfflineUserDataJobServiceClient._read_environment_variables() - self._client_cert_source = ( - OfflineUserDataJobServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - OfflineUserDataJobServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, OfflineUserDataJobServiceTransport - ) - if transport_provided: - # transport is a OfflineUserDataJobServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - OfflineUserDataJobServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or OfflineUserDataJobServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[OfflineUserDataJobServiceTransport], - Callable[..., OfflineUserDataJobServiceTransport], - ] = ( - OfflineUserDataJobServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., OfflineUserDataJobServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.OfflineUserDataJobServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.OfflineUserDataJobService", - "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.ads.googleads.v19.services.OfflineUserDataJobService", - "credentialsType": None, - } - ), - ) - - def create_offline_user_data_job( - self, - request: Optional[ - Union[ - offline_user_data_job_service.CreateOfflineUserDataJobRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - job: Optional[offline_user_data_job.OfflineUserDataJob] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> offline_user_data_job_service.CreateOfflineUserDataJobResponse: - r"""Creates an offline user data job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `NotAllowlistedError <>`__ `OfflineUserDataJobError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.CreateOfflineUserDataJobRequest, dict]): - The request object. Request message for - [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v19.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. - customer_id (str): - Required. The ID of the customer for - which to create an offline user data - job. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - job (google.ads.googleads.v19.resources.types.OfflineUserDataJob): - Required. The offline user data job - to be created. - - This corresponds to the ``job`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateOfflineUserDataJobResponse: - Response message for - [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v19.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, job] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - offline_user_data_job_service.CreateOfflineUserDataJobRequest, - ): - request = ( - offline_user_data_job_service.CreateOfflineUserDataJobRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if job is not None: - request.job = job - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.create_offline_user_data_job - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def add_offline_user_data_job_operations( - self, - request: Optional[ - Union[ - offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest, - dict, - ] - ] = None, - *, - resource_name: Optional[str] = None, - operations: Optional[ - MutableSequence[ - offline_user_data_job_service.OfflineUserDataJobOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse: - r"""Adds operations to the offline user data job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `OfflineUserDataJobError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.AddOfflineUserDataJobOperationsRequest, dict]): - The request object. Request message for - [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v19.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. - resource_name (str): - Required. The resource name of the - OfflineUserDataJob. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.OfflineUserDataJobOperation]): - Required. The list of operations to - be done. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.AddOfflineUserDataJobOperationsResponse: - Response message for - [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v19.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest, - ): - request = offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.add_offline_user_data_job_operations - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def run_offline_user_data_job( - self, - request: Optional[ - Union[ - offline_user_data_job_service.RunOfflineUserDataJobRequest, dict - ] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> operation.Operation: - r"""Runs the offline user data job. - - When finished, the long running operation will contain the - processing result or failure information, if any. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `OfflineUserDataJobError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.RunOfflineUserDataJobRequest, dict]): - The request object. Request message for - [OfflineUserDataJobService.RunOfflineUserDataJob][google.ads.googleads.v19.services.OfflineUserDataJobService.RunOfflineUserDataJob]. - resource_name (str): - Required. The resource name of the - OfflineUserDataJob to run. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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: - An object representing a long-running operation. - - The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated - empty messages in your APIs. A typical example is to - use it as the request or the response type of an API - method. For instance: - - service Foo { - rpc Bar(google.protobuf.Empty) returns - (google.protobuf.Empty); - - } - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, offline_user_data_job_service.RunOfflineUserDataJobRequest - ): - request = ( - offline_user_data_job_service.RunOfflineUserDataJobRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.run_offline_user_data_job - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Wrap the response in an operation future. - response = operation.from_gapic( - response, - self._transport.operations_client, - empty_pb2.Empty, - metadata_type=offline_user_data_job.OfflineUserDataJobMetadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "OfflineUserDataJobServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("OfflineUserDataJobServiceClient",) diff --git a/google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/base.py b/google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/base.py deleted file mode 100644 index f95cf87cd..000000000 --- a/google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/base.py +++ /dev/null @@ -1,215 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - offline_user_data_job_service, -) -from google.longrunning import operations_pb2 # type: ignore - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class OfflineUserDataJobServiceTransport(abc.ABC): - """Abstract transport class for OfflineUserDataJobService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.create_offline_user_data_job: gapic_v1.method.wrap_method( - self.create_offline_user_data_job, - default_timeout=None, - client_info=client_info, - ), - self.add_offline_user_data_job_operations: gapic_v1.method.wrap_method( - self.add_offline_user_data_job_operations, - default_timeout=None, - client_info=client_info, - ), - self.run_offline_user_data_job: gapic_v1.method.wrap_method( - self.run_offline_user_data_job, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def operations_client(self): - """Return the client designed to process long-running operations.""" - raise NotImplementedError() - - @property - def create_offline_user_data_job( - self, - ) -> Callable[ - [offline_user_data_job_service.CreateOfflineUserDataJobRequest], - Union[ - offline_user_data_job_service.CreateOfflineUserDataJobResponse, - Awaitable[ - offline_user_data_job_service.CreateOfflineUserDataJobResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def add_offline_user_data_job_operations( - self, - ) -> Callable[ - [offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest], - Union[ - offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse, - Awaitable[ - offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def run_offline_user_data_job( - self, - ) -> Callable[ - [offline_user_data_job_service.RunOfflineUserDataJobRequest], - Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("OfflineUserDataJobServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/grpc.py b/google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/grpc.py deleted file mode 100644 index 89f050b1b..000000000 --- a/google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/grpc.py +++ /dev/null @@ -1,488 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import operations_v1 -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - offline_user_data_job_service, -) -from google.longrunning import operations_pb2 # type: ignore -from .base import OfflineUserDataJobServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.OfflineUserDataJobService", - "rpcName": str(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.ads.googleads.v19.services.OfflineUserDataJobService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class OfflineUserDataJobServiceGrpcTransport( - OfflineUserDataJobServiceTransport -): - """gRPC backend transport for OfflineUserDataJobService. - - Service to manage offline user data jobs. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[operations_v1.OperationsClient] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # 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._logged_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def create_offline_user_data_job( - self, - ) -> Callable[ - [offline_user_data_job_service.CreateOfflineUserDataJobRequest], - offline_user_data_job_service.CreateOfflineUserDataJobResponse, - ]: - r"""Return a callable for the create offline user data job method over gRPC. - - Creates an offline user data job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `NotAllowlistedError <>`__ `OfflineUserDataJobError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.CreateOfflineUserDataJobRequest], - ~.CreateOfflineUserDataJobResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_offline_user_data_job" not in self._stubs: - self._stubs["create_offline_user_data_job"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.OfflineUserDataJobService/CreateOfflineUserDataJob", - request_serializer=offline_user_data_job_service.CreateOfflineUserDataJobRequest.serialize, - response_deserializer=offline_user_data_job_service.CreateOfflineUserDataJobResponse.deserialize, - ) - ) - return self._stubs["create_offline_user_data_job"] - - @property - def add_offline_user_data_job_operations( - self, - ) -> Callable[ - [offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest], - offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse, - ]: - r"""Return a callable for the add offline user data job - operations method over gRPC. - - Adds operations to the offline user data job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `OfflineUserDataJobError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.AddOfflineUserDataJobOperationsRequest], - ~.AddOfflineUserDataJobOperationsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "add_offline_user_data_job_operations" not in self._stubs: - self._stubs["add_offline_user_data_job_operations"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.OfflineUserDataJobService/AddOfflineUserDataJobOperations", - request_serializer=offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest.serialize, - response_deserializer=offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse.deserialize, - ) - ) - return self._stubs["add_offline_user_data_job_operations"] - - @property - def run_offline_user_data_job( - self, - ) -> Callable[ - [offline_user_data_job_service.RunOfflineUserDataJobRequest], - operations_pb2.Operation, - ]: - r"""Return a callable for the run offline user data job method over gRPC. - - Runs the offline user data job. - - When finished, the long running operation will contain the - processing result or failure information, if any. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `OfflineUserDataJobError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.RunOfflineUserDataJobRequest], - ~.Operation]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "run_offline_user_data_job" not in self._stubs: - self._stubs["run_offline_user_data_job"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.OfflineUserDataJobService/RunOfflineUserDataJob", - request_serializer=offline_user_data_job_service.RunOfflineUserDataJobRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - ) - return self._stubs["run_offline_user_data_job"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("OfflineUserDataJobServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/grpc_asyncio.py deleted file mode 100644 index 212cd650a..000000000 --- a/google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,525 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.api_core import operations_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - offline_user_data_job_service, -) -from google.longrunning import operations_pb2 # type: ignore -from .base import OfflineUserDataJobServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.OfflineUserDataJobService", - "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.ads.googleads.v19.services.OfflineUserDataJobService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class OfflineUserDataJobServiceGrpcAsyncIOTransport( - OfflineUserDataJobServiceTransport -): - """gRPC AsyncIO backend transport for OfflineUserDataJobService. - - Service to manage offline user data jobs. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - self._operations_client: Optional[ - operations_v1.OperationsAsyncClient - ] = None - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def operations_client(self) -> operations_v1.OperationsAsyncClient: - """Create the client designed to process long-running operations. - - This property caches on the instance; repeated calls return the same - client. - """ - # 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._logged_channel - ) - - # Return the client from cache. - return self._operations_client - - @property - def create_offline_user_data_job( - self, - ) -> Callable[ - [offline_user_data_job_service.CreateOfflineUserDataJobRequest], - Awaitable[ - offline_user_data_job_service.CreateOfflineUserDataJobResponse - ], - ]: - r"""Return a callable for the create offline user data job method over gRPC. - - Creates an offline user data job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `NotAllowlistedError <>`__ `OfflineUserDataJobError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.CreateOfflineUserDataJobRequest], - Awaitable[~.CreateOfflineUserDataJobResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_offline_user_data_job" not in self._stubs: - self._stubs["create_offline_user_data_job"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.OfflineUserDataJobService/CreateOfflineUserDataJob", - request_serializer=offline_user_data_job_service.CreateOfflineUserDataJobRequest.serialize, - response_deserializer=offline_user_data_job_service.CreateOfflineUserDataJobResponse.deserialize, - ) - ) - return self._stubs["create_offline_user_data_job"] - - @property - def add_offline_user_data_job_operations( - self, - ) -> Callable[ - [offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest], - Awaitable[ - offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse - ], - ]: - r"""Return a callable for the add offline user data job - operations method over gRPC. - - Adds operations to the offline user data job. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `OfflineUserDataJobError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.AddOfflineUserDataJobOperationsRequest], - Awaitable[~.AddOfflineUserDataJobOperationsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "add_offline_user_data_job_operations" not in self._stubs: - self._stubs["add_offline_user_data_job_operations"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.OfflineUserDataJobService/AddOfflineUserDataJobOperations", - request_serializer=offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest.serialize, - response_deserializer=offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse.deserialize, - ) - ) - return self._stubs["add_offline_user_data_job_operations"] - - @property - def run_offline_user_data_job( - self, - ) -> Callable[ - [offline_user_data_job_service.RunOfflineUserDataJobRequest], - Awaitable[operations_pb2.Operation], - ]: - r"""Return a callable for the run offline user data job method over gRPC. - - Runs the offline user data job. - - When finished, the long running operation will contain the - processing result or failure information, if any. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ - `HeaderError <>`__ `InternalError <>`__ - `OfflineUserDataJobError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.RunOfflineUserDataJobRequest], - Awaitable[~.Operation]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "run_offline_user_data_job" not in self._stubs: - self._stubs["run_offline_user_data_job"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.OfflineUserDataJobService/RunOfflineUserDataJob", - request_serializer=offline_user_data_job_service.RunOfflineUserDataJobRequest.serialize, - response_deserializer=operations_pb2.Operation.FromString, - ) - ) - return self._stubs["run_offline_user_data_job"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.create_offline_user_data_job: self._wrap_method( - self.create_offline_user_data_job, - default_timeout=None, - client_info=client_info, - ), - self.add_offline_user_data_job_operations: self._wrap_method( - self.add_offline_user_data_job_operations, - default_timeout=None, - client_info=client_info, - ), - self.run_offline_user_data_job: self._wrap_method( - self.run_offline_user_data_job, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("OfflineUserDataJobServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/payments_account_service/async_client.py b/google/ads/googleads/v19/services/services/payments_account_service/async_client.py deleted file mode 100644 index 9eadcdece..000000000 --- a/google/ads/googleads/v19/services/services/payments_account_service/async_client.py +++ /dev/null @@ -1,423 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import payments_account_service -from .transports.base import ( - PaymentsAccountServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import PaymentsAccountServiceClient - -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 PaymentsAccountServiceAsyncClient: - """Service to provide payments accounts that can be used to set - up consolidated billing. - """ - - _client: PaymentsAccountServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = PaymentsAccountServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = PaymentsAccountServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - PaymentsAccountServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = PaymentsAccountServiceClient._DEFAULT_UNIVERSE - - customer_path = staticmethod(PaymentsAccountServiceClient.customer_path) - parse_customer_path = staticmethod( - PaymentsAccountServiceClient.parse_customer_path - ) - payments_account_path = staticmethod( - PaymentsAccountServiceClient.payments_account_path - ) - parse_payments_account_path = staticmethod( - PaymentsAccountServiceClient.parse_payments_account_path - ) - common_billing_account_path = staticmethod( - PaymentsAccountServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - PaymentsAccountServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - PaymentsAccountServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - PaymentsAccountServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - PaymentsAccountServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - PaymentsAccountServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - PaymentsAccountServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - PaymentsAccountServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - PaymentsAccountServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - PaymentsAccountServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - PaymentsAccountServiceAsyncClient: The constructed client. - """ - return PaymentsAccountServiceClient.from_service_account_info.__func__(PaymentsAccountServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - PaymentsAccountServiceAsyncClient: The constructed client. - """ - return PaymentsAccountServiceClient.from_service_account_file.__func__(PaymentsAccountServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return PaymentsAccountServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> PaymentsAccountServiceTransport: - """Returns the transport used by the client instance. - - Returns: - PaymentsAccountServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = PaymentsAccountServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - PaymentsAccountServiceTransport, - Callable[..., PaymentsAccountServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the payments account service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,PaymentsAccountServiceTransport,Callable[..., PaymentsAccountServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the PaymentsAccountServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = PaymentsAccountServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.PaymentsAccountServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.PaymentsAccountService", - "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.ads.googleads.v19.services.PaymentsAccountService", - "credentialsType": None, - } - ), - ) - - async def list_payments_accounts( - self, - request: Optional[ - Union[payments_account_service.ListPaymentsAccountsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> payments_account_service.ListPaymentsAccountsResponse: - r"""Returns all payments accounts associated with all managers - between the login customer ID and specified serving customer in - the hierarchy, inclusive. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PaymentsAccountError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ListPaymentsAccountsRequest, dict]]): - The request object. Request message for fetching all - accessible payments accounts. - customer_id (:class:`str`): - Required. The ID of the customer to - apply the PaymentsAccount list operation - to. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListPaymentsAccountsResponse: - Response message for - [PaymentsAccountService.ListPaymentsAccounts][google.ads.googleads.v19.services.PaymentsAccountService.ListPaymentsAccounts]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, payments_account_service.ListPaymentsAccountsRequest - ): - request = payments_account_service.ListPaymentsAccountsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_payments_accounts - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "PaymentsAccountServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("PaymentsAccountServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/payments_account_service/client.py b/google/ads/googleads/v19/services/services/payments_account_service/client.py deleted file mode 100644 index 2bec37f45..000000000 --- a/google/ads/googleads/v19/services/services/payments_account_service/client.py +++ /dev/null @@ -1,880 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import payments_account_service -from .transports.base import ( - PaymentsAccountServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import PaymentsAccountServiceGrpcTransport -from .transports.grpc_asyncio import PaymentsAccountServiceGrpcAsyncIOTransport - - -class PaymentsAccountServiceClientMeta(type): - """Metaclass for the PaymentsAccountService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[PaymentsAccountServiceTransport]] - _transport_registry["grpc"] = PaymentsAccountServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - PaymentsAccountServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[PaymentsAccountServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class PaymentsAccountServiceClient(metaclass=PaymentsAccountServiceClientMeta): - """Service to provide payments accounts that can be used to set - up consolidated billing. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - PaymentsAccountServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - PaymentsAccountServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> PaymentsAccountServiceTransport: - """Returns the transport used by the client instance. - - Returns: - PaymentsAccountServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def payments_account_path( - customer_id: str, - payments_account_id: str, - ) -> str: - """Returns a fully-qualified payments_account string.""" - return "customers/{customer_id}/paymentsAccounts/{payments_account_id}".format( - customer_id=customer_id, - payments_account_id=payments_account_id, - ) - - @staticmethod - def parse_payments_account_path(path: str) -> Dict[str, str]: - """Parses a payments_account path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/paymentsAccounts/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = PaymentsAccountServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = PaymentsAccountServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - PaymentsAccountServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = PaymentsAccountServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - PaymentsAccountServiceTransport, - Callable[..., PaymentsAccountServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the payments account service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,PaymentsAccountServiceTransport,Callable[..., PaymentsAccountServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the PaymentsAccountServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = PaymentsAccountServiceClient._read_environment_variables() - self._client_cert_source = ( - PaymentsAccountServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - PaymentsAccountServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, PaymentsAccountServiceTransport - ) - if transport_provided: - # transport is a PaymentsAccountServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(PaymentsAccountServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or PaymentsAccountServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[PaymentsAccountServiceTransport], - Callable[..., PaymentsAccountServiceTransport], - ] = ( - PaymentsAccountServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., PaymentsAccountServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.PaymentsAccountServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.PaymentsAccountService", - "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.ads.googleads.v19.services.PaymentsAccountService", - "credentialsType": None, - } - ), - ) - - def list_payments_accounts( - self, - request: Optional[ - Union[payments_account_service.ListPaymentsAccountsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> payments_account_service.ListPaymentsAccountsResponse: - r"""Returns all payments accounts associated with all managers - between the login customer ID and specified serving customer in - the hierarchy, inclusive. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PaymentsAccountError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ListPaymentsAccountsRequest, dict]): - The request object. Request message for fetching all - accessible payments accounts. - customer_id (str): - Required. The ID of the customer to - apply the PaymentsAccount list operation - to. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListPaymentsAccountsResponse: - Response message for - [PaymentsAccountService.ListPaymentsAccounts][google.ads.googleads.v19.services.PaymentsAccountService.ListPaymentsAccounts]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, payments_account_service.ListPaymentsAccountsRequest - ): - request = payments_account_service.ListPaymentsAccountsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.list_payments_accounts - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "PaymentsAccountServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("PaymentsAccountServiceClient",) diff --git a/google/ads/googleads/v19/services/services/payments_account_service/transports/base.py b/google/ads/googleads/v19/services/services/payments_account_service/transports/base.py deleted file mode 100644 index d80d2926b..000000000 --- a/google/ads/googleads/v19/services/services/payments_account_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import payments_account_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class PaymentsAccountServiceTransport(abc.ABC): - """Abstract transport class for PaymentsAccountService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.list_payments_accounts: gapic_v1.method.wrap_method( - self.list_payments_accounts, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def list_payments_accounts( - self, - ) -> Callable[ - [payments_account_service.ListPaymentsAccountsRequest], - Union[ - payments_account_service.ListPaymentsAccountsResponse, - Awaitable[payments_account_service.ListPaymentsAccountsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("PaymentsAccountServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/payments_account_service/transports/grpc.py b/google/ads/googleads/v19/services/services/payments_account_service/transports/grpc.py deleted file mode 100644 index 6d26c7c13..000000000 --- a/google/ads/googleads/v19/services/services/payments_account_service/transports/grpc.py +++ /dev/null @@ -1,389 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import payments_account_service -from .base import PaymentsAccountServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.PaymentsAccountService", - "rpcName": str(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.ads.googleads.v19.services.PaymentsAccountService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class PaymentsAccountServiceGrpcTransport(PaymentsAccountServiceTransport): - """gRPC backend transport for PaymentsAccountService. - - Service to provide payments accounts that can be used to set - up consolidated billing. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def list_payments_accounts( - self, - ) -> Callable[ - [payments_account_service.ListPaymentsAccountsRequest], - payments_account_service.ListPaymentsAccountsResponse, - ]: - r"""Return a callable for the list payments accounts method over gRPC. - - Returns all payments accounts associated with all managers - between the login customer ID and specified serving customer in - the hierarchy, inclusive. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PaymentsAccountError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListPaymentsAccountsRequest], - ~.ListPaymentsAccountsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_payments_accounts" not in self._stubs: - self._stubs["list_payments_accounts"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.PaymentsAccountService/ListPaymentsAccounts", - request_serializer=payments_account_service.ListPaymentsAccountsRequest.serialize, - response_deserializer=payments_account_service.ListPaymentsAccountsResponse.deserialize, - ) - ) - return self._stubs["list_payments_accounts"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("PaymentsAccountServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/payments_account_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/payments_account_service/transports/grpc_asyncio.py deleted file mode 100644 index 99db38eba..000000000 --- a/google/ads/googleads/v19/services/services/payments_account_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,412 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import payments_account_service -from .base import PaymentsAccountServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.PaymentsAccountService", - "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.ads.googleads.v19.services.PaymentsAccountService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class PaymentsAccountServiceGrpcAsyncIOTransport( - PaymentsAccountServiceTransport -): - """gRPC AsyncIO backend transport for PaymentsAccountService. - - Service to provide payments accounts that can be used to set - up consolidated billing. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def list_payments_accounts( - self, - ) -> Callable[ - [payments_account_service.ListPaymentsAccountsRequest], - Awaitable[payments_account_service.ListPaymentsAccountsResponse], - ]: - r"""Return a callable for the list payments accounts method over gRPC. - - Returns all payments accounts associated with all managers - between the login customer ID and specified serving customer in - the hierarchy, inclusive. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `PaymentsAccountError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListPaymentsAccountsRequest], - Awaitable[~.ListPaymentsAccountsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_payments_accounts" not in self._stubs: - self._stubs["list_payments_accounts"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.PaymentsAccountService/ListPaymentsAccounts", - request_serializer=payments_account_service.ListPaymentsAccountsRequest.serialize, - response_deserializer=payments_account_service.ListPaymentsAccountsResponse.deserialize, - ) - ) - return self._stubs["list_payments_accounts"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.list_payments_accounts: self._wrap_method( - self.list_payments_accounts, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("PaymentsAccountServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/product_link_invitation_service/async_client.py b/google/ads/googleads/v19/services/services/product_link_invitation_service/async_client.py deleted file mode 100644 index f0b0e1cd3..000000000 --- a/google/ads/googleads/v19/services/services/product_link_invitation_service/async_client.py +++ /dev/null @@ -1,677 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.enums.types import ( - product_link_invitation_status as gage_product_link_invitation_status, -) -from google.ads.googleads.v19.resources.types import ( - product_link_invitation as gagr_product_link_invitation, -) -from google.ads.googleads.v19.services.types import ( - product_link_invitation_service, -) -from .transports.base import ( - ProductLinkInvitationServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import ProductLinkInvitationServiceClient - -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 ProductLinkInvitationServiceAsyncClient: - """This service allows management of product link invitations - from Google Ads accounts to other accounts. - """ - - _client: ProductLinkInvitationServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ProductLinkInvitationServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - ProductLinkInvitationServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - ProductLinkInvitationServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ProductLinkInvitationServiceClient._DEFAULT_UNIVERSE - - customer_path = staticmethod( - ProductLinkInvitationServiceClient.customer_path - ) - parse_customer_path = staticmethod( - ProductLinkInvitationServiceClient.parse_customer_path - ) - product_link_invitation_path = staticmethod( - ProductLinkInvitationServiceClient.product_link_invitation_path - ) - parse_product_link_invitation_path = staticmethod( - ProductLinkInvitationServiceClient.parse_product_link_invitation_path - ) - common_billing_account_path = staticmethod( - ProductLinkInvitationServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ProductLinkInvitationServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ProductLinkInvitationServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ProductLinkInvitationServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ProductLinkInvitationServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ProductLinkInvitationServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ProductLinkInvitationServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ProductLinkInvitationServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ProductLinkInvitationServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ProductLinkInvitationServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductLinkInvitationServiceAsyncClient: The constructed client. - """ - return ProductLinkInvitationServiceClient.from_service_account_info.__func__(ProductLinkInvitationServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductLinkInvitationServiceAsyncClient: The constructed client. - """ - return ProductLinkInvitationServiceClient.from_service_account_file.__func__(ProductLinkInvitationServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ProductLinkInvitationServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ProductLinkInvitationServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ProductLinkInvitationServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ProductLinkInvitationServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ProductLinkInvitationServiceTransport, - Callable[..., ProductLinkInvitationServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the product link invitation service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ProductLinkInvitationServiceTransport,Callable[..., ProductLinkInvitationServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ProductLinkInvitationServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ProductLinkInvitationServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ProductLinkInvitationServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ProductLinkInvitationService", - "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.ads.googleads.v19.services.ProductLinkInvitationService", - "credentialsType": None, - } - ), - ) - - async def create_product_link_invitation( - self, - request: Optional[ - Union[ - product_link_invitation_service.CreateProductLinkInvitationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - product_link_invitation: Optional[ - gagr_product_link_invitation.ProductLinkInvitation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> product_link_invitation_service.CreateProductLinkInvitationResponse: - r"""Creates a product link invitation. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.CreateProductLinkInvitationRequest, dict]]): - The request object. Request message for - [ProductLinkInvitationService.CreateProductLinkInvitation][google.ads.googleads.v19.services.ProductLinkInvitationService.CreateProductLinkInvitation]. - customer_id (:class:`str`): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - product_link_invitation (:class:`google.ads.googleads.v19.resources.types.ProductLinkInvitation`): - Required. The product link invitation - to be created. - - This corresponds to the ``product_link_invitation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateProductLinkInvitationResponse: - Response message for product link - invitation create. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, product_link_invitation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - product_link_invitation_service.CreateProductLinkInvitationRequest, - ): - request = product_link_invitation_service.CreateProductLinkInvitationRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if product_link_invitation is not None: - request.product_link_invitation = product_link_invitation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.create_product_link_invitation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def update_product_link_invitation( - self, - request: Optional[ - Union[ - product_link_invitation_service.UpdateProductLinkInvitationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - product_link_invitation_status: Optional[ - gage_product_link_invitation_status.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus - ] = None, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> product_link_invitation_service.UpdateProductLinkInvitationResponse: - r"""Update a product link invitation. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.UpdateProductLinkInvitationRequest, dict]]): - The request object. Request message for - [ProductLinkInvitationService.UpdateProductLinkInvitation][google.ads.googleads.v19.services.ProductLinkInvitationService.UpdateProductLinkInvitation]. - customer_id (:class:`str`): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - product_link_invitation_status (:class:`google.ads.googleads.v19.enums.types.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus`): - Required. The product link invitation - to be created. - - This corresponds to the ``product_link_invitation_status`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - resource_name (:class:`str`): - Required. Resource name of the - product link invitation. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UpdateProductLinkInvitationResponse: - Response message for product link - invitation update. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [ - customer_id, - product_link_invitation_status, - resource_name, - ] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - product_link_invitation_service.UpdateProductLinkInvitationRequest, - ): - request = product_link_invitation_service.UpdateProductLinkInvitationRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if product_link_invitation_status is not None: - request.product_link_invitation_status = ( - product_link_invitation_status - ) - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.update_product_link_invitation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def remove_product_link_invitation( - self, - request: Optional[ - Union[ - product_link_invitation_service.RemoveProductLinkInvitationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> product_link_invitation_service.RemoveProductLinkInvitationResponse: - r"""Remove a product link invitation. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.RemoveProductLinkInvitationRequest, dict]]): - The request object. Request message for - [ProductLinkinvitationService.RemoveProductLinkInvitation][]. - customer_id (:class:`str`): - Required. The ID of the product link - invitation being removed. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - resource_name (:class:`str`): - Required. The resource name of the product link - invitation being removed. expected, in this format: - - ```` - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.RemoveProductLinkInvitationResponse: - Response message for product link - invitation removeal. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - product_link_invitation_service.RemoveProductLinkInvitationRequest, - ): - request = product_link_invitation_service.RemoveProductLinkInvitationRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.remove_product_link_invitation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ProductLinkInvitationServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ProductLinkInvitationServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/product_link_invitation_service/client.py b/google/ads/googleads/v19/services/services/product_link_invitation_service/client.py deleted file mode 100644 index d0810a44f..000000000 --- a/google/ads/googleads/v19/services/services/product_link_invitation_service/client.py +++ /dev/null @@ -1,1139 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.enums.types import ( - product_link_invitation_status as gage_product_link_invitation_status, -) -from google.ads.googleads.v19.resources.types import ( - product_link_invitation as gagr_product_link_invitation, -) -from google.ads.googleads.v19.services.types import ( - product_link_invitation_service, -) -from .transports.base import ( - ProductLinkInvitationServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ProductLinkInvitationServiceGrpcTransport -from .transports.grpc_asyncio import ( - ProductLinkInvitationServiceGrpcAsyncIOTransport, -) - - -class ProductLinkInvitationServiceClientMeta(type): - """Metaclass for the ProductLinkInvitationService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ProductLinkInvitationServiceTransport]] - _transport_registry["grpc"] = ProductLinkInvitationServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - ProductLinkInvitationServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ProductLinkInvitationServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ProductLinkInvitationServiceClient( - metaclass=ProductLinkInvitationServiceClientMeta -): - """This service allows management of product link invitations - from Google Ads accounts to other accounts. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductLinkInvitationServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductLinkInvitationServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ProductLinkInvitationServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ProductLinkInvitationServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def product_link_invitation_path( - customer_id: str, - customer_invitation_id: str, - ) -> str: - """Returns a fully-qualified product_link_invitation string.""" - return "customers/{customer_id}/productLinkInvitations/{customer_invitation_id}".format( - customer_id=customer_id, - customer_invitation_id=customer_invitation_id, - ) - - @staticmethod - def parse_product_link_invitation_path(path: str) -> Dict[str, str]: - """Parses a product_link_invitation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/productLinkInvitations/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - ProductLinkInvitationServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - ProductLinkInvitationServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = ProductLinkInvitationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ProductLinkInvitationServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ProductLinkInvitationServiceTransport, - Callable[..., ProductLinkInvitationServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the product link invitation service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ProductLinkInvitationServiceTransport,Callable[..., ProductLinkInvitationServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ProductLinkInvitationServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ProductLinkInvitationServiceClient._read_environment_variables() - self._client_cert_source = ( - ProductLinkInvitationServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - ProductLinkInvitationServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ProductLinkInvitationServiceTransport - ) - if transport_provided: - # transport is a ProductLinkInvitationServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - ProductLinkInvitationServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ProductLinkInvitationServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ProductLinkInvitationServiceTransport], - Callable[..., ProductLinkInvitationServiceTransport], - ] = ( - ProductLinkInvitationServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ProductLinkInvitationServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ProductLinkInvitationServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ProductLinkInvitationService", - "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.ads.googleads.v19.services.ProductLinkInvitationService", - "credentialsType": None, - } - ), - ) - - def create_product_link_invitation( - self, - request: Optional[ - Union[ - product_link_invitation_service.CreateProductLinkInvitationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - product_link_invitation: Optional[ - gagr_product_link_invitation.ProductLinkInvitation - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> product_link_invitation_service.CreateProductLinkInvitationResponse: - r"""Creates a product link invitation. - - Args: - request (Union[google.ads.googleads.v19.services.types.CreateProductLinkInvitationRequest, dict]): - The request object. Request message for - [ProductLinkInvitationService.CreateProductLinkInvitation][google.ads.googleads.v19.services.ProductLinkInvitationService.CreateProductLinkInvitation]. - customer_id (str): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - product_link_invitation (google.ads.googleads.v19.resources.types.ProductLinkInvitation): - Required. The product link invitation - to be created. - - This corresponds to the ``product_link_invitation`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateProductLinkInvitationResponse: - Response message for product link - invitation create. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, product_link_invitation] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - product_link_invitation_service.CreateProductLinkInvitationRequest, - ): - request = product_link_invitation_service.CreateProductLinkInvitationRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if product_link_invitation is not None: - request.product_link_invitation = product_link_invitation - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.create_product_link_invitation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def update_product_link_invitation( - self, - request: Optional[ - Union[ - product_link_invitation_service.UpdateProductLinkInvitationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - product_link_invitation_status: Optional[ - gage_product_link_invitation_status.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus - ] = None, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> product_link_invitation_service.UpdateProductLinkInvitationResponse: - r"""Update a product link invitation. - - Args: - request (Union[google.ads.googleads.v19.services.types.UpdateProductLinkInvitationRequest, dict]): - The request object. Request message for - [ProductLinkInvitationService.UpdateProductLinkInvitation][google.ads.googleads.v19.services.ProductLinkInvitationService.UpdateProductLinkInvitation]. - customer_id (str): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - product_link_invitation_status (google.ads.googleads.v19.enums.types.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus): - Required. The product link invitation - to be created. - - This corresponds to the ``product_link_invitation_status`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - resource_name (str): - Required. Resource name of the - product link invitation. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UpdateProductLinkInvitationResponse: - Response message for product link - invitation update. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [ - customer_id, - product_link_invitation_status, - resource_name, - ] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - product_link_invitation_service.UpdateProductLinkInvitationRequest, - ): - request = product_link_invitation_service.UpdateProductLinkInvitationRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if product_link_invitation_status is not None: - request.product_link_invitation_status = ( - product_link_invitation_status - ) - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.update_product_link_invitation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def remove_product_link_invitation( - self, - request: Optional[ - Union[ - product_link_invitation_service.RemoveProductLinkInvitationRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> product_link_invitation_service.RemoveProductLinkInvitationResponse: - r"""Remove a product link invitation. - - Args: - request (Union[google.ads.googleads.v19.services.types.RemoveProductLinkInvitationRequest, dict]): - The request object. Request message for - [ProductLinkinvitationService.RemoveProductLinkInvitation][]. - customer_id (str): - Required. The ID of the product link - invitation being removed. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - resource_name (str): - Required. The resource name of the product link - invitation being removed. expected, in this format: - - ```` - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.RemoveProductLinkInvitationResponse: - Response message for product link - invitation removeal. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - product_link_invitation_service.RemoveProductLinkInvitationRequest, - ): - request = product_link_invitation_service.RemoveProductLinkInvitationRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.remove_product_link_invitation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ProductLinkInvitationServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ProductLinkInvitationServiceClient",) diff --git a/google/ads/googleads/v19/services/services/product_link_invitation_service/transports/base.py b/google/ads/googleads/v19/services/services/product_link_invitation_service/transports/base.py deleted file mode 100644 index 73ebe19e5..000000000 --- a/google/ads/googleads/v19/services/services/product_link_invitation_service/transports/base.py +++ /dev/null @@ -1,214 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - product_link_invitation_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ProductLinkInvitationServiceTransport(abc.ABC): - """Abstract transport class for ProductLinkInvitationService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.create_product_link_invitation: gapic_v1.method.wrap_method( - self.create_product_link_invitation, - default_timeout=None, - client_info=client_info, - ), - self.update_product_link_invitation: gapic_v1.method.wrap_method( - self.update_product_link_invitation, - default_timeout=None, - client_info=client_info, - ), - self.remove_product_link_invitation: gapic_v1.method.wrap_method( - self.remove_product_link_invitation, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def create_product_link_invitation( - self, - ) -> Callable[ - [product_link_invitation_service.CreateProductLinkInvitationRequest], - Union[ - product_link_invitation_service.CreateProductLinkInvitationResponse, - Awaitable[ - product_link_invitation_service.CreateProductLinkInvitationResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def update_product_link_invitation( - self, - ) -> Callable[ - [product_link_invitation_service.UpdateProductLinkInvitationRequest], - Union[ - product_link_invitation_service.UpdateProductLinkInvitationResponse, - Awaitable[ - product_link_invitation_service.UpdateProductLinkInvitationResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def remove_product_link_invitation( - self, - ) -> Callable[ - [product_link_invitation_service.RemoveProductLinkInvitationRequest], - Union[ - product_link_invitation_service.RemoveProductLinkInvitationResponse, - Awaitable[ - product_link_invitation_service.RemoveProductLinkInvitationResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ProductLinkInvitationServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/product_link_invitation_service/transports/grpc.py b/google/ads/googleads/v19/services/services/product_link_invitation_service/transports/grpc.py deleted file mode 100644 index 00af4e78d..000000000 --- a/google/ads/googleads/v19/services/services/product_link_invitation_service/transports/grpc.py +++ /dev/null @@ -1,448 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - product_link_invitation_service, -) -from .base import ProductLinkInvitationServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ProductLinkInvitationService", - "rpcName": str(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.ads.googleads.v19.services.ProductLinkInvitationService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ProductLinkInvitationServiceGrpcTransport( - ProductLinkInvitationServiceTransport -): - """gRPC backend transport for ProductLinkInvitationService. - - This service allows management of product link invitations - from Google Ads accounts to other accounts. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def create_product_link_invitation( - self, - ) -> Callable[ - [product_link_invitation_service.CreateProductLinkInvitationRequest], - product_link_invitation_service.CreateProductLinkInvitationResponse, - ]: - r"""Return a callable for the create product link invitation method over gRPC. - - Creates a product link invitation. - - Returns: - Callable[[~.CreateProductLinkInvitationRequest], - ~.CreateProductLinkInvitationResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_product_link_invitation" not in self._stubs: - self._stubs["create_product_link_invitation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ProductLinkInvitationService/CreateProductLinkInvitation", - request_serializer=product_link_invitation_service.CreateProductLinkInvitationRequest.serialize, - response_deserializer=product_link_invitation_service.CreateProductLinkInvitationResponse.deserialize, - ) - ) - return self._stubs["create_product_link_invitation"] - - @property - def update_product_link_invitation( - self, - ) -> Callable[ - [product_link_invitation_service.UpdateProductLinkInvitationRequest], - product_link_invitation_service.UpdateProductLinkInvitationResponse, - ]: - r"""Return a callable for the update product link invitation method over gRPC. - - Update a product link invitation. - - Returns: - Callable[[~.UpdateProductLinkInvitationRequest], - ~.UpdateProductLinkInvitationResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "update_product_link_invitation" not in self._stubs: - self._stubs["update_product_link_invitation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ProductLinkInvitationService/UpdateProductLinkInvitation", - request_serializer=product_link_invitation_service.UpdateProductLinkInvitationRequest.serialize, - response_deserializer=product_link_invitation_service.UpdateProductLinkInvitationResponse.deserialize, - ) - ) - return self._stubs["update_product_link_invitation"] - - @property - def remove_product_link_invitation( - self, - ) -> Callable[ - [product_link_invitation_service.RemoveProductLinkInvitationRequest], - product_link_invitation_service.RemoveProductLinkInvitationResponse, - ]: - r"""Return a callable for the remove product link invitation method over gRPC. - - Remove a product link invitation. - - Returns: - Callable[[~.RemoveProductLinkInvitationRequest], - ~.RemoveProductLinkInvitationResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "remove_product_link_invitation" not in self._stubs: - self._stubs["remove_product_link_invitation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ProductLinkInvitationService/RemoveProductLinkInvitation", - request_serializer=product_link_invitation_service.RemoveProductLinkInvitationRequest.serialize, - response_deserializer=product_link_invitation_service.RemoveProductLinkInvitationResponse.deserialize, - ) - ) - return self._stubs["remove_product_link_invitation"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ProductLinkInvitationServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/product_link_invitation_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/product_link_invitation_service/transports/grpc_asyncio.py deleted file mode 100644 index eae32305a..000000000 --- a/google/ads/googleads/v19/services/services/product_link_invitation_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,485 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - product_link_invitation_service, -) -from .base import ProductLinkInvitationServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ProductLinkInvitationService", - "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.ads.googleads.v19.services.ProductLinkInvitationService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ProductLinkInvitationServiceGrpcAsyncIOTransport( - ProductLinkInvitationServiceTransport -): - """gRPC AsyncIO backend transport for ProductLinkInvitationService. - - This service allows management of product link invitations - from Google Ads accounts to other accounts. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def create_product_link_invitation( - self, - ) -> Callable[ - [product_link_invitation_service.CreateProductLinkInvitationRequest], - Awaitable[ - product_link_invitation_service.CreateProductLinkInvitationResponse - ], - ]: - r"""Return a callable for the create product link invitation method over gRPC. - - Creates a product link invitation. - - Returns: - Callable[[~.CreateProductLinkInvitationRequest], - Awaitable[~.CreateProductLinkInvitationResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_product_link_invitation" not in self._stubs: - self._stubs["create_product_link_invitation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ProductLinkInvitationService/CreateProductLinkInvitation", - request_serializer=product_link_invitation_service.CreateProductLinkInvitationRequest.serialize, - response_deserializer=product_link_invitation_service.CreateProductLinkInvitationResponse.deserialize, - ) - ) - return self._stubs["create_product_link_invitation"] - - @property - def update_product_link_invitation( - self, - ) -> Callable[ - [product_link_invitation_service.UpdateProductLinkInvitationRequest], - Awaitable[ - product_link_invitation_service.UpdateProductLinkInvitationResponse - ], - ]: - r"""Return a callable for the update product link invitation method over gRPC. - - Update a product link invitation. - - Returns: - Callable[[~.UpdateProductLinkInvitationRequest], - Awaitable[~.UpdateProductLinkInvitationResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "update_product_link_invitation" not in self._stubs: - self._stubs["update_product_link_invitation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ProductLinkInvitationService/UpdateProductLinkInvitation", - request_serializer=product_link_invitation_service.UpdateProductLinkInvitationRequest.serialize, - response_deserializer=product_link_invitation_service.UpdateProductLinkInvitationResponse.deserialize, - ) - ) - return self._stubs["update_product_link_invitation"] - - @property - def remove_product_link_invitation( - self, - ) -> Callable[ - [product_link_invitation_service.RemoveProductLinkInvitationRequest], - Awaitable[ - product_link_invitation_service.RemoveProductLinkInvitationResponse - ], - ]: - r"""Return a callable for the remove product link invitation method over gRPC. - - Remove a product link invitation. - - Returns: - Callable[[~.RemoveProductLinkInvitationRequest], - Awaitable[~.RemoveProductLinkInvitationResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "remove_product_link_invitation" not in self._stubs: - self._stubs["remove_product_link_invitation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ProductLinkInvitationService/RemoveProductLinkInvitation", - request_serializer=product_link_invitation_service.RemoveProductLinkInvitationRequest.serialize, - response_deserializer=product_link_invitation_service.RemoveProductLinkInvitationResponse.deserialize, - ) - ) - return self._stubs["remove_product_link_invitation"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.create_product_link_invitation: self._wrap_method( - self.create_product_link_invitation, - default_timeout=None, - client_info=client_info, - ), - self.update_product_link_invitation: self._wrap_method( - self.update_product_link_invitation, - default_timeout=None, - client_info=client_info, - ), - self.remove_product_link_invitation: self._wrap_method( - self.remove_product_link_invitation, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ProductLinkInvitationServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/product_link_service/async_client.py b/google/ads/googleads/v19/services/services/product_link_service/async_client.py deleted file mode 100644 index e4ca96889..000000000 --- a/google/ads/googleads/v19/services/services/product_link_service/async_client.py +++ /dev/null @@ -1,534 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.resources.types import ( - product_link as gagr_product_link, -) -from google.ads.googleads.v19.services.types import product_link_service -from .transports.base import ProductLinkServiceTransport, DEFAULT_CLIENT_INFO -from .client import ProductLinkServiceClient - -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 ProductLinkServiceAsyncClient: - """This service allows management of links between a Google - Ads customer and another product. - """ - - _client: ProductLinkServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ProductLinkServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ProductLinkServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - ProductLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ProductLinkServiceClient._DEFAULT_UNIVERSE - - customer_path = staticmethod(ProductLinkServiceClient.customer_path) - parse_customer_path = staticmethod( - ProductLinkServiceClient.parse_customer_path - ) - product_link_path = staticmethod(ProductLinkServiceClient.product_link_path) - parse_product_link_path = staticmethod( - ProductLinkServiceClient.parse_product_link_path - ) - common_billing_account_path = staticmethod( - ProductLinkServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ProductLinkServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ProductLinkServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ProductLinkServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ProductLinkServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ProductLinkServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ProductLinkServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ProductLinkServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ProductLinkServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ProductLinkServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductLinkServiceAsyncClient: The constructed client. - """ - return ProductLinkServiceClient.from_service_account_info.__func__(ProductLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductLinkServiceAsyncClient: The constructed client. - """ - return ProductLinkServiceClient.from_service_account_file.__func__(ProductLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ProductLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ProductLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ProductLinkServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ProductLinkServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ProductLinkServiceTransport, - Callable[..., ProductLinkServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the product link service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ProductLinkServiceTransport,Callable[..., ProductLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ProductLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ProductLinkServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ProductLinkServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ProductLinkService", - "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.ads.googleads.v19.services.ProductLinkService", - "credentialsType": None, - } - ), - ) - - async def create_product_link( - self, - request: Optional[ - Union[product_link_service.CreateProductLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - product_link: Optional[gagr_product_link.ProductLink] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> product_link_service.CreateProductLinkResponse: - r"""Creates a product link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.CreateProductLinkRequest, dict]]): - The request object. Request message for - [ProductLinkService.CreateProductLink][google.ads.googleads.v19.services.ProductLinkService.CreateProductLink]. - customer_id (:class:`str`): - Required. The ID of the customer for - which the product link is created. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - product_link (:class:`google.ads.googleads.v19.resources.types.ProductLink`): - Required. The product link to be - created. - - This corresponds to the ``product_link`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateProductLinkResponse: - Response message for - [ProductLinkService.CreateProductLink][google.ads.googleads.v19.services.ProductLinkService.CreateProductLink]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, product_link] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, product_link_service.CreateProductLinkRequest - ): - request = product_link_service.CreateProductLinkRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if product_link is not None: - request.product_link = product_link - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.create_product_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def remove_product_link( - self, - request: Optional[ - Union[product_link_service.RemoveProductLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> product_link_service.RemoveProductLinkResponse: - r"""Removes a product link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.RemoveProductLinkRequest, dict]]): - The request object. Request message for - [ProductLinkService.RemoveProductLink][google.ads.googleads.v19.services.ProductLinkService.RemoveProductLink]. - customer_id (:class:`str`): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - resource_name (:class:`str`): - Required. Remove operation: A resource name for the - product link to remove is expected, in this format: - - ``customers/{customer_id}/productLinks/{product_link_id}`` - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.RemoveProductLinkResponse: - Response message for product link - removal. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, product_link_service.RemoveProductLinkRequest - ): - request = product_link_service.RemoveProductLinkRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.remove_product_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ProductLinkServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ProductLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/product_link_service/client.py b/google/ads/googleads/v19/services/services/product_link_service/client.py deleted file mode 100644 index 8317a6f09..000000000 --- a/google/ads/googleads/v19/services/services/product_link_service/client.py +++ /dev/null @@ -1,984 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.resources.types import ( - product_link as gagr_product_link, -) -from google.ads.googleads.v19.services.types import product_link_service -from .transports.base import ProductLinkServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import ProductLinkServiceGrpcTransport -from .transports.grpc_asyncio import ProductLinkServiceGrpcAsyncIOTransport - - -class ProductLinkServiceClientMeta(type): - """Metaclass for the ProductLinkService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ProductLinkServiceTransport]] - _transport_registry["grpc"] = ProductLinkServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ProductLinkServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ProductLinkServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ProductLinkServiceClient(metaclass=ProductLinkServiceClientMeta): - """This service allows management of links between a Google - Ads customer and another product. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ProductLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ProductLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ProductLinkServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def customer_path( - customer_id: str, - ) -> str: - """Returns a fully-qualified customer string.""" - return "customers/{customer_id}".format( - customer_id=customer_id, - ) - - @staticmethod - def parse_customer_path(path: str) -> Dict[str, str]: - """Parses a customer path into its component segments.""" - m = re.match(r"^customers/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def product_link_path( - customer_id: str, - product_link_id: str, - ) -> str: - """Returns a fully-qualified product_link string.""" - return "customers/{customer_id}/productLinks/{product_link_id}".format( - customer_id=customer_id, - product_link_id=product_link_id, - ) - - @staticmethod - def parse_product_link_path(path: str) -> Dict[str, str]: - """Parses a product_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/productLinks/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ProductLinkServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ProductLinkServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - ProductLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ProductLinkServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ProductLinkServiceTransport, - Callable[..., ProductLinkServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the product link service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ProductLinkServiceTransport,Callable[..., ProductLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ProductLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ProductLinkServiceClient._read_environment_variables() - self._client_cert_source = ( - ProductLinkServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ProductLinkServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, ProductLinkServiceTransport) - if transport_provided: - # transport is a ProductLinkServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(ProductLinkServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ProductLinkServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ProductLinkServiceTransport], - Callable[..., ProductLinkServiceTransport], - ] = ( - ProductLinkServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., ProductLinkServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ProductLinkServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ProductLinkService", - "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.ads.googleads.v19.services.ProductLinkService", - "credentialsType": None, - } - ), - ) - - def create_product_link( - self, - request: Optional[ - Union[product_link_service.CreateProductLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - product_link: Optional[gagr_product_link.ProductLink] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> product_link_service.CreateProductLinkResponse: - r"""Creates a product link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.CreateProductLinkRequest, dict]): - The request object. Request message for - [ProductLinkService.CreateProductLink][google.ads.googleads.v19.services.ProductLinkService.CreateProductLink]. - customer_id (str): - Required. The ID of the customer for - which the product link is created. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - product_link (google.ads.googleads.v19.resources.types.ProductLink): - Required. The product link to be - created. - - This corresponds to the ``product_link`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.CreateProductLinkResponse: - Response message for - [ProductLinkService.CreateProductLink][google.ads.googleads.v19.services.ProductLinkService.CreateProductLink]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, product_link] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, product_link_service.CreateProductLinkRequest - ): - request = product_link_service.CreateProductLinkRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if product_link is not None: - request.product_link = product_link - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.create_product_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def remove_product_link( - self, - request: Optional[ - Union[product_link_service.RemoveProductLinkRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> product_link_service.RemoveProductLinkResponse: - r"""Removes a product link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.RemoveProductLinkRequest, dict]): - The request object. Request message for - [ProductLinkService.RemoveProductLink][google.ads.googleads.v19.services.ProductLinkService.RemoveProductLink]. - customer_id (str): - Required. The ID of the customer - being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - resource_name (str): - Required. Remove operation: A resource name for the - product link to remove is expected, in this format: - - ``customers/{customer_id}/productLinks/{product_link_id}`` - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.RemoveProductLinkResponse: - Response message for product link - removal. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, product_link_service.RemoveProductLinkRequest - ): - request = product_link_service.RemoveProductLinkRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.remove_product_link - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ProductLinkServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ProductLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/product_link_service/transports/base.py b/google/ads/googleads/v19/services/services/product_link_service/transports/base.py deleted file mode 100644 index 8192ef4e1..000000000 --- a/google/ads/googleads/v19/services/services/product_link_service/transports/base.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import product_link_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ProductLinkServiceTransport(abc.ABC): - """Abstract transport class for ProductLinkService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.create_product_link: gapic_v1.method.wrap_method( - self.create_product_link, - default_timeout=None, - client_info=client_info, - ), - self.remove_product_link: gapic_v1.method.wrap_method( - self.remove_product_link, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def create_product_link( - self, - ) -> Callable[ - [product_link_service.CreateProductLinkRequest], - Union[ - product_link_service.CreateProductLinkResponse, - Awaitable[product_link_service.CreateProductLinkResponse], - ], - ]: - raise NotImplementedError() - - @property - def remove_product_link( - self, - ) -> Callable[ - [product_link_service.RemoveProductLinkRequest], - Union[ - product_link_service.RemoveProductLinkResponse, - Awaitable[product_link_service.RemoveProductLinkResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ProductLinkServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/product_link_service/transports/grpc.py b/google/ads/googleads/v19/services/services/product_link_service/transports/grpc.py deleted file mode 100644 index b5f61eb6e..000000000 --- a/google/ads/googleads/v19/services/services/product_link_service/transports/grpc.py +++ /dev/null @@ -1,423 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import product_link_service -from .base import ProductLinkServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ProductLinkService", - "rpcName": str(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.ads.googleads.v19.services.ProductLinkService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ProductLinkServiceGrpcTransport(ProductLinkServiceTransport): - """gRPC backend transport for ProductLinkService. - - This service allows management of links between a Google - Ads customer and another product. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def create_product_link( - self, - ) -> Callable[ - [product_link_service.CreateProductLinkRequest], - product_link_service.CreateProductLinkResponse, - ]: - r"""Return a callable for the create product link method over gRPC. - - Creates a product link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.CreateProductLinkRequest], - ~.CreateProductLinkResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_product_link" not in self._stubs: - self._stubs["create_product_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ProductLinkService/CreateProductLink", - request_serializer=product_link_service.CreateProductLinkRequest.serialize, - response_deserializer=product_link_service.CreateProductLinkResponse.deserialize, - ) - ) - return self._stubs["create_product_link"] - - @property - def remove_product_link( - self, - ) -> Callable[ - [product_link_service.RemoveProductLinkRequest], - product_link_service.RemoveProductLinkResponse, - ]: - r"""Return a callable for the remove product link method over gRPC. - - Removes a product link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.RemoveProductLinkRequest], - ~.RemoveProductLinkResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "remove_product_link" not in self._stubs: - self._stubs["remove_product_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ProductLinkService/RemoveProductLink", - request_serializer=product_link_service.RemoveProductLinkRequest.serialize, - response_deserializer=product_link_service.RemoveProductLinkResponse.deserialize, - ) - ) - return self._stubs["remove_product_link"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ProductLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/product_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/product_link_service/transports/grpc_asyncio.py deleted file mode 100644 index c1599222d..000000000 --- a/google/ads/googleads/v19/services/services/product_link_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,449 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import product_link_service -from .base import ProductLinkServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ProductLinkService", - "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.ads.googleads.v19.services.ProductLinkService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ProductLinkServiceGrpcAsyncIOTransport(ProductLinkServiceTransport): - """gRPC AsyncIO backend transport for ProductLinkService. - - This service allows management of links between a Google - Ads customer and another product. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def create_product_link( - self, - ) -> Callable[ - [product_link_service.CreateProductLinkRequest], - Awaitable[product_link_service.CreateProductLinkResponse], - ]: - r"""Return a callable for the create product link method over gRPC. - - Creates a product link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.CreateProductLinkRequest], - Awaitable[~.CreateProductLinkResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "create_product_link" not in self._stubs: - self._stubs["create_product_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ProductLinkService/CreateProductLink", - request_serializer=product_link_service.CreateProductLinkRequest.serialize, - response_deserializer=product_link_service.CreateProductLinkResponse.deserialize, - ) - ) - return self._stubs["create_product_link"] - - @property - def remove_product_link( - self, - ) -> Callable[ - [product_link_service.RemoveProductLinkRequest], - Awaitable[product_link_service.RemoveProductLinkResponse], - ]: - r"""Return a callable for the remove product link method over gRPC. - - Removes a product link. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.RemoveProductLinkRequest], - Awaitable[~.RemoveProductLinkResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "remove_product_link" not in self._stubs: - self._stubs["remove_product_link"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ProductLinkService/RemoveProductLink", - request_serializer=product_link_service.RemoveProductLinkRequest.serialize, - response_deserializer=product_link_service.RemoveProductLinkResponse.deserialize, - ) - ) - return self._stubs["remove_product_link"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.create_product_link: self._wrap_method( - self.create_product_link, - default_timeout=None, - client_info=client_info, - ), - self.remove_product_link: self._wrap_method( - self.remove_product_link, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ProductLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/reach_plan_service/async_client.py b/google/ads/googleads/v19/services/services/reach_plan_service/async_client.py deleted file mode 100644 index f9a2b2520..000000000 --- a/google/ads/googleads/v19/services/services/reach_plan_service/async_client.py +++ /dev/null @@ -1,667 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import reach_plan_service -from .transports.base import ReachPlanServiceTransport, DEFAULT_CLIENT_INFO -from .client import ReachPlanServiceClient - -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 ReachPlanServiceAsyncClient: - """Reach Plan Service gives users information about audience - size that can be reached through advertisement on YouTube. In - particular, GenerateReachForecast provides estimated number of - people of specified demographics that can be reached by an ad in - a given market by a campaign of certain duration with a defined - budget. - """ - - _client: ReachPlanServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ReachPlanServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ReachPlanServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - ReachPlanServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ReachPlanServiceClient._DEFAULT_UNIVERSE - - common_billing_account_path = staticmethod( - ReachPlanServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ReachPlanServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(ReachPlanServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - ReachPlanServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ReachPlanServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ReachPlanServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ReachPlanServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ReachPlanServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ReachPlanServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ReachPlanServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ReachPlanServiceAsyncClient: The constructed client. - """ - return ReachPlanServiceClient.from_service_account_info.__func__(ReachPlanServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ReachPlanServiceAsyncClient: The constructed client. - """ - return ReachPlanServiceClient.from_service_account_file.__func__(ReachPlanServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ReachPlanServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ReachPlanServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ReachPlanServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ReachPlanServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ReachPlanServiceTransport, - Callable[..., ReachPlanServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the reach plan service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ReachPlanServiceTransport,Callable[..., ReachPlanServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ReachPlanServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ReachPlanServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ReachPlanServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ReachPlanService", - "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.ads.googleads.v19.services.ReachPlanService", - "credentialsType": None, - } - ), - ) - - async def generate_conversion_rates( - self, - request: Optional[ - Union[reach_plan_service.GenerateConversionRatesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> reach_plan_service.GenerateConversionRatesResponse: - r"""Returns a collection of conversion rate suggestions for - supported plannable products. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateConversionRatesRequest, dict]]): - The request object. Request message for - [ReachPlanService.GenerateConversionRates][google.ads.googleads.v19.services.ReachPlanService.GenerateConversionRates]. - customer_id (:class:`str`): - Required. The ID of the customer. A - conversion rate based on the historical - data of this customer may be suggested. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateConversionRatesResponse: - Response message for - [ReachPlanService.GenerateConversionRates][google.ads.googleads.v19.services.ReachPlanService.GenerateConversionRates], - containing conversion rate suggestions for supported - plannable products. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, reach_plan_service.GenerateConversionRatesRequest - ): - request = reach_plan_service.GenerateConversionRatesRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_conversion_rates - ] - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_plannable_locations( - self, - request: Optional[ - Union[reach_plan_service.ListPlannableLocationsRequest, dict] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> reach_plan_service.ListPlannableLocationsResponse: - r"""Returns the list of plannable locations (for example, - countries). - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ListPlannableLocationsRequest, dict]]): - The request object. Request message for - [ReachPlanService.ListPlannableLocations][google.ads.googleads.v19.services.ReachPlanService.ListPlannableLocations]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListPlannableLocationsResponse: - The list of plannable locations. - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, reach_plan_service.ListPlannableLocationsRequest - ): - request = reach_plan_service.ListPlannableLocationsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_plannable_locations - ] - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def list_plannable_products( - self, - request: Optional[ - Union[reach_plan_service.ListPlannableProductsRequest, dict] - ] = None, - *, - plannable_location_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> reach_plan_service.ListPlannableProductsResponse: - r"""Returns the list of per-location plannable YouTube ad formats - with allowed targeting. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ListPlannableProductsRequest, dict]]): - The request object. Request to list available products in - a given location. - plannable_location_id (:class:`str`): - Required. The ID of the selected location for planning. - To list the available plannable location IDs use - [ReachPlanService.ListPlannableLocations][google.ads.googleads.v19.services.ReachPlanService.ListPlannableLocations]. - - This corresponds to the ``plannable_location_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListPlannableProductsResponse: - A response with all available - products. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [plannable_location_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, reach_plan_service.ListPlannableProductsRequest - ): - request = reach_plan_service.ListPlannableProductsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if plannable_location_id is not None: - request.plannable_location_id = plannable_location_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.list_plannable_products - ] - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def generate_reach_forecast( - self, - request: Optional[ - Union[reach_plan_service.GenerateReachForecastRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - campaign_duration: Optional[reach_plan_service.CampaignDuration] = None, - planned_products: Optional[ - MutableSequence[reach_plan_service.PlannedProduct] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> reach_plan_service.GenerateReachForecastResponse: - r"""Generates a reach forecast for a given targeting / product mix. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `ReachPlanError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateReachForecastRequest, dict]]): - The request object. Request message for - [ReachPlanService.GenerateReachForecast][google.ads.googleads.v19.services.ReachPlanService.GenerateReachForecast]. - customer_id (:class:`str`): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - campaign_duration (:class:`google.ads.googleads.v19.services.types.CampaignDuration`): - Required. Campaign duration. - This corresponds to the ``campaign_duration`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - planned_products (:class:`MutableSequence[google.ads.googleads.v19.services.types.PlannedProduct]`): - Required. The products to be - forecast. The max number of allowed - planned products is 15. - - This corresponds to the ``planned_products`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateReachForecastResponse: - Response message containing the - generated reach curve. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, campaign_duration, planned_products] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, reach_plan_service.GenerateReachForecastRequest - ): - request = reach_plan_service.GenerateReachForecastRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if campaign_duration is not None: - request.campaign_duration = campaign_duration - if planned_products: - request.planned_products.extend(planned_products) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_reach_forecast - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ReachPlanServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ReachPlanServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/reach_plan_service/client.py b/google/ads/googleads/v19/services/services/reach_plan_service/client.py deleted file mode 100644 index 313c7d7fa..000000000 --- a/google/ads/googleads/v19/services/services/reach_plan_service/client.py +++ /dev/null @@ -1,1101 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import reach_plan_service -from .transports.base import ReachPlanServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import ReachPlanServiceGrpcTransport -from .transports.grpc_asyncio import ReachPlanServiceGrpcAsyncIOTransport - - -class ReachPlanServiceClientMeta(type): - """Metaclass for the ReachPlanService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ReachPlanServiceTransport]] - _transport_registry["grpc"] = ReachPlanServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ReachPlanServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ReachPlanServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ReachPlanServiceClient(metaclass=ReachPlanServiceClientMeta): - """Reach Plan Service gives users information about audience - size that can be reached through advertisement on YouTube. In - particular, GenerateReachForecast provides estimated number of - people of specified demographics that can be reached by an ad in - a given market by a campaign of certain duration with a defined - budget. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ReachPlanServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ReachPlanServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ReachPlanServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ReachPlanServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ReachPlanServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ReachPlanServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - ReachPlanServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ReachPlanServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ReachPlanServiceTransport, - Callable[..., ReachPlanServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the reach plan service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ReachPlanServiceTransport,Callable[..., ReachPlanServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ReachPlanServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ReachPlanServiceClient._read_environment_variables() - self._client_cert_source = ( - ReachPlanServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ReachPlanServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, ReachPlanServiceTransport) - if transport_provided: - # transport is a ReachPlanServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(ReachPlanServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ReachPlanServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ReachPlanServiceTransport], - Callable[..., ReachPlanServiceTransport], - ] = ( - ReachPlanServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., ReachPlanServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ReachPlanServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ReachPlanService", - "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.ads.googleads.v19.services.ReachPlanService", - "credentialsType": None, - } - ), - ) - - def generate_conversion_rates( - self, - request: Optional[ - Union[reach_plan_service.GenerateConversionRatesRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> reach_plan_service.GenerateConversionRatesResponse: - r"""Returns a collection of conversion rate suggestions for - supported plannable products. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateConversionRatesRequest, dict]): - The request object. Request message for - [ReachPlanService.GenerateConversionRates][google.ads.googleads.v19.services.ReachPlanService.GenerateConversionRates]. - customer_id (str): - Required. The ID of the customer. A - conversion rate based on the historical - data of this customer may be suggested. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateConversionRatesResponse: - Response message for - [ReachPlanService.GenerateConversionRates][google.ads.googleads.v19.services.ReachPlanService.GenerateConversionRates], - containing conversion rate suggestions for supported - plannable products. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, reach_plan_service.GenerateConversionRatesRequest - ): - request = reach_plan_service.GenerateConversionRatesRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_conversion_rates - ] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_plannable_locations( - self, - request: Optional[ - Union[reach_plan_service.ListPlannableLocationsRequest, dict] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> reach_plan_service.ListPlannableLocationsResponse: - r"""Returns the list of plannable locations (for example, - countries). - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ListPlannableLocationsRequest, dict]): - The request object. Request message for - [ReachPlanService.ListPlannableLocations][google.ads.googleads.v19.services.ReachPlanService.ListPlannableLocations]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListPlannableLocationsResponse: - The list of plannable locations. - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, reach_plan_service.ListPlannableLocationsRequest - ): - request = reach_plan_service.ListPlannableLocationsRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.list_plannable_locations - ] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def list_plannable_products( - self, - request: Optional[ - Union[reach_plan_service.ListPlannableProductsRequest, dict] - ] = None, - *, - plannable_location_id: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> reach_plan_service.ListPlannableProductsResponse: - r"""Returns the list of per-location plannable YouTube ad formats - with allowed targeting. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ListPlannableProductsRequest, dict]): - The request object. Request to list available products in - a given location. - plannable_location_id (str): - Required. The ID of the selected location for planning. - To list the available plannable location IDs use - [ReachPlanService.ListPlannableLocations][google.ads.googleads.v19.services.ReachPlanService.ListPlannableLocations]. - - This corresponds to the ``plannable_location_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ListPlannableProductsResponse: - A response with all available - products. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [plannable_location_id] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, reach_plan_service.ListPlannableProductsRequest - ): - request = reach_plan_service.ListPlannableProductsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if plannable_location_id is not None: - request.plannable_location_id = plannable_location_id - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.list_plannable_products - ] - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def generate_reach_forecast( - self, - request: Optional[ - Union[reach_plan_service.GenerateReachForecastRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - campaign_duration: Optional[reach_plan_service.CampaignDuration] = None, - planned_products: Optional[ - MutableSequence[reach_plan_service.PlannedProduct] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> reach_plan_service.GenerateReachForecastResponse: - r"""Generates a reach forecast for a given targeting / product mix. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `ReachPlanError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateReachForecastRequest, dict]): - The request object. Request message for - [ReachPlanService.GenerateReachForecast][google.ads.googleads.v19.services.ReachPlanService.GenerateReachForecast]. - customer_id (str): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - campaign_duration (google.ads.googleads.v19.services.types.CampaignDuration): - Required. Campaign duration. - This corresponds to the ``campaign_duration`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - planned_products (MutableSequence[google.ads.googleads.v19.services.types.PlannedProduct]): - Required. The products to be - forecast. The max number of allowed - planned products is 15. - - This corresponds to the ``planned_products`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateReachForecastResponse: - Response message containing the - generated reach curve. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, campaign_duration, planned_products] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, reach_plan_service.GenerateReachForecastRequest - ): - request = reach_plan_service.GenerateReachForecastRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if campaign_duration is not None: - request.campaign_duration = campaign_duration - if planned_products is not None: - request.planned_products = planned_products - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_reach_forecast - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ReachPlanServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ReachPlanServiceClient",) diff --git a/google/ads/googleads/v19/services/services/reach_plan_service/transports/base.py b/google/ads/googleads/v19/services/services/reach_plan_service/transports/base.py deleted file mode 100644 index 243f06e78..000000000 --- a/google/ads/googleads/v19/services/services/reach_plan_service/transports/base.py +++ /dev/null @@ -1,223 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import reach_plan_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ReachPlanServiceTransport(abc.ABC): - """Abstract transport class for ReachPlanService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.generate_conversion_rates: gapic_v1.method.wrap_method( - self.generate_conversion_rates, - default_timeout=None, - client_info=client_info, - ), - self.list_plannable_locations: gapic_v1.method.wrap_method( - self.list_plannable_locations, - default_timeout=None, - client_info=client_info, - ), - self.list_plannable_products: gapic_v1.method.wrap_method( - self.list_plannable_products, - default_timeout=None, - client_info=client_info, - ), - self.generate_reach_forecast: gapic_v1.method.wrap_method( - self.generate_reach_forecast, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def generate_conversion_rates( - self, - ) -> Callable[ - [reach_plan_service.GenerateConversionRatesRequest], - Union[ - reach_plan_service.GenerateConversionRatesResponse, - Awaitable[reach_plan_service.GenerateConversionRatesResponse], - ], - ]: - raise NotImplementedError() - - @property - def list_plannable_locations( - self, - ) -> Callable[ - [reach_plan_service.ListPlannableLocationsRequest], - Union[ - reach_plan_service.ListPlannableLocationsResponse, - Awaitable[reach_plan_service.ListPlannableLocationsResponse], - ], - ]: - raise NotImplementedError() - - @property - def list_plannable_products( - self, - ) -> Callable[ - [reach_plan_service.ListPlannableProductsRequest], - Union[ - reach_plan_service.ListPlannableProductsResponse, - Awaitable[reach_plan_service.ListPlannableProductsResponse], - ], - ]: - raise NotImplementedError() - - @property - def generate_reach_forecast( - self, - ) -> Callable[ - [reach_plan_service.GenerateReachForecastRequest], - Union[ - reach_plan_service.GenerateReachForecastResponse, - Awaitable[reach_plan_service.GenerateReachForecastResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ReachPlanServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/reach_plan_service/transports/grpc.py b/google/ads/googleads/v19/services/services/reach_plan_service/transports/grpc.py deleted file mode 100644 index 97a616f27..000000000 --- a/google/ads/googleads/v19/services/services/reach_plan_service/transports/grpc.py +++ /dev/null @@ -1,499 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import reach_plan_service -from .base import ReachPlanServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ReachPlanService", - "rpcName": str(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.ads.googleads.v19.services.ReachPlanService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ReachPlanServiceGrpcTransport(ReachPlanServiceTransport): - """gRPC backend transport for ReachPlanService. - - Reach Plan Service gives users information about audience - size that can be reached through advertisement on YouTube. In - particular, GenerateReachForecast provides estimated number of - people of specified demographics that can be reached by an ad in - a given market by a campaign of certain duration with a defined - budget. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def generate_conversion_rates( - self, - ) -> Callable[ - [reach_plan_service.GenerateConversionRatesRequest], - reach_plan_service.GenerateConversionRatesResponse, - ]: - r"""Return a callable for the generate conversion rates method over gRPC. - - Returns a collection of conversion rate suggestions for - supported plannable products. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateConversionRatesRequest], - ~.GenerateConversionRatesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_conversion_rates" not in self._stubs: - self._stubs["generate_conversion_rates"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ReachPlanService/GenerateConversionRates", - request_serializer=reach_plan_service.GenerateConversionRatesRequest.serialize, - response_deserializer=reach_plan_service.GenerateConversionRatesResponse.deserialize, - ) - ) - return self._stubs["generate_conversion_rates"] - - @property - def list_plannable_locations( - self, - ) -> Callable[ - [reach_plan_service.ListPlannableLocationsRequest], - reach_plan_service.ListPlannableLocationsResponse, - ]: - r"""Return a callable for the list plannable locations method over gRPC. - - Returns the list of plannable locations (for example, - countries). - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListPlannableLocationsRequest], - ~.ListPlannableLocationsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_plannable_locations" not in self._stubs: - self._stubs["list_plannable_locations"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ReachPlanService/ListPlannableLocations", - request_serializer=reach_plan_service.ListPlannableLocationsRequest.serialize, - response_deserializer=reach_plan_service.ListPlannableLocationsResponse.deserialize, - ) - ) - return self._stubs["list_plannable_locations"] - - @property - def list_plannable_products( - self, - ) -> Callable[ - [reach_plan_service.ListPlannableProductsRequest], - reach_plan_service.ListPlannableProductsResponse, - ]: - r"""Return a callable for the list plannable products method over gRPC. - - Returns the list of per-location plannable YouTube ad formats - with allowed targeting. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListPlannableProductsRequest], - ~.ListPlannableProductsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_plannable_products" not in self._stubs: - self._stubs["list_plannable_products"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ReachPlanService/ListPlannableProducts", - request_serializer=reach_plan_service.ListPlannableProductsRequest.serialize, - response_deserializer=reach_plan_service.ListPlannableProductsResponse.deserialize, - ) - ) - return self._stubs["list_plannable_products"] - - @property - def generate_reach_forecast( - self, - ) -> Callable[ - [reach_plan_service.GenerateReachForecastRequest], - reach_plan_service.GenerateReachForecastResponse, - ]: - r"""Return a callable for the generate reach forecast method over gRPC. - - Generates a reach forecast for a given targeting / product mix. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `ReachPlanError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateReachForecastRequest], - ~.GenerateReachForecastResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_reach_forecast" not in self._stubs: - self._stubs["generate_reach_forecast"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ReachPlanService/GenerateReachForecast", - request_serializer=reach_plan_service.GenerateReachForecastRequest.serialize, - response_deserializer=reach_plan_service.GenerateReachForecastResponse.deserialize, - ) - ) - return self._stubs["generate_reach_forecast"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ReachPlanServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/reach_plan_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/reach_plan_service/transports/grpc_asyncio.py deleted file mode 100644 index 154bcdf82..000000000 --- a/google/ads/googleads/v19/services/services/reach_plan_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,535 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import reach_plan_service -from .base import ReachPlanServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ReachPlanService", - "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.ads.googleads.v19.services.ReachPlanService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ReachPlanServiceGrpcAsyncIOTransport(ReachPlanServiceTransport): - """gRPC AsyncIO backend transport for ReachPlanService. - - Reach Plan Service gives users information about audience - size that can be reached through advertisement on YouTube. In - particular, GenerateReachForecast provides estimated number of - people of specified demographics that can be reached by an ad in - a given market by a campaign of certain duration with a defined - budget. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def generate_conversion_rates( - self, - ) -> Callable[ - [reach_plan_service.GenerateConversionRatesRequest], - Awaitable[reach_plan_service.GenerateConversionRatesResponse], - ]: - r"""Return a callable for the generate conversion rates method over gRPC. - - Returns a collection of conversion rate suggestions for - supported plannable products. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateConversionRatesRequest], - Awaitable[~.GenerateConversionRatesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_conversion_rates" not in self._stubs: - self._stubs["generate_conversion_rates"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ReachPlanService/GenerateConversionRates", - request_serializer=reach_plan_service.GenerateConversionRatesRequest.serialize, - response_deserializer=reach_plan_service.GenerateConversionRatesResponse.deserialize, - ) - ) - return self._stubs["generate_conversion_rates"] - - @property - def list_plannable_locations( - self, - ) -> Callable[ - [reach_plan_service.ListPlannableLocationsRequest], - Awaitable[reach_plan_service.ListPlannableLocationsResponse], - ]: - r"""Return a callable for the list plannable locations method over gRPC. - - Returns the list of plannable locations (for example, - countries). - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListPlannableLocationsRequest], - Awaitable[~.ListPlannableLocationsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_plannable_locations" not in self._stubs: - self._stubs["list_plannable_locations"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ReachPlanService/ListPlannableLocations", - request_serializer=reach_plan_service.ListPlannableLocationsRequest.serialize, - response_deserializer=reach_plan_service.ListPlannableLocationsResponse.deserialize, - ) - ) - return self._stubs["list_plannable_locations"] - - @property - def list_plannable_products( - self, - ) -> Callable[ - [reach_plan_service.ListPlannableProductsRequest], - Awaitable[reach_plan_service.ListPlannableProductsResponse], - ]: - r"""Return a callable for the list plannable products method over gRPC. - - Returns the list of per-location plannable YouTube ad formats - with allowed targeting. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.ListPlannableProductsRequest], - Awaitable[~.ListPlannableProductsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "list_plannable_products" not in self._stubs: - self._stubs["list_plannable_products"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ReachPlanService/ListPlannableProducts", - request_serializer=reach_plan_service.ListPlannableProductsRequest.serialize, - response_deserializer=reach_plan_service.ListPlannableProductsResponse.deserialize, - ) - ) - return self._stubs["list_plannable_products"] - - @property - def generate_reach_forecast( - self, - ) -> Callable[ - [reach_plan_service.GenerateReachForecastRequest], - Awaitable[reach_plan_service.GenerateReachForecastResponse], - ]: - r"""Return a callable for the generate reach forecast method over gRPC. - - Generates a reach forecast for a given targeting / product mix. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ - `ReachPlanError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateReachForecastRequest], - Awaitable[~.GenerateReachForecastResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_reach_forecast" not in self._stubs: - self._stubs["generate_reach_forecast"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ReachPlanService/GenerateReachForecast", - request_serializer=reach_plan_service.GenerateReachForecastRequest.serialize, - response_deserializer=reach_plan_service.GenerateReachForecastResponse.deserialize, - ) - ) - return self._stubs["generate_reach_forecast"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.generate_conversion_rates: self._wrap_method( - self.generate_conversion_rates, - default_timeout=None, - client_info=client_info, - ), - self.list_plannable_locations: self._wrap_method( - self.list_plannable_locations, - default_timeout=None, - client_info=client_info, - ), - self.list_plannable_products: self._wrap_method( - self.list_plannable_products, - default_timeout=None, - client_info=client_info, - ), - self.generate_reach_forecast: self._wrap_method( - self.generate_reach_forecast, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ReachPlanServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/recommendation_service/async_client.py b/google/ads/googleads/v19/services/services/recommendation_service/async_client.py deleted file mode 100644 index 71a8242f3..000000000 --- a/google/ads/googleads/v19/services/services/recommendation_service/async_client.py +++ /dev/null @@ -1,713 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.enums.types import ( - advertising_channel_type as gage_advertising_channel_type, -) -from google.ads.googleads.v19.enums.types import recommendation_type -from google.ads.googleads.v19.services.types import recommendation_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import RecommendationServiceTransport, DEFAULT_CLIENT_INFO -from .client import RecommendationServiceClient - -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 RecommendationServiceAsyncClient: - """Service to manage recommendations.""" - - _client: RecommendationServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = RecommendationServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = RecommendationServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - RecommendationServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = RecommendationServiceClient._DEFAULT_UNIVERSE - - ad_path = staticmethod(RecommendationServiceClient.ad_path) - parse_ad_path = staticmethod(RecommendationServiceClient.parse_ad_path) - ad_group_path = staticmethod(RecommendationServiceClient.ad_group_path) - parse_ad_group_path = staticmethod( - RecommendationServiceClient.parse_ad_group_path - ) - asset_path = staticmethod(RecommendationServiceClient.asset_path) - parse_asset_path = staticmethod( - RecommendationServiceClient.parse_asset_path - ) - campaign_path = staticmethod(RecommendationServiceClient.campaign_path) - parse_campaign_path = staticmethod( - RecommendationServiceClient.parse_campaign_path - ) - campaign_budget_path = staticmethod( - RecommendationServiceClient.campaign_budget_path - ) - parse_campaign_budget_path = staticmethod( - RecommendationServiceClient.parse_campaign_budget_path - ) - conversion_action_path = staticmethod( - RecommendationServiceClient.conversion_action_path - ) - parse_conversion_action_path = staticmethod( - RecommendationServiceClient.parse_conversion_action_path - ) - recommendation_path = staticmethod( - RecommendationServiceClient.recommendation_path - ) - parse_recommendation_path = staticmethod( - RecommendationServiceClient.parse_recommendation_path - ) - common_billing_account_path = staticmethod( - RecommendationServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - RecommendationServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - RecommendationServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - RecommendationServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - RecommendationServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - RecommendationServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - RecommendationServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - RecommendationServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - RecommendationServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - RecommendationServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RecommendationServiceAsyncClient: The constructed client. - """ - return RecommendationServiceClient.from_service_account_info.__func__(RecommendationServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RecommendationServiceAsyncClient: The constructed client. - """ - return RecommendationServiceClient.from_service_account_file.__func__(RecommendationServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return RecommendationServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> RecommendationServiceTransport: - """Returns the transport used by the client instance. - - Returns: - RecommendationServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = RecommendationServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - RecommendationServiceTransport, - Callable[..., RecommendationServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the recommendation service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,RecommendationServiceTransport,Callable[..., RecommendationServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the RecommendationServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = RecommendationServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.RecommendationServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.RecommendationService", - "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.ads.googleads.v19.services.RecommendationService", - "credentialsType": None, - } - ), - ) - - async def apply_recommendation( - self, - request: Optional[ - Union[recommendation_service.ApplyRecommendationRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[recommendation_service.ApplyRecommendationOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> recommendation_service.ApplyRecommendationResponse: - r"""Applies given recommendations with corresponding apply - parameters. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ - `UrlFieldError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.ApplyRecommendationRequest, dict]]): - The request object. Request message for - [RecommendationService.ApplyRecommendation][google.ads.googleads.v19.services.RecommendationService.ApplyRecommendation]. - customer_id (:class:`str`): - Required. The ID of the customer with - the recommendation. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.ApplyRecommendationOperation]`): - Required. The list of operations to apply - recommendations. If partial_failure=false all - recommendations should be of the same type There is a - limit of 100 operations per request. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ApplyRecommendationResponse: - Response message for - [RecommendationService.ApplyRecommendation][google.ads.googleads.v19.services.RecommendationService.ApplyRecommendation]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, recommendation_service.ApplyRecommendationRequest - ): - request = recommendation_service.ApplyRecommendationRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.apply_recommendation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def dismiss_recommendation( - self, - request: Optional[ - Union[recommendation_service.DismissRecommendationRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - recommendation_service.DismissRecommendationRequest.DismissRecommendationOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> recommendation_service.DismissRecommendationResponse: - r"""Dismisses given recommendations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ - `RecommendationError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.DismissRecommendationRequest, dict]]): - The request object. Request message for - [RecommendationService.DismissRecommendation][google.ads.googleads.v19.services.RecommendationService.DismissRecommendation]. - customer_id (:class:`str`): - Required. The ID of the customer with - the recommendation. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.DismissRecommendationRequest.DismissRecommendationOperation]`): - Required. The list of operations to dismiss - recommendations. If partial_failure=false all - recommendations should be of the same type There is a - limit of 100 operations per request. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.DismissRecommendationResponse: - Response message for - [RecommendationService.DismissRecommendation][google.ads.googleads.v19.services.RecommendationService.DismissRecommendation]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, recommendation_service.DismissRecommendationRequest - ): - request = recommendation_service.DismissRecommendationRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.dismiss_recommendation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def generate_recommendations( - self, - request: Optional[ - Union[recommendation_service.GenerateRecommendationsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - recommendation_types: Optional[ - MutableSequence[ - recommendation_type.RecommendationTypeEnum.RecommendationType - ] - ] = None, - advertising_channel_type: Optional[ - gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> recommendation_service.GenerateRecommendationsResponse: - r"""Generates Recommendations based off the requested - recommendation_types. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ - `RecommendationError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateRecommendationsRequest, dict]]): - The request object. Request message for - [RecommendationService.GenerateRecommendations][google.ads.googleads.v19.services.RecommendationService.GenerateRecommendations]. - customer_id (:class:`str`): - Required. The ID of the customer - generating recommendations. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - recommendation_types (:class:`MutableSequence[google.ads.googleads.v19.enums.types.RecommendationTypeEnum.RecommendationType]`): - Required. List of eligible recommendation_types to - generate. If the uploaded criteria isn't sufficient to - make a recommendation, or the campaign is already in the - recommended state, no recommendation will be returned - for that type. Generally, a recommendation is returned - if all required fields for that recommendation_type are - uploaded, but there are cases where this is still not - sufficient. - - The following recommendation_types are supported for - recommendation generation: CAMPAIGN_BUDGET, KEYWORD, - MAXIMIZE_CLICKS_OPT_IN, MAXIMIZE_CONVERSIONS_OPT_IN, - MAXIMIZE_CONVERSION_VALUE_OPT_IN, SET_TARGET_CPA, - SET_TARGET_ROAS, SITELINK_ASSET, TARGET_CPA_OPT_IN, - TARGET_ROAS_OPT_IN - - This corresponds to the ``recommendation_types`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - advertising_channel_type (:class:`google.ads.googleads.v19.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType`): - Required. Advertising channel type of the campaign. The - following advertising_channel_types are supported for - recommendation generation: PERFORMANCE_MAX and SEARCH - - This corresponds to the ``advertising_channel_type`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateRecommendationsResponse: - Response message for - [RecommendationService.GenerateRecommendations][google.ads.googleads.v19.services.RecommendationService.GenerateRecommendations]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [ - customer_id, - recommendation_types, - advertising_channel_type, - ] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, recommendation_service.GenerateRecommendationsRequest - ): - request = recommendation_service.GenerateRecommendationsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if advertising_channel_type is not None: - request.advertising_channel_type = advertising_channel_type - if recommendation_types: - request.recommendation_types.extend(recommendation_types) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_recommendations - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "RecommendationServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("RecommendationServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/recommendation_service/client.py b/google/ads/googleads/v19/services/services/recommendation_service/client.py deleted file mode 100644 index 8a921d66f..000000000 --- a/google/ads/googleads/v19/services/services/recommendation_service/client.py +++ /dev/null @@ -1,1259 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.enums.types import ( - advertising_channel_type as gage_advertising_channel_type, -) -from google.ads.googleads.v19.enums.types import recommendation_type -from google.ads.googleads.v19.services.types import recommendation_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import RecommendationServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import RecommendationServiceGrpcTransport -from .transports.grpc_asyncio import RecommendationServiceGrpcAsyncIOTransport - - -class RecommendationServiceClientMeta(type): - """Metaclass for the RecommendationService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[RecommendationServiceTransport]] - _transport_registry["grpc"] = RecommendationServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - RecommendationServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[RecommendationServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class RecommendationServiceClient(metaclass=RecommendationServiceClientMeta): - """Service to manage recommendations.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RecommendationServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RecommendationServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> RecommendationServiceTransport: - """Returns the transport used by the client instance. - - Returns: - RecommendationServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def ad_path( - customer_id: str, - ad_id: str, - ) -> str: - """Returns a fully-qualified ad string.""" - return "customers/{customer_id}/ads/{ad_id}".format( - customer_id=customer_id, - ad_id=ad_id, - ) - - @staticmethod - def parse_ad_path(path: str) -> Dict[str, str]: - """Parses a ad path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/ads/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def ad_group_path( - customer_id: str, - ad_group_id: str, - ) -> str: - """Returns a fully-qualified ad_group string.""" - return "customers/{customer_id}/adGroups/{ad_group_id}".format( - customer_id=customer_id, - ad_group_id=ad_group_id, - ) - - @staticmethod - def parse_ad_group_path(path: str) -> Dict[str, str]: - """Parses a ad_group path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/adGroups/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def asset_path( - customer_id: str, - asset_id: str, - ) -> str: - """Returns a fully-qualified asset string.""" - return "customers/{customer_id}/assets/{asset_id}".format( - customer_id=customer_id, - asset_id=asset_id, - ) - - @staticmethod - def parse_asset_path(path: str) -> Dict[str, str]: - """Parses a asset path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/assets/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def campaign_budget_path( - customer_id: str, - campaign_budget_id: str, - ) -> str: - """Returns a fully-qualified campaign_budget string.""" - return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( - customer_id=customer_id, - campaign_budget_id=campaign_budget_id, - ) - - @staticmethod - def parse_campaign_budget_path(path: str) -> Dict[str, str]: - """Parses a campaign_budget path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def conversion_action_path( - customer_id: str, - conversion_action_id: str, - ) -> str: - """Returns a fully-qualified conversion_action string.""" - return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( - customer_id=customer_id, - conversion_action_id=conversion_action_id, - ) - - @staticmethod - def parse_conversion_action_path(path: str) -> Dict[str, str]: - """Parses a conversion_action path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/conversionActions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def recommendation_path( - customer_id: str, - recommendation_id: str, - ) -> str: - """Returns a fully-qualified recommendation string.""" - return "customers/{customer_id}/recommendations/{recommendation_id}".format( - customer_id=customer_id, - recommendation_id=recommendation_id, - ) - - @staticmethod - def parse_recommendation_path(path: str) -> Dict[str, str]: - """Parses a recommendation path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/recommendations/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = RecommendationServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = RecommendationServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - RecommendationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = RecommendationServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - RecommendationServiceTransport, - Callable[..., RecommendationServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the recommendation service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,RecommendationServiceTransport,Callable[..., RecommendationServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the RecommendationServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = RecommendationServiceClient._read_environment_variables() - self._client_cert_source = ( - RecommendationServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - RecommendationServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, RecommendationServiceTransport - ) - if transport_provided: - # transport is a RecommendationServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(RecommendationServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or RecommendationServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[RecommendationServiceTransport], - Callable[..., RecommendationServiceTransport], - ] = ( - RecommendationServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., RecommendationServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.RecommendationServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.RecommendationService", - "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.ads.googleads.v19.services.RecommendationService", - "credentialsType": None, - } - ), - ) - - def apply_recommendation( - self, - request: Optional[ - Union[recommendation_service.ApplyRecommendationRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[recommendation_service.ApplyRecommendationOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> recommendation_service.ApplyRecommendationResponse: - r"""Applies given recommendations with corresponding apply - parameters. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ - `UrlFieldError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.ApplyRecommendationRequest, dict]): - The request object. Request message for - [RecommendationService.ApplyRecommendation][google.ads.googleads.v19.services.RecommendationService.ApplyRecommendation]. - customer_id (str): - Required. The ID of the customer with - the recommendation. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.ApplyRecommendationOperation]): - Required. The list of operations to apply - recommendations. If partial_failure=false all - recommendations should be of the same type There is a - limit of 100 operations per request. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.ApplyRecommendationResponse: - Response message for - [RecommendationService.ApplyRecommendation][google.ads.googleads.v19.services.RecommendationService.ApplyRecommendation]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, recommendation_service.ApplyRecommendationRequest - ): - request = recommendation_service.ApplyRecommendationRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.apply_recommendation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def dismiss_recommendation( - self, - request: Optional[ - Union[recommendation_service.DismissRecommendationRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - recommendation_service.DismissRecommendationRequest.DismissRecommendationOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> recommendation_service.DismissRecommendationResponse: - r"""Dismisses given recommendations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ - `RecommendationError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.DismissRecommendationRequest, dict]): - The request object. Request message for - [RecommendationService.DismissRecommendation][google.ads.googleads.v19.services.RecommendationService.DismissRecommendation]. - customer_id (str): - Required. The ID of the customer with - the recommendation. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.DismissRecommendationRequest.DismissRecommendationOperation]): - Required. The list of operations to dismiss - recommendations. If partial_failure=false all - recommendations should be of the same type There is a - limit of 100 operations per request. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.DismissRecommendationResponse: - Response message for - [RecommendationService.DismissRecommendation][google.ads.googleads.v19.services.RecommendationService.DismissRecommendation]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, recommendation_service.DismissRecommendationRequest - ): - request = recommendation_service.DismissRecommendationRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.dismiss_recommendation - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def generate_recommendations( - self, - request: Optional[ - Union[recommendation_service.GenerateRecommendationsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - recommendation_types: Optional[ - MutableSequence[ - recommendation_type.RecommendationTypeEnum.RecommendationType - ] - ] = None, - advertising_channel_type: Optional[ - gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> recommendation_service.GenerateRecommendationsResponse: - r"""Generates Recommendations based off the requested - recommendation_types. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ - `RecommendationError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateRecommendationsRequest, dict]): - The request object. Request message for - [RecommendationService.GenerateRecommendations][google.ads.googleads.v19.services.RecommendationService.GenerateRecommendations]. - customer_id (str): - Required. The ID of the customer - generating recommendations. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - recommendation_types (MutableSequence[google.ads.googleads.v19.enums.types.RecommendationTypeEnum.RecommendationType]): - Required. List of eligible recommendation_types to - generate. If the uploaded criteria isn't sufficient to - make a recommendation, or the campaign is already in the - recommended state, no recommendation will be returned - for that type. Generally, a recommendation is returned - if all required fields for that recommendation_type are - uploaded, but there are cases where this is still not - sufficient. - - The following recommendation_types are supported for - recommendation generation: CAMPAIGN_BUDGET, KEYWORD, - MAXIMIZE_CLICKS_OPT_IN, MAXIMIZE_CONVERSIONS_OPT_IN, - MAXIMIZE_CONVERSION_VALUE_OPT_IN, SET_TARGET_CPA, - SET_TARGET_ROAS, SITELINK_ASSET, TARGET_CPA_OPT_IN, - TARGET_ROAS_OPT_IN - - This corresponds to the ``recommendation_types`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - advertising_channel_type (google.ads.googleads.v19.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): - Required. Advertising channel type of the campaign. The - following advertising_channel_types are supported for - recommendation generation: PERFORMANCE_MAX and SEARCH - - This corresponds to the ``advertising_channel_type`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateRecommendationsResponse: - Response message for - [RecommendationService.GenerateRecommendations][google.ads.googleads.v19.services.RecommendationService.GenerateRecommendations]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [ - customer_id, - recommendation_types, - advertising_channel_type, - ] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, recommendation_service.GenerateRecommendationsRequest - ): - request = recommendation_service.GenerateRecommendationsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if recommendation_types is not None: - request.recommendation_types = recommendation_types - if advertising_channel_type is not None: - request.advertising_channel_type = advertising_channel_type - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_recommendations - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "RecommendationServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("RecommendationServiceClient",) diff --git a/google/ads/googleads/v19/services/services/recommendation_service/transports/base.py b/google/ads/googleads/v19/services/services/recommendation_service/transports/base.py deleted file mode 100644 index f507efec9..000000000 --- a/google/ads/googleads/v19/services/services/recommendation_service/transports/base.py +++ /dev/null @@ -1,206 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import recommendation_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class RecommendationServiceTransport(abc.ABC): - """Abstract transport class for RecommendationService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.apply_recommendation: gapic_v1.method.wrap_method( - self.apply_recommendation, - default_timeout=None, - client_info=client_info, - ), - self.dismiss_recommendation: gapic_v1.method.wrap_method( - self.dismiss_recommendation, - default_timeout=None, - client_info=client_info, - ), - self.generate_recommendations: gapic_v1.method.wrap_method( - self.generate_recommendations, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def apply_recommendation( - self, - ) -> Callable[ - [recommendation_service.ApplyRecommendationRequest], - Union[ - recommendation_service.ApplyRecommendationResponse, - Awaitable[recommendation_service.ApplyRecommendationResponse], - ], - ]: - raise NotImplementedError() - - @property - def dismiss_recommendation( - self, - ) -> Callable[ - [recommendation_service.DismissRecommendationRequest], - Union[ - recommendation_service.DismissRecommendationResponse, - Awaitable[recommendation_service.DismissRecommendationResponse], - ], - ]: - raise NotImplementedError() - - @property - def generate_recommendations( - self, - ) -> Callable[ - [recommendation_service.GenerateRecommendationsRequest], - Union[ - recommendation_service.GenerateRecommendationsResponse, - Awaitable[recommendation_service.GenerateRecommendationsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("RecommendationServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/recommendation_service/transports/grpc.py b/google/ads/googleads/v19/services/services/recommendation_service/transports/grpc.py deleted file mode 100644 index 0a14b2144..000000000 --- a/google/ads/googleads/v19/services/services/recommendation_service/transports/grpc.py +++ /dev/null @@ -1,461 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import recommendation_service -from .base import RecommendationServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.RecommendationService", - "rpcName": str(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.ads.googleads.v19.services.RecommendationService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class RecommendationServiceGrpcTransport(RecommendationServiceTransport): - """gRPC backend transport for RecommendationService. - - Service to manage recommendations. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def apply_recommendation( - self, - ) -> Callable[ - [recommendation_service.ApplyRecommendationRequest], - recommendation_service.ApplyRecommendationResponse, - ]: - r"""Return a callable for the apply recommendation method over gRPC. - - Applies given recommendations with corresponding apply - parameters. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.ApplyRecommendationRequest], - ~.ApplyRecommendationResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "apply_recommendation" not in self._stubs: - self._stubs["apply_recommendation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.RecommendationService/ApplyRecommendation", - request_serializer=recommendation_service.ApplyRecommendationRequest.serialize, - response_deserializer=recommendation_service.ApplyRecommendationResponse.deserialize, - ) - ) - return self._stubs["apply_recommendation"] - - @property - def dismiss_recommendation( - self, - ) -> Callable[ - [recommendation_service.DismissRecommendationRequest], - recommendation_service.DismissRecommendationResponse, - ]: - r"""Return a callable for the dismiss recommendation method over gRPC. - - Dismisses given recommendations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ - `RecommendationError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.DismissRecommendationRequest], - ~.DismissRecommendationResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "dismiss_recommendation" not in self._stubs: - self._stubs["dismiss_recommendation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.RecommendationService/DismissRecommendation", - request_serializer=recommendation_service.DismissRecommendationRequest.serialize, - response_deserializer=recommendation_service.DismissRecommendationResponse.deserialize, - ) - ) - return self._stubs["dismiss_recommendation"] - - @property - def generate_recommendations( - self, - ) -> Callable[ - [recommendation_service.GenerateRecommendationsRequest], - recommendation_service.GenerateRecommendationsResponse, - ]: - r"""Return a callable for the generate recommendations method over gRPC. - - Generates Recommendations based off the requested - recommendation_types. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ - `RecommendationError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateRecommendationsRequest], - ~.GenerateRecommendationsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_recommendations" not in self._stubs: - self._stubs["generate_recommendations"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.RecommendationService/GenerateRecommendations", - request_serializer=recommendation_service.GenerateRecommendationsRequest.serialize, - response_deserializer=recommendation_service.GenerateRecommendationsResponse.deserialize, - ) - ) - return self._stubs["generate_recommendations"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("RecommendationServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/recommendation_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/recommendation_service/transports/grpc_asyncio.py deleted file mode 100644 index 507807c85..000000000 --- a/google/ads/googleads/v19/services/services/recommendation_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,492 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import recommendation_service -from .base import RecommendationServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.RecommendationService", - "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.ads.googleads.v19.services.RecommendationService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class RecommendationServiceGrpcAsyncIOTransport(RecommendationServiceTransport): - """gRPC AsyncIO backend transport for RecommendationService. - - Service to manage recommendations. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def apply_recommendation( - self, - ) -> Callable[ - [recommendation_service.ApplyRecommendationRequest], - Awaitable[recommendation_service.ApplyRecommendationResponse], - ]: - r"""Return a callable for the apply recommendation method over gRPC. - - Applies given recommendations with corresponding apply - parameters. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.ApplyRecommendationRequest], - Awaitable[~.ApplyRecommendationResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "apply_recommendation" not in self._stubs: - self._stubs["apply_recommendation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.RecommendationService/ApplyRecommendation", - request_serializer=recommendation_service.ApplyRecommendationRequest.serialize, - response_deserializer=recommendation_service.ApplyRecommendationResponse.deserialize, - ) - ) - return self._stubs["apply_recommendation"] - - @property - def dismiss_recommendation( - self, - ) -> Callable[ - [recommendation_service.DismissRecommendationRequest], - Awaitable[recommendation_service.DismissRecommendationResponse], - ]: - r"""Return a callable for the dismiss recommendation method over gRPC. - - Dismisses given recommendations. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ - `RecommendationError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.DismissRecommendationRequest], - Awaitable[~.DismissRecommendationResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "dismiss_recommendation" not in self._stubs: - self._stubs["dismiss_recommendation"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.RecommendationService/DismissRecommendation", - request_serializer=recommendation_service.DismissRecommendationRequest.serialize, - response_deserializer=recommendation_service.DismissRecommendationResponse.deserialize, - ) - ) - return self._stubs["dismiss_recommendation"] - - @property - def generate_recommendations( - self, - ) -> Callable[ - [recommendation_service.GenerateRecommendationsRequest], - Awaitable[recommendation_service.GenerateRecommendationsResponse], - ]: - r"""Return a callable for the generate recommendations method over gRPC. - - Generates Recommendations based off the requested - recommendation_types. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ - `RecommendationError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.GenerateRecommendationsRequest], - Awaitable[~.GenerateRecommendationsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_recommendations" not in self._stubs: - self._stubs["generate_recommendations"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.RecommendationService/GenerateRecommendations", - request_serializer=recommendation_service.GenerateRecommendationsRequest.serialize, - response_deserializer=recommendation_service.GenerateRecommendationsResponse.deserialize, - ) - ) - return self._stubs["generate_recommendations"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.apply_recommendation: self._wrap_method( - self.apply_recommendation, - default_timeout=None, - client_info=client_info, - ), - self.dismiss_recommendation: self._wrap_method( - self.dismiss_recommendation, - default_timeout=None, - client_info=client_info, - ), - self.generate_recommendations: self._wrap_method( - self.generate_recommendations, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("RecommendationServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/recommendation_subscription_service/async_client.py b/google/ads/googleads/v19/services/services/recommendation_subscription_service/async_client.py deleted file mode 100644 index 459e9caa8..000000000 --- a/google/ads/googleads/v19/services/services/recommendation_subscription_service/async_client.py +++ /dev/null @@ -1,446 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - recommendation_subscription_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - RecommendationSubscriptionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import RecommendationSubscriptionServiceClient - -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 RecommendationSubscriptionServiceAsyncClient: - """Service to manage recommendation subscriptions.""" - - _client: RecommendationSubscriptionServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = RecommendationSubscriptionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - RecommendationSubscriptionServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - RecommendationSubscriptionServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ( - RecommendationSubscriptionServiceClient._DEFAULT_UNIVERSE - ) - - recommendation_subscription_path = staticmethod( - RecommendationSubscriptionServiceClient.recommendation_subscription_path - ) - parse_recommendation_subscription_path = staticmethod( - RecommendationSubscriptionServiceClient.parse_recommendation_subscription_path - ) - common_billing_account_path = staticmethod( - RecommendationSubscriptionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - RecommendationSubscriptionServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - RecommendationSubscriptionServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - RecommendationSubscriptionServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - RecommendationSubscriptionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - RecommendationSubscriptionServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - RecommendationSubscriptionServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - RecommendationSubscriptionServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - RecommendationSubscriptionServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - RecommendationSubscriptionServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RecommendationSubscriptionServiceAsyncClient: The constructed client. - """ - return RecommendationSubscriptionServiceClient.from_service_account_info.__func__(RecommendationSubscriptionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RecommendationSubscriptionServiceAsyncClient: The constructed client. - """ - return RecommendationSubscriptionServiceClient.from_service_account_file.__func__(RecommendationSubscriptionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return RecommendationSubscriptionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> RecommendationSubscriptionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - RecommendationSubscriptionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - RecommendationSubscriptionServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - RecommendationSubscriptionServiceTransport, - Callable[..., RecommendationSubscriptionServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the recommendation subscription service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,RecommendationSubscriptionServiceTransport,Callable[..., RecommendationSubscriptionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the RecommendationSubscriptionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = RecommendationSubscriptionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.RecommendationSubscriptionServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.RecommendationSubscriptionService", - "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.ads.googleads.v19.services.RecommendationSubscriptionService", - "credentialsType": None, - } - ), - ) - - async def mutate_recommendation_subscription( - self, - request: Optional[ - Union[ - recommendation_subscription_service.MutateRecommendationSubscriptionRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - recommendation_subscription_service.RecommendationSubscriptionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - recommendation_subscription_service.MutateRecommendationSubscriptionResponse - ): - r"""Mutates given subscription with corresponding apply parameters. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ - `UrlFieldError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateRecommendationSubscriptionRequest, dict]]): - The request object. Request message for - [RecommendationSubscriptionService.MutateRecommendationSubscription] - customer_id (:class:`str`): - Required. The ID of the subscribing - customer. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.RecommendationSubscriptionOperation]`): - Required. The list of create or - update operations. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateRecommendationSubscriptionResponse: - Response message for - [RecommendationSubscriptionService.MutateRecommendationSubscription] - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - recommendation_subscription_service.MutateRecommendationSubscriptionRequest, - ): - request = recommendation_subscription_service.MutateRecommendationSubscriptionRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_recommendation_subscription - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__( - self, - ) -> "RecommendationSubscriptionServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("RecommendationSubscriptionServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/recommendation_subscription_service/client.py b/google/ads/googleads/v19/services/services/recommendation_subscription_service/client.py deleted file mode 100644 index 7f277c53b..000000000 --- a/google/ads/googleads/v19/services/services/recommendation_subscription_service/client.py +++ /dev/null @@ -1,909 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - recommendation_subscription_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - RecommendationSubscriptionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import RecommendationSubscriptionServiceGrpcTransport -from .transports.grpc_asyncio import ( - RecommendationSubscriptionServiceGrpcAsyncIOTransport, -) - - -class RecommendationSubscriptionServiceClientMeta(type): - """Metaclass for the RecommendationSubscriptionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[RecommendationSubscriptionServiceTransport]] - _transport_registry["grpc"] = RecommendationSubscriptionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - RecommendationSubscriptionServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[RecommendationSubscriptionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class RecommendationSubscriptionServiceClient( - metaclass=RecommendationSubscriptionServiceClientMeta -): - """Service to manage recommendation subscriptions.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RecommendationSubscriptionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RecommendationSubscriptionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> RecommendationSubscriptionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - RecommendationSubscriptionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def recommendation_subscription_path( - customer_id: str, - recommendation_type: str, - ) -> str: - """Returns a fully-qualified recommendation_subscription string.""" - return "customers/{customer_id}/recommendationSubscriptions/{recommendation_type}".format( - customer_id=customer_id, - recommendation_type=recommendation_type, - ) - - @staticmethod - def parse_recommendation_subscription_path(path: str) -> Dict[str, str]: - """Parses a recommendation_subscription path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/recommendationSubscriptions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - RecommendationSubscriptionServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - RecommendationSubscriptionServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = RecommendationSubscriptionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - RecommendationSubscriptionServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - RecommendationSubscriptionServiceTransport, - Callable[..., RecommendationSubscriptionServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the recommendation subscription service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,RecommendationSubscriptionServiceTransport,Callable[..., RecommendationSubscriptionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the RecommendationSubscriptionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ( - RecommendationSubscriptionServiceClient._read_environment_variables() - ) - self._client_cert_source = ( - RecommendationSubscriptionServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - RecommendationSubscriptionServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, RecommendationSubscriptionServiceTransport - ) - if transport_provided: - # transport is a RecommendationSubscriptionServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - RecommendationSubscriptionServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or RecommendationSubscriptionServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[RecommendationSubscriptionServiceTransport], - Callable[..., RecommendationSubscriptionServiceTransport], - ] = ( - RecommendationSubscriptionServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., RecommendationSubscriptionServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.RecommendationSubscriptionServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.RecommendationSubscriptionService", - "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.ads.googleads.v19.services.RecommendationSubscriptionService", - "credentialsType": None, - } - ), - ) - - def mutate_recommendation_subscription( - self, - request: Optional[ - Union[ - recommendation_subscription_service.MutateRecommendationSubscriptionRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - recommendation_subscription_service.RecommendationSubscriptionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - recommendation_subscription_service.MutateRecommendationSubscriptionResponse - ): - r"""Mutates given subscription with corresponding apply parameters. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ - `UrlFieldError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateRecommendationSubscriptionRequest, dict]): - The request object. Request message for - [RecommendationSubscriptionService.MutateRecommendationSubscription] - customer_id (str): - Required. The ID of the subscribing - customer. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.RecommendationSubscriptionOperation]): - Required. The list of create or - update operations. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateRecommendationSubscriptionResponse: - Response message for - [RecommendationSubscriptionService.MutateRecommendationSubscription] - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - recommendation_subscription_service.MutateRecommendationSubscriptionRequest, - ): - request = recommendation_subscription_service.MutateRecommendationSubscriptionRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_recommendation_subscription - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "RecommendationSubscriptionServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("RecommendationSubscriptionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/base.py b/google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/base.py deleted file mode 100644 index 9d550728b..000000000 --- a/google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - recommendation_subscription_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class RecommendationSubscriptionServiceTransport(abc.ABC): - """Abstract transport class for RecommendationSubscriptionService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_recommendation_subscription: gapic_v1.method.wrap_method( - self.mutate_recommendation_subscription, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_recommendation_subscription( - self, - ) -> Callable[ - [ - recommendation_subscription_service.MutateRecommendationSubscriptionRequest - ], - Union[ - recommendation_subscription_service.MutateRecommendationSubscriptionResponse, - Awaitable[ - recommendation_subscription_service.MutateRecommendationSubscriptionResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("RecommendationSubscriptionServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/grpc.py b/google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/grpc.py deleted file mode 100644 index aa81c3424..000000000 --- a/google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/grpc.py +++ /dev/null @@ -1,397 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - recommendation_subscription_service, -) -from .base import ( - RecommendationSubscriptionServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.RecommendationSubscriptionService", - "rpcName": str(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.ads.googleads.v19.services.RecommendationSubscriptionService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class RecommendationSubscriptionServiceGrpcTransport( - RecommendationSubscriptionServiceTransport -): - """gRPC backend transport for RecommendationSubscriptionService. - - Service to manage recommendation subscriptions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_recommendation_subscription( - self, - ) -> Callable[ - [ - recommendation_subscription_service.MutateRecommendationSubscriptionRequest - ], - recommendation_subscription_service.MutateRecommendationSubscriptionResponse, - ]: - r"""Return a callable for the mutate recommendation - subscription method over gRPC. - - Mutates given subscription with corresponding apply parameters. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateRecommendationSubscriptionRequest], - ~.MutateRecommendationSubscriptionResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_recommendation_subscription" not in self._stubs: - self._stubs["mutate_recommendation_subscription"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.RecommendationSubscriptionService/MutateRecommendationSubscription", - request_serializer=recommendation_subscription_service.MutateRecommendationSubscriptionRequest.serialize, - response_deserializer=recommendation_subscription_service.MutateRecommendationSubscriptionResponse.deserialize, - ) - ) - return self._stubs["mutate_recommendation_subscription"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("RecommendationSubscriptionServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/grpc_asyncio.py deleted file mode 100644 index aa6367bdc..000000000 --- a/google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,420 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - recommendation_subscription_service, -) -from .base import ( - RecommendationSubscriptionServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.RecommendationSubscriptionService", - "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.ads.googleads.v19.services.RecommendationSubscriptionService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class RecommendationSubscriptionServiceGrpcAsyncIOTransport( - RecommendationSubscriptionServiceTransport -): - """gRPC AsyncIO backend transport for RecommendationSubscriptionService. - - Service to manage recommendation subscriptions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_recommendation_subscription( - self, - ) -> Callable[ - [ - recommendation_subscription_service.MutateRecommendationSubscriptionRequest - ], - Awaitable[ - recommendation_subscription_service.MutateRecommendationSubscriptionResponse - ], - ]: - r"""Return a callable for the mutate recommendation - subscription method over gRPC. - - Mutates given subscription with corresponding apply parameters. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ - `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ - `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ - `UrlFieldError <>`__ - - Returns: - Callable[[~.MutateRecommendationSubscriptionRequest], - Awaitable[~.MutateRecommendationSubscriptionResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_recommendation_subscription" not in self._stubs: - self._stubs["mutate_recommendation_subscription"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.RecommendationSubscriptionService/MutateRecommendationSubscription", - request_serializer=recommendation_subscription_service.MutateRecommendationSubscriptionRequest.serialize, - response_deserializer=recommendation_subscription_service.MutateRecommendationSubscriptionResponse.deserialize, - ) - ) - return self._stubs["mutate_recommendation_subscription"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_recommendation_subscription: self._wrap_method( - self.mutate_recommendation_subscription, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("RecommendationSubscriptionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/remarketing_action_service/async_client.py b/google/ads/googleads/v19/services/services/remarketing_action_service/async_client.py deleted file mode 100644 index 9424bb7c4..000000000 --- a/google/ads/googleads/v19/services/services/remarketing_action_service/async_client.py +++ /dev/null @@ -1,436 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import remarketing_action_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - RemarketingActionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import RemarketingActionServiceClient - -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 RemarketingActionServiceAsyncClient: - """Service to manage remarketing actions.""" - - _client: RemarketingActionServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = RemarketingActionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = RemarketingActionServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - RemarketingActionServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = RemarketingActionServiceClient._DEFAULT_UNIVERSE - - remarketing_action_path = staticmethod( - RemarketingActionServiceClient.remarketing_action_path - ) - parse_remarketing_action_path = staticmethod( - RemarketingActionServiceClient.parse_remarketing_action_path - ) - common_billing_account_path = staticmethod( - RemarketingActionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - RemarketingActionServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - RemarketingActionServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - RemarketingActionServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - RemarketingActionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - RemarketingActionServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - RemarketingActionServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - RemarketingActionServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - RemarketingActionServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - RemarketingActionServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RemarketingActionServiceAsyncClient: The constructed client. - """ - return RemarketingActionServiceClient.from_service_account_info.__func__(RemarketingActionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RemarketingActionServiceAsyncClient: The constructed client. - """ - return RemarketingActionServiceClient.from_service_account_file.__func__(RemarketingActionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return RemarketingActionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> RemarketingActionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - RemarketingActionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = RemarketingActionServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - RemarketingActionServiceTransport, - Callable[..., RemarketingActionServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the remarketing action service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,RemarketingActionServiceTransport,Callable[..., RemarketingActionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the RemarketingActionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = RemarketingActionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.RemarketingActionServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.RemarketingActionService", - "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.ads.googleads.v19.services.RemarketingActionService", - "credentialsType": None, - } - ), - ) - - async def mutate_remarketing_actions( - self, - request: Optional[ - Union[ - remarketing_action_service.MutateRemarketingActionsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - remarketing_action_service.RemarketingActionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> remarketing_action_service.MutateRemarketingActionsResponse: - r"""Creates or updates remarketing actions. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionActionError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateRemarketingActionsRequest, dict]]): - The request object. Request message for - [RemarketingActionService.MutateRemarketingActions][google.ads.googleads.v19.services.RemarketingActionService.MutateRemarketingActions]. - customer_id (:class:`str`): - Required. The ID of the customer - whose remarketing actions are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.RemarketingActionOperation]`): - Required. The list of operations to - perform on individual remarketing - actions. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateRemarketingActionsResponse: - Response message for remarketing - action mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, remarketing_action_service.MutateRemarketingActionsRequest - ): - request = ( - remarketing_action_service.MutateRemarketingActionsRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_remarketing_actions - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "RemarketingActionServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("RemarketingActionServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/remarketing_action_service/client.py b/google/ads/googleads/v19/services/services/remarketing_action_service/client.py deleted file mode 100644 index b39444c84..000000000 --- a/google/ads/googleads/v19/services/services/remarketing_action_service/client.py +++ /dev/null @@ -1,894 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import remarketing_action_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - RemarketingActionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import RemarketingActionServiceGrpcTransport -from .transports.grpc_asyncio import ( - RemarketingActionServiceGrpcAsyncIOTransport, -) - - -class RemarketingActionServiceClientMeta(type): - """Metaclass for the RemarketingActionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[RemarketingActionServiceTransport]] - _transport_registry["grpc"] = RemarketingActionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - RemarketingActionServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[RemarketingActionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class RemarketingActionServiceClient( - metaclass=RemarketingActionServiceClientMeta -): - """Service to manage remarketing actions.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RemarketingActionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - RemarketingActionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> RemarketingActionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - RemarketingActionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def remarketing_action_path( - customer_id: str, - remarketing_action_id: str, - ) -> str: - """Returns a fully-qualified remarketing_action string.""" - return "customers/{customer_id}/remarketingActions/{remarketing_action_id}".format( - customer_id=customer_id, - remarketing_action_id=remarketing_action_id, - ) - - @staticmethod - def parse_remarketing_action_path(path: str) -> Dict[str, str]: - """Parses a remarketing_action path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/remarketingActions/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = RemarketingActionServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = RemarketingActionServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = RemarketingActionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = RemarketingActionServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - RemarketingActionServiceTransport, - Callable[..., RemarketingActionServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the remarketing action service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,RemarketingActionServiceTransport,Callable[..., RemarketingActionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the RemarketingActionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = RemarketingActionServiceClient._read_environment_variables() - self._client_cert_source = ( - RemarketingActionServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - RemarketingActionServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, RemarketingActionServiceTransport - ) - if transport_provided: - # transport is a RemarketingActionServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(RemarketingActionServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or RemarketingActionServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[RemarketingActionServiceTransport], - Callable[..., RemarketingActionServiceTransport], - ] = ( - RemarketingActionServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., RemarketingActionServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.RemarketingActionServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.RemarketingActionService", - "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.ads.googleads.v19.services.RemarketingActionService", - "credentialsType": None, - } - ), - ) - - def mutate_remarketing_actions( - self, - request: Optional[ - Union[ - remarketing_action_service.MutateRemarketingActionsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - remarketing_action_service.RemarketingActionOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> remarketing_action_service.MutateRemarketingActionsResponse: - r"""Creates or updates remarketing actions. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionActionError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateRemarketingActionsRequest, dict]): - The request object. Request message for - [RemarketingActionService.MutateRemarketingActions][google.ads.googleads.v19.services.RemarketingActionService.MutateRemarketingActions]. - customer_id (str): - Required. The ID of the customer - whose remarketing actions are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.RemarketingActionOperation]): - Required. The list of operations to - perform on individual remarketing - actions. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateRemarketingActionsResponse: - Response message for remarketing - action mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, remarketing_action_service.MutateRemarketingActionsRequest - ): - request = ( - remarketing_action_service.MutateRemarketingActionsRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_remarketing_actions - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "RemarketingActionServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("RemarketingActionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/remarketing_action_service/transports/base.py b/google/ads/googleads/v19/services/services/remarketing_action_service/transports/base.py deleted file mode 100644 index eb39551af..000000000 --- a/google/ads/googleads/v19/services/services/remarketing_action_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import remarketing_action_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class RemarketingActionServiceTransport(abc.ABC): - """Abstract transport class for RemarketingActionService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_remarketing_actions: gapic_v1.method.wrap_method( - self.mutate_remarketing_actions, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_remarketing_actions( - self, - ) -> Callable[ - [remarketing_action_service.MutateRemarketingActionsRequest], - Union[ - remarketing_action_service.MutateRemarketingActionsResponse, - Awaitable[ - remarketing_action_service.MutateRemarketingActionsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("RemarketingActionServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/remarketing_action_service/transports/grpc.py b/google/ads/googleads/v19/services/services/remarketing_action_service/transports/grpc.py deleted file mode 100644 index 9c2981ef1..000000000 --- a/google/ads/googleads/v19/services/services/remarketing_action_service/transports/grpc.py +++ /dev/null @@ -1,387 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import remarketing_action_service -from .base import RemarketingActionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.RemarketingActionService", - "rpcName": str(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.ads.googleads.v19.services.RemarketingActionService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class RemarketingActionServiceGrpcTransport(RemarketingActionServiceTransport): - """gRPC backend transport for RemarketingActionService. - - Service to manage remarketing actions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_remarketing_actions( - self, - ) -> Callable[ - [remarketing_action_service.MutateRemarketingActionsRequest], - remarketing_action_service.MutateRemarketingActionsResponse, - ]: - r"""Return a callable for the mutate remarketing actions method over gRPC. - - Creates or updates remarketing actions. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionActionError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateRemarketingActionsRequest], - ~.MutateRemarketingActionsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_remarketing_actions" not in self._stubs: - self._stubs["mutate_remarketing_actions"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.RemarketingActionService/MutateRemarketingActions", - request_serializer=remarketing_action_service.MutateRemarketingActionsRequest.serialize, - response_deserializer=remarketing_action_service.MutateRemarketingActionsResponse.deserialize, - ) - ) - return self._stubs["mutate_remarketing_actions"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("RemarketingActionServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/remarketing_action_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/remarketing_action_service/transports/grpc_asyncio.py deleted file mode 100644 index caacce0fe..000000000 --- a/google/ads/googleads/v19/services/services/remarketing_action_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,410 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import remarketing_action_service -from .base import RemarketingActionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.RemarketingActionService", - "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.ads.googleads.v19.services.RemarketingActionService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class RemarketingActionServiceGrpcAsyncIOTransport( - RemarketingActionServiceTransport -): - """gRPC AsyncIO backend transport for RemarketingActionService. - - Service to manage remarketing actions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_remarketing_actions( - self, - ) -> Callable[ - [remarketing_action_service.MutateRemarketingActionsRequest], - Awaitable[remarketing_action_service.MutateRemarketingActionsResponse], - ]: - r"""Return a callable for the mutate remarketing actions method over gRPC. - - Creates or updates remarketing actions. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `ConversionActionError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateRemarketingActionsRequest], - Awaitable[~.MutateRemarketingActionsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_remarketing_actions" not in self._stubs: - self._stubs["mutate_remarketing_actions"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.RemarketingActionService/MutateRemarketingActions", - request_serializer=remarketing_action_service.MutateRemarketingActionsRequest.serialize, - response_deserializer=remarketing_action_service.MutateRemarketingActionsResponse.deserialize, - ) - ) - return self._stubs["mutate_remarketing_actions"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_remarketing_actions: self._wrap_method( - self.mutate_remarketing_actions, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("RemarketingActionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/shareable_preview_service/async_client.py b/google/ads/googleads/v19/services/services/shareable_preview_service/async_client.py deleted file mode 100644 index 741b8395b..000000000 --- a/google/ads/googleads/v19/services/services/shareable_preview_service/async_client.py +++ /dev/null @@ -1,419 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import shareable_preview_service -from .transports.base import ( - ShareablePreviewServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import ShareablePreviewServiceClient - -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 ShareablePreviewServiceAsyncClient: - """Service to generate Shareable Previews.""" - - _client: ShareablePreviewServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ShareablePreviewServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ShareablePreviewServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - ShareablePreviewServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ShareablePreviewServiceClient._DEFAULT_UNIVERSE - - common_billing_account_path = staticmethod( - ShareablePreviewServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ShareablePreviewServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ShareablePreviewServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ShareablePreviewServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ShareablePreviewServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ShareablePreviewServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ShareablePreviewServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ShareablePreviewServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ShareablePreviewServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ShareablePreviewServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ShareablePreviewServiceAsyncClient: The constructed client. - """ - return ShareablePreviewServiceClient.from_service_account_info.__func__(ShareablePreviewServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ShareablePreviewServiceAsyncClient: The constructed client. - """ - return ShareablePreviewServiceClient.from_service_account_file.__func__(ShareablePreviewServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ShareablePreviewServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ShareablePreviewServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ShareablePreviewServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ShareablePreviewServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ShareablePreviewServiceTransport, - Callable[..., ShareablePreviewServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the shareable preview service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ShareablePreviewServiceTransport,Callable[..., ShareablePreviewServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ShareablePreviewServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ShareablePreviewServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ShareablePreviewServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ShareablePreviewService", - "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.ads.googleads.v19.services.ShareablePreviewService", - "credentialsType": None, - } - ), - ) - - async def generate_shareable_previews( - self, - request: Optional[ - Union[ - shareable_preview_service.GenerateShareablePreviewsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - shareable_previews: Optional[ - MutableSequence[shareable_preview_service.ShareablePreview] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> shareable_preview_service.GenerateShareablePreviewsResponse: - r"""Returns the requested Shareable Preview. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GenerateShareablePreviewsRequest, dict]]): - The request object. Request message for - [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v19.services.ShareablePreviewService.GenerateShareablePreviews]. - customer_id (:class:`str`): - Required. The customer creating the - shareable previews request. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - shareable_previews (:class:`MutableSequence[google.ads.googleads.v19.services.types.ShareablePreview]`): - Required. The list of shareable - previews to generate. - - This corresponds to the ``shareable_previews`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateShareablePreviewsResponse: - Response message for - [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v19.services.ShareablePreviewService.GenerateShareablePreviews]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, shareable_previews] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, shareable_preview_service.GenerateShareablePreviewsRequest - ): - request = ( - shareable_preview_service.GenerateShareablePreviewsRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if shareable_previews: - request.shareable_previews.extend(shareable_previews) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.generate_shareable_previews - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "ShareablePreviewServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ShareablePreviewServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/shareable_preview_service/client.py b/google/ads/googleads/v19/services/services/shareable_preview_service/client.py deleted file mode 100644 index e9f6f2000..000000000 --- a/google/ads/googleads/v19/services/services/shareable_preview_service/client.py +++ /dev/null @@ -1,863 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import shareable_preview_service -from .transports.base import ( - ShareablePreviewServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ShareablePreviewServiceGrpcTransport -from .transports.grpc_asyncio import ShareablePreviewServiceGrpcAsyncIOTransport - - -class ShareablePreviewServiceClientMeta(type): - """Metaclass for the ShareablePreviewService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ShareablePreviewServiceTransport]] - _transport_registry["grpc"] = ShareablePreviewServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - ShareablePreviewServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ShareablePreviewServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ShareablePreviewServiceClient( - metaclass=ShareablePreviewServiceClientMeta -): - """Service to generate Shareable Previews.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ShareablePreviewServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ShareablePreviewServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ShareablePreviewServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ShareablePreviewServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ShareablePreviewServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ShareablePreviewServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - ShareablePreviewServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ShareablePreviewServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ShareablePreviewServiceTransport, - Callable[..., ShareablePreviewServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the shareable preview service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ShareablePreviewServiceTransport,Callable[..., ShareablePreviewServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ShareablePreviewServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ShareablePreviewServiceClient._read_environment_variables() - self._client_cert_source = ( - ShareablePreviewServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - ShareablePreviewServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ShareablePreviewServiceTransport - ) - if transport_provided: - # transport is a ShareablePreviewServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(ShareablePreviewServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ShareablePreviewServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ShareablePreviewServiceTransport], - Callable[..., ShareablePreviewServiceTransport], - ] = ( - ShareablePreviewServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ShareablePreviewServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ShareablePreviewServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ShareablePreviewService", - "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.ads.googleads.v19.services.ShareablePreviewService", - "credentialsType": None, - } - ), - ) - - def generate_shareable_previews( - self, - request: Optional[ - Union[ - shareable_preview_service.GenerateShareablePreviewsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - shareable_previews: Optional[ - MutableSequence[shareable_preview_service.ShareablePreview] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> shareable_preview_service.GenerateShareablePreviewsResponse: - r"""Returns the requested Shareable Preview. - - Args: - request (Union[google.ads.googleads.v19.services.types.GenerateShareablePreviewsRequest, dict]): - The request object. Request message for - [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v19.services.ShareablePreviewService.GenerateShareablePreviews]. - customer_id (str): - Required. The customer creating the - shareable previews request. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - shareable_previews (MutableSequence[google.ads.googleads.v19.services.types.ShareablePreview]): - Required. The list of shareable - previews to generate. - - This corresponds to the ``shareable_previews`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GenerateShareablePreviewsResponse: - Response message for - [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v19.services.ShareablePreviewService.GenerateShareablePreviews]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, shareable_previews] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, shareable_preview_service.GenerateShareablePreviewsRequest - ): - request = ( - shareable_preview_service.GenerateShareablePreviewsRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if shareable_previews is not None: - request.shareable_previews = shareable_previews - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.generate_shareable_previews - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ShareablePreviewServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ShareablePreviewServiceClient",) diff --git a/google/ads/googleads/v19/services/services/shareable_preview_service/transports/base.py b/google/ads/googleads/v19/services/services/shareable_preview_service/transports/base.py deleted file mode 100644 index 98248a8fe..000000000 --- a/google/ads/googleads/v19/services/services/shareable_preview_service/transports/base.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import shareable_preview_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ShareablePreviewServiceTransport(abc.ABC): - """Abstract transport class for ShareablePreviewService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.generate_shareable_previews: gapic_v1.method.wrap_method( - self.generate_shareable_previews, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def generate_shareable_previews( - self, - ) -> Callable[ - [shareable_preview_service.GenerateShareablePreviewsRequest], - Union[ - shareable_preview_service.GenerateShareablePreviewsResponse, - Awaitable[ - shareable_preview_service.GenerateShareablePreviewsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ShareablePreviewServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/shareable_preview_service/transports/grpc.py b/google/ads/googleads/v19/services/services/shareable_preview_service/transports/grpc.py deleted file mode 100644 index 6da6c28e3..000000000 --- a/google/ads/googleads/v19/services/services/shareable_preview_service/transports/grpc.py +++ /dev/null @@ -1,381 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import shareable_preview_service -from .base import ShareablePreviewServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ShareablePreviewService", - "rpcName": str(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.ads.googleads.v19.services.ShareablePreviewService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ShareablePreviewServiceGrpcTransport(ShareablePreviewServiceTransport): - """gRPC backend transport for ShareablePreviewService. - - Service to generate Shareable Previews. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def generate_shareable_previews( - self, - ) -> Callable[ - [shareable_preview_service.GenerateShareablePreviewsRequest], - shareable_preview_service.GenerateShareablePreviewsResponse, - ]: - r"""Return a callable for the generate shareable previews method over gRPC. - - Returns the requested Shareable Preview. - - Returns: - Callable[[~.GenerateShareablePreviewsRequest], - ~.GenerateShareablePreviewsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_shareable_previews" not in self._stubs: - self._stubs["generate_shareable_previews"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ShareablePreviewService/GenerateShareablePreviews", - request_serializer=shareable_preview_service.GenerateShareablePreviewsRequest.serialize, - response_deserializer=shareable_preview_service.GenerateShareablePreviewsResponse.deserialize, - ) - ) - return self._stubs["generate_shareable_previews"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ShareablePreviewServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/shareable_preview_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/shareable_preview_service/transports/grpc_asyncio.py deleted file mode 100644 index d24f30f2e..000000000 --- a/google/ads/googleads/v19/services/services/shareable_preview_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,404 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import shareable_preview_service -from .base import ShareablePreviewServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ShareablePreviewService", - "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.ads.googleads.v19.services.ShareablePreviewService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ShareablePreviewServiceGrpcAsyncIOTransport( - ShareablePreviewServiceTransport -): - """gRPC AsyncIO backend transport for ShareablePreviewService. - - Service to generate Shareable Previews. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def generate_shareable_previews( - self, - ) -> Callable[ - [shareable_preview_service.GenerateShareablePreviewsRequest], - Awaitable[shareable_preview_service.GenerateShareablePreviewsResponse], - ]: - r"""Return a callable for the generate shareable previews method over gRPC. - - Returns the requested Shareable Preview. - - Returns: - Callable[[~.GenerateShareablePreviewsRequest], - Awaitable[~.GenerateShareablePreviewsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "generate_shareable_previews" not in self._stubs: - self._stubs["generate_shareable_previews"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ShareablePreviewService/GenerateShareablePreviews", - request_serializer=shareable_preview_service.GenerateShareablePreviewsRequest.serialize, - response_deserializer=shareable_preview_service.GenerateShareablePreviewsResponse.deserialize, - ) - ) - return self._stubs["generate_shareable_previews"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.generate_shareable_previews: self._wrap_method( - self.generate_shareable_previews, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ShareablePreviewServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/shared_criterion_service/async_client.py b/google/ads/googleads/v19/services/services/shared_criterion_service/async_client.py deleted file mode 100644 index 0a59b43cf..000000000 --- a/google/ads/googleads/v19/services/services/shared_criterion_service/async_client.py +++ /dev/null @@ -1,444 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import shared_criterion_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - SharedCriterionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import SharedCriterionServiceClient - -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 SharedCriterionServiceAsyncClient: - """Service to manage shared criteria.""" - - _client: SharedCriterionServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = SharedCriterionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = SharedCriterionServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - SharedCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = SharedCriterionServiceClient._DEFAULT_UNIVERSE - - mobile_app_category_constant_path = staticmethod( - SharedCriterionServiceClient.mobile_app_category_constant_path - ) - parse_mobile_app_category_constant_path = staticmethod( - SharedCriterionServiceClient.parse_mobile_app_category_constant_path - ) - shared_criterion_path = staticmethod( - SharedCriterionServiceClient.shared_criterion_path - ) - parse_shared_criterion_path = staticmethod( - SharedCriterionServiceClient.parse_shared_criterion_path - ) - shared_set_path = staticmethod(SharedCriterionServiceClient.shared_set_path) - parse_shared_set_path = staticmethod( - SharedCriterionServiceClient.parse_shared_set_path - ) - common_billing_account_path = staticmethod( - SharedCriterionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - SharedCriterionServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - SharedCriterionServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - SharedCriterionServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - SharedCriterionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - SharedCriterionServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - SharedCriterionServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - SharedCriterionServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - SharedCriterionServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - SharedCriterionServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SharedCriterionServiceAsyncClient: The constructed client. - """ - return SharedCriterionServiceClient.from_service_account_info.__func__(SharedCriterionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SharedCriterionServiceAsyncClient: The constructed client. - """ - return SharedCriterionServiceClient.from_service_account_file.__func__(SharedCriterionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return SharedCriterionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> SharedCriterionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SharedCriterionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = SharedCriterionServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - SharedCriterionServiceTransport, - Callable[..., SharedCriterionServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the shared criterion service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,SharedCriterionServiceTransport,Callable[..., SharedCriterionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the SharedCriterionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = SharedCriterionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.SharedCriterionServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.SharedCriterionService", - "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.ads.googleads.v19.services.SharedCriterionService", - "credentialsType": None, - } - ), - ) - - async def mutate_shared_criteria( - self, - request: Optional[ - Union[shared_criterion_service.MutateSharedCriteriaRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[shared_criterion_service.SharedCriterionOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> shared_criterion_service.MutateSharedCriteriaResponse: - r"""Creates or removes shared criteria. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateSharedCriteriaRequest, dict]]): - The request object. Request message for - [SharedCriterionService.MutateSharedCriteria][google.ads.googleads.v19.services.SharedCriterionService.MutateSharedCriteria]. - customer_id (:class:`str`): - Required. The ID of the customer - whose shared criteria are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.SharedCriterionOperation]`): - Required. The list of operations to - perform on individual shared criteria. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateSharedCriteriaResponse: - Response message for a shared - criterion mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, shared_criterion_service.MutateSharedCriteriaRequest - ): - request = shared_criterion_service.MutateSharedCriteriaRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_shared_criteria - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "SharedCriterionServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("SharedCriterionServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/shared_criterion_service/client.py b/google/ads/googleads/v19/services/services/shared_criterion_service/client.py deleted file mode 100644 index 3f529bc23..000000000 --- a/google/ads/googleads/v19/services/services/shared_criterion_service/client.py +++ /dev/null @@ -1,930 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import shared_criterion_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - SharedCriterionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import SharedCriterionServiceGrpcTransport -from .transports.grpc_asyncio import SharedCriterionServiceGrpcAsyncIOTransport - - -class SharedCriterionServiceClientMeta(type): - """Metaclass for the SharedCriterionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[SharedCriterionServiceTransport]] - _transport_registry["grpc"] = SharedCriterionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - SharedCriterionServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[SharedCriterionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class SharedCriterionServiceClient(metaclass=SharedCriterionServiceClientMeta): - """Service to manage shared criteria.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SharedCriterionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SharedCriterionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> SharedCriterionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SharedCriterionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def mobile_app_category_constant_path( - mobile_app_category_id: str, - ) -> str: - """Returns a fully-qualified mobile_app_category_constant string.""" - return "mobileAppCategoryConstants/{mobile_app_category_id}".format( - mobile_app_category_id=mobile_app_category_id, - ) - - @staticmethod - def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: - """Parses a mobile_app_category_constant path into its component segments.""" - m = re.match( - r"^mobileAppCategoryConstants/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def shared_criterion_path( - customer_id: str, - shared_set_id: str, - criterion_id: str, - ) -> str: - """Returns a fully-qualified shared_criterion string.""" - return "customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}".format( - customer_id=customer_id, - shared_set_id=shared_set_id, - criterion_id=criterion_id, - ) - - @staticmethod - def parse_shared_criterion_path(path: str) -> Dict[str, str]: - """Parses a shared_criterion path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/sharedCriteria/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def shared_set_path( - customer_id: str, - shared_set_id: str, - ) -> str: - """Returns a fully-qualified shared_set string.""" - return "customers/{customer_id}/sharedSets/{shared_set_id}".format( - customer_id=customer_id, - shared_set_id=shared_set_id, - ) - - @staticmethod - def parse_shared_set_path(path: str) -> Dict[str, str]: - """Parses a shared_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/sharedSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = SharedCriterionServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = SharedCriterionServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - SharedCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = SharedCriterionServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - SharedCriterionServiceTransport, - Callable[..., SharedCriterionServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the shared criterion service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,SharedCriterionServiceTransport,Callable[..., SharedCriterionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the SharedCriterionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = SharedCriterionServiceClient._read_environment_variables() - self._client_cert_source = ( - SharedCriterionServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - SharedCriterionServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, SharedCriterionServiceTransport - ) - if transport_provided: - # transport is a SharedCriterionServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(SharedCriterionServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or SharedCriterionServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[SharedCriterionServiceTransport], - Callable[..., SharedCriterionServiceTransport], - ] = ( - SharedCriterionServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., SharedCriterionServiceTransport], transport - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.SharedCriterionServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.SharedCriterionService", - "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.ads.googleads.v19.services.SharedCriterionService", - "credentialsType": None, - } - ), - ) - - def mutate_shared_criteria( - self, - request: Optional[ - Union[shared_criterion_service.MutateSharedCriteriaRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[shared_criterion_service.SharedCriterionOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> shared_criterion_service.MutateSharedCriteriaResponse: - r"""Creates or removes shared criteria. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateSharedCriteriaRequest, dict]): - The request object. Request message for - [SharedCriterionService.MutateSharedCriteria][google.ads.googleads.v19.services.SharedCriterionService.MutateSharedCriteria]. - customer_id (str): - Required. The ID of the customer - whose shared criteria are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.SharedCriterionOperation]): - Required. The list of operations to - perform on individual shared criteria. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateSharedCriteriaResponse: - Response message for a shared - criterion mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, shared_criterion_service.MutateSharedCriteriaRequest - ): - request = shared_criterion_service.MutateSharedCriteriaRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_shared_criteria - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "SharedCriterionServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("SharedCriterionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/shared_criterion_service/transports/base.py b/google/ads/googleads/v19/services/services/shared_criterion_service/transports/base.py deleted file mode 100644 index a09497c06..000000000 --- a/google/ads/googleads/v19/services/services/shared_criterion_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import shared_criterion_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class SharedCriterionServiceTransport(abc.ABC): - """Abstract transport class for SharedCriterionService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_shared_criteria: gapic_v1.method.wrap_method( - self.mutate_shared_criteria, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_shared_criteria( - self, - ) -> Callable[ - [shared_criterion_service.MutateSharedCriteriaRequest], - Union[ - shared_criterion_service.MutateSharedCriteriaResponse, - Awaitable[shared_criterion_service.MutateSharedCriteriaResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("SharedCriterionServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/shared_criterion_service/transports/grpc.py b/google/ads/googleads/v19/services/services/shared_criterion_service/transports/grpc.py deleted file mode 100644 index 4da04a5de..000000000 --- a/google/ads/googleads/v19/services/services/shared_criterion_service/transports/grpc.py +++ /dev/null @@ -1,392 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import shared_criterion_service -from .base import SharedCriterionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.SharedCriterionService", - "rpcName": str(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.ads.googleads.v19.services.SharedCriterionService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class SharedCriterionServiceGrpcTransport(SharedCriterionServiceTransport): - """gRPC backend transport for SharedCriterionService. - - Service to manage shared criteria. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_shared_criteria( - self, - ) -> Callable[ - [shared_criterion_service.MutateSharedCriteriaRequest], - shared_criterion_service.MutateSharedCriteriaResponse, - ]: - r"""Return a callable for the mutate shared criteria method over gRPC. - - Creates or removes shared criteria. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Returns: - Callable[[~.MutateSharedCriteriaRequest], - ~.MutateSharedCriteriaResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_shared_criteria" not in self._stubs: - self._stubs["mutate_shared_criteria"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SharedCriterionService/MutateSharedCriteria", - request_serializer=shared_criterion_service.MutateSharedCriteriaRequest.serialize, - response_deserializer=shared_criterion_service.MutateSharedCriteriaResponse.deserialize, - ) - ) - return self._stubs["mutate_shared_criteria"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("SharedCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/shared_criterion_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/shared_criterion_service/transports/grpc_asyncio.py deleted file mode 100644 index 186e5805e..000000000 --- a/google/ads/googleads/v19/services/services/shared_criterion_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,415 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import shared_criterion_service -from .base import SharedCriterionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.SharedCriterionService", - "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.ads.googleads.v19.services.SharedCriterionService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class SharedCriterionServiceGrpcAsyncIOTransport( - SharedCriterionServiceTransport -): - """gRPC AsyncIO backend transport for SharedCriterionService. - - Service to manage shared criteria. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_shared_criteria( - self, - ) -> Callable[ - [shared_criterion_service.MutateSharedCriteriaRequest], - Awaitable[shared_criterion_service.MutateSharedCriteriaResponse], - ]: - r"""Return a callable for the mutate shared criteria method over gRPC. - - Creates or removes shared criteria. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CriterionError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ - `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ - `RequestError <>`__ `ResourceCountLimitExceededError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Returns: - Callable[[~.MutateSharedCriteriaRequest], - Awaitable[~.MutateSharedCriteriaResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_shared_criteria" not in self._stubs: - self._stubs["mutate_shared_criteria"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SharedCriterionService/MutateSharedCriteria", - request_serializer=shared_criterion_service.MutateSharedCriteriaRequest.serialize, - response_deserializer=shared_criterion_service.MutateSharedCriteriaResponse.deserialize, - ) - ) - return self._stubs["mutate_shared_criteria"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_shared_criteria: self._wrap_method( - self.mutate_shared_criteria, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("SharedCriterionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/shared_set_service/async_client.py b/google/ads/googleads/v19/services/services/shared_set_service/async_client.py deleted file mode 100644 index ede4dcc6f..000000000 --- a/google/ads/googleads/v19/services/services/shared_set_service/async_client.py +++ /dev/null @@ -1,423 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import shared_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import SharedSetServiceTransport, DEFAULT_CLIENT_INFO -from .client import SharedSetServiceClient - -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 SharedSetServiceAsyncClient: - """Service to manage shared sets.""" - - _client: SharedSetServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = SharedSetServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = SharedSetServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - SharedSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = SharedSetServiceClient._DEFAULT_UNIVERSE - - shared_set_path = staticmethod(SharedSetServiceClient.shared_set_path) - parse_shared_set_path = staticmethod( - SharedSetServiceClient.parse_shared_set_path - ) - common_billing_account_path = staticmethod( - SharedSetServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - SharedSetServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(SharedSetServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - SharedSetServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - SharedSetServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - SharedSetServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - SharedSetServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - SharedSetServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - SharedSetServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - SharedSetServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SharedSetServiceAsyncClient: The constructed client. - """ - return SharedSetServiceClient.from_service_account_info.__func__(SharedSetServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SharedSetServiceAsyncClient: The constructed client. - """ - return SharedSetServiceClient.from_service_account_file.__func__(SharedSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return SharedSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> SharedSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SharedSetServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = SharedSetServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - SharedSetServiceTransport, - Callable[..., SharedSetServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the shared set service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,SharedSetServiceTransport,Callable[..., SharedSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the SharedSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = SharedSetServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.SharedSetServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.SharedSetService", - "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.ads.googleads.v19.services.SharedSetService", - "credentialsType": None, - } - ), - ) - - async def mutate_shared_sets( - self, - request: Optional[ - Union[shared_set_service.MutateSharedSetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[shared_set_service.SharedSetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> shared_set_service.MutateSharedSetsResponse: - r"""Creates, updates, or removes shared sets. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SharedSetError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateSharedSetsRequest, dict]]): - The request object. Request message for - [SharedSetService.MutateSharedSets][google.ads.googleads.v19.services.SharedSetService.MutateSharedSets]. - customer_id (:class:`str`): - Required. The ID of the customer - whose shared sets are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.SharedSetOperation]`): - Required. The list of operations to - perform on individual shared sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateSharedSetsResponse: - Response message for a shared set - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, shared_set_service.MutateSharedSetsRequest): - request = shared_set_service.MutateSharedSetsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_shared_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "SharedSetServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("SharedSetServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/shared_set_service/client.py b/google/ads/googleads/v19/services/services/shared_set_service/client.py deleted file mode 100644 index 67fdf7b1f..000000000 --- a/google/ads/googleads/v19/services/services/shared_set_service/client.py +++ /dev/null @@ -1,875 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import shared_set_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import SharedSetServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import SharedSetServiceGrpcTransport -from .transports.grpc_asyncio import SharedSetServiceGrpcAsyncIOTransport - - -class SharedSetServiceClientMeta(type): - """Metaclass for the SharedSetService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[SharedSetServiceTransport]] - _transport_registry["grpc"] = SharedSetServiceGrpcTransport - _transport_registry["grpc_asyncio"] = SharedSetServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[SharedSetServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class SharedSetServiceClient(metaclass=SharedSetServiceClientMeta): - """Service to manage shared sets.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SharedSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SharedSetServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> SharedSetServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SharedSetServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def shared_set_path( - customer_id: str, - shared_set_id: str, - ) -> str: - """Returns a fully-qualified shared_set string.""" - return "customers/{customer_id}/sharedSets/{shared_set_id}".format( - customer_id=customer_id, - shared_set_id=shared_set_id, - ) - - @staticmethod - def parse_shared_set_path(path: str) -> Dict[str, str]: - """Parses a shared_set path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/sharedSets/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = SharedSetServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = SharedSetServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - SharedSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = SharedSetServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - SharedSetServiceTransport, - Callable[..., SharedSetServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the shared set service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,SharedSetServiceTransport,Callable[..., SharedSetServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the SharedSetServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = SharedSetServiceClient._read_environment_variables() - self._client_cert_source = ( - SharedSetServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = SharedSetServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, SharedSetServiceTransport) - if transport_provided: - # transport is a SharedSetServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(SharedSetServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or SharedSetServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[SharedSetServiceTransport], - Callable[..., SharedSetServiceTransport], - ] = ( - SharedSetServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., SharedSetServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.SharedSetServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.SharedSetService", - "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.ads.googleads.v19.services.SharedSetService", - "credentialsType": None, - } - ), - ) - - def mutate_shared_sets( - self, - request: Optional[ - Union[shared_set_service.MutateSharedSetsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[shared_set_service.SharedSetOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> shared_set_service.MutateSharedSetsResponse: - r"""Creates, updates, or removes shared sets. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SharedSetError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateSharedSetsRequest, dict]): - The request object. Request message for - [SharedSetService.MutateSharedSets][google.ads.googleads.v19.services.SharedSetService.MutateSharedSets]. - customer_id (str): - Required. The ID of the customer - whose shared sets are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.SharedSetOperation]): - Required. The list of operations to - perform on individual shared sets. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateSharedSetsResponse: - Response message for a shared set - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, shared_set_service.MutateSharedSetsRequest): - request = shared_set_service.MutateSharedSetsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_shared_sets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "SharedSetServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("SharedSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/shared_set_service/transports/base.py b/google/ads/googleads/v19/services/services/shared_set_service/transports/base.py deleted file mode 100644 index 82dee2e6a..000000000 --- a/google/ads/googleads/v19/services/services/shared_set_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import shared_set_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class SharedSetServiceTransport(abc.ABC): - """Abstract transport class for SharedSetService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_shared_sets: gapic_v1.method.wrap_method( - self.mutate_shared_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_shared_sets( - self, - ) -> Callable[ - [shared_set_service.MutateSharedSetsRequest], - Union[ - shared_set_service.MutateSharedSetsResponse, - Awaitable[shared_set_service.MutateSharedSetsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("SharedSetServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/shared_set_service/transports/grpc.py b/google/ads/googleads/v19/services/services/shared_set_service/transports/grpc.py deleted file mode 100644 index add5a7c06..000000000 --- a/google/ads/googleads/v19/services/services/shared_set_service/transports/grpc.py +++ /dev/null @@ -1,393 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import shared_set_service -from .base import SharedSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.SharedSetService", - "rpcName": str(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.ads.googleads.v19.services.SharedSetService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class SharedSetServiceGrpcTransport(SharedSetServiceTransport): - """gRPC backend transport for SharedSetService. - - Service to manage shared sets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_shared_sets( - self, - ) -> Callable[ - [shared_set_service.MutateSharedSetsRequest], - shared_set_service.MutateSharedSetsResponse, - ]: - r"""Return a callable for the mutate shared sets method over gRPC. - - Creates, updates, or removes shared sets. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SharedSetError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Returns: - Callable[[~.MutateSharedSetsRequest], - ~.MutateSharedSetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_shared_sets" not in self._stubs: - self._stubs["mutate_shared_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SharedSetService/MutateSharedSets", - request_serializer=shared_set_service.MutateSharedSetsRequest.serialize, - response_deserializer=shared_set_service.MutateSharedSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_shared_sets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("SharedSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/shared_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/shared_set_service/transports/grpc_asyncio.py deleted file mode 100644 index 35377b14f..000000000 --- a/google/ads/googleads/v19/services/services/shared_set_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,414 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import shared_set_service -from .base import SharedSetServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.SharedSetService", - "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.ads.googleads.v19.services.SharedSetService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class SharedSetServiceGrpcAsyncIOTransport(SharedSetServiceTransport): - """gRPC AsyncIO backend transport for SharedSetService. - - Service to manage shared sets. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_shared_sets( - self, - ) -> Callable[ - [shared_set_service.MutateSharedSetsRequest], - Awaitable[shared_set_service.MutateSharedSetsResponse], - ]: - r"""Return a callable for the mutate shared sets method over gRPC. - - Creates, updates, or removes shared sets. Operation statuses are - returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ - `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ - `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ - `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ - `ResourceCountLimitExceededError <>`__ `SharedSetError <>`__ - `SizeLimitError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ - - Returns: - Callable[[~.MutateSharedSetsRequest], - Awaitable[~.MutateSharedSetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_shared_sets" not in self._stubs: - self._stubs["mutate_shared_sets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SharedSetService/MutateSharedSets", - request_serializer=shared_set_service.MutateSharedSetsRequest.serialize, - response_deserializer=shared_set_service.MutateSharedSetsResponse.deserialize, - ) - ) - return self._stubs["mutate_shared_sets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_shared_sets: self._wrap_method( - self.mutate_shared_sets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("SharedSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/async_client.py b/google/ads/googleads/v19/services/services/smart_campaign_setting_service/async_client.py deleted file mode 100644 index 3653706c5..000000000 --- a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/async_client.py +++ /dev/null @@ -1,538 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - smart_campaign_setting_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - SmartCampaignSettingServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import SmartCampaignSettingServiceClient - -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 SmartCampaignSettingServiceAsyncClient: - """Service to manage Smart campaign settings.""" - - _client: SmartCampaignSettingServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = SmartCampaignSettingServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - SmartCampaignSettingServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - SmartCampaignSettingServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = SmartCampaignSettingServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod( - SmartCampaignSettingServiceClient.campaign_path - ) - parse_campaign_path = staticmethod( - SmartCampaignSettingServiceClient.parse_campaign_path - ) - smart_campaign_setting_path = staticmethod( - SmartCampaignSettingServiceClient.smart_campaign_setting_path - ) - parse_smart_campaign_setting_path = staticmethod( - SmartCampaignSettingServiceClient.parse_smart_campaign_setting_path - ) - common_billing_account_path = staticmethod( - SmartCampaignSettingServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - SmartCampaignSettingServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - SmartCampaignSettingServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - SmartCampaignSettingServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - SmartCampaignSettingServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - SmartCampaignSettingServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - SmartCampaignSettingServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - SmartCampaignSettingServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - SmartCampaignSettingServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - SmartCampaignSettingServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SmartCampaignSettingServiceAsyncClient: The constructed client. - """ - return SmartCampaignSettingServiceClient.from_service_account_info.__func__(SmartCampaignSettingServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SmartCampaignSettingServiceAsyncClient: The constructed client. - """ - return SmartCampaignSettingServiceClient.from_service_account_file.__func__(SmartCampaignSettingServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return SmartCampaignSettingServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> SmartCampaignSettingServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SmartCampaignSettingServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = SmartCampaignSettingServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - SmartCampaignSettingServiceTransport, - Callable[..., SmartCampaignSettingServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the smart campaign setting service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,SmartCampaignSettingServiceTransport,Callable[..., SmartCampaignSettingServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the SmartCampaignSettingServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = SmartCampaignSettingServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.SmartCampaignSettingServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.SmartCampaignSettingService", - "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.ads.googleads.v19.services.SmartCampaignSettingService", - "credentialsType": None, - } - ), - ) - - async def get_smart_campaign_status( - self, - request: Optional[ - Union[ - smart_campaign_setting_service.GetSmartCampaignStatusRequest, - dict, - ] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> smart_campaign_setting_service.GetSmartCampaignStatusResponse: - r"""Returns the status of the requested Smart campaign. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.GetSmartCampaignStatusRequest, dict]]): - The request object. Request message for - [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v19.services.SmartCampaignSettingService.GetSmartCampaignStatus]. - resource_name (:class:`str`): - Required. The resource name of the - Smart campaign setting belonging to the - Smart campaign to fetch the status of. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GetSmartCampaignStatusResponse: - Response message for - [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v19.services.SmartCampaignSettingService.GetSmartCampaignStatus]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - smart_campaign_setting_service.GetSmartCampaignStatusRequest, - ): - request = ( - smart_campaign_setting_service.GetSmartCampaignStatusRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.get_smart_campaign_status - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def mutate_smart_campaign_settings( - self, - request: Optional[ - Union[ - smart_campaign_setting_service.MutateSmartCampaignSettingsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - smart_campaign_setting_service.SmartCampaignSettingOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> smart_campaign_setting_service.MutateSmartCampaignSettingsResponse: - r"""Updates Smart campaign settings for campaigns. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateSmartCampaignSettingsRequest, dict]]): - The request object. Request message for - [SmartCampaignSettingService.MutateSmartCampaignSettings][google.ads.googleads.v19.services.SmartCampaignSettingService.MutateSmartCampaignSettings]. - customer_id (:class:`str`): - Required. The ID of the customer - whose Smart campaign settings are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.SmartCampaignSettingOperation]`): - Required. The list of operations to - perform on individual Smart campaign - settings. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateSmartCampaignSettingsResponse: - Response message for campaign mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - smart_campaign_setting_service.MutateSmartCampaignSettingsRequest, - ): - request = smart_campaign_setting_service.MutateSmartCampaignSettingsRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_smart_campaign_settings - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "SmartCampaignSettingServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("SmartCampaignSettingServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/client.py b/google/ads/googleads/v19/services/services/smart_campaign_setting_service/client.py deleted file mode 100644 index 1a7ae9584..000000000 --- a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/client.py +++ /dev/null @@ -1,1014 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - smart_campaign_setting_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - SmartCampaignSettingServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import SmartCampaignSettingServiceGrpcTransport -from .transports.grpc_asyncio import ( - SmartCampaignSettingServiceGrpcAsyncIOTransport, -) - - -class SmartCampaignSettingServiceClientMeta(type): - """Metaclass for the SmartCampaignSettingService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[SmartCampaignSettingServiceTransport]] - _transport_registry["grpc"] = SmartCampaignSettingServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - SmartCampaignSettingServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[SmartCampaignSettingServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class SmartCampaignSettingServiceClient( - metaclass=SmartCampaignSettingServiceClientMeta -): - """Service to manage Smart campaign settings.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SmartCampaignSettingServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SmartCampaignSettingServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> SmartCampaignSettingServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SmartCampaignSettingServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def smart_campaign_setting_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified smart_campaign_setting string.""" - return "customers/{customer_id}/smartCampaignSettings/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_smart_campaign_setting_path(path: str) -> Dict[str, str]: - """Parses a smart_campaign_setting path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/smartCampaignSettings/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - SmartCampaignSettingServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - SmartCampaignSettingServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = SmartCampaignSettingServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = SmartCampaignSettingServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - SmartCampaignSettingServiceTransport, - Callable[..., SmartCampaignSettingServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the smart campaign setting service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,SmartCampaignSettingServiceTransport,Callable[..., SmartCampaignSettingServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the SmartCampaignSettingServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = SmartCampaignSettingServiceClient._read_environment_variables() - self._client_cert_source = ( - SmartCampaignSettingServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - SmartCampaignSettingServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, SmartCampaignSettingServiceTransport - ) - if transport_provided: - # transport is a SmartCampaignSettingServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - SmartCampaignSettingServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or SmartCampaignSettingServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[SmartCampaignSettingServiceTransport], - Callable[..., SmartCampaignSettingServiceTransport], - ] = ( - SmartCampaignSettingServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., SmartCampaignSettingServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.SmartCampaignSettingServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.SmartCampaignSettingService", - "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.ads.googleads.v19.services.SmartCampaignSettingService", - "credentialsType": None, - } - ), - ) - - def get_smart_campaign_status( - self, - request: Optional[ - Union[ - smart_campaign_setting_service.GetSmartCampaignStatusRequest, - dict, - ] - ] = None, - *, - resource_name: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> smart_campaign_setting_service.GetSmartCampaignStatusResponse: - r"""Returns the status of the requested Smart campaign. - - Args: - request (Union[google.ads.googleads.v19.services.types.GetSmartCampaignStatusRequest, dict]): - The request object. Request message for - [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v19.services.SmartCampaignSettingService.GetSmartCampaignStatus]. - resource_name (str): - Required. The resource name of the - Smart campaign setting belonging to the - Smart campaign to fetch the status of. - - This corresponds to the ``resource_name`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.GetSmartCampaignStatusResponse: - Response message for - [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v19.services.SmartCampaignSettingService.GetSmartCampaignStatus]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [resource_name] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - smart_campaign_setting_service.GetSmartCampaignStatusRequest, - ): - request = ( - smart_campaign_setting_service.GetSmartCampaignStatusRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if resource_name is not None: - request.resource_name = resource_name - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.get_smart_campaign_status - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def mutate_smart_campaign_settings( - self, - request: Optional[ - Union[ - smart_campaign_setting_service.MutateSmartCampaignSettingsRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - smart_campaign_setting_service.SmartCampaignSettingOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> smart_campaign_setting_service.MutateSmartCampaignSettingsResponse: - r"""Updates Smart campaign settings for campaigns. - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateSmartCampaignSettingsRequest, dict]): - The request object. Request message for - [SmartCampaignSettingService.MutateSmartCampaignSettings][google.ads.googleads.v19.services.SmartCampaignSettingService.MutateSmartCampaignSettings]. - customer_id (str): - Required. The ID of the customer - whose Smart campaign settings are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.SmartCampaignSettingOperation]): - Required. The list of operations to - perform on individual Smart campaign - settings. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateSmartCampaignSettingsResponse: - Response message for campaign mutate. - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - smart_campaign_setting_service.MutateSmartCampaignSettingsRequest, - ): - request = smart_campaign_setting_service.MutateSmartCampaignSettingsRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_smart_campaign_settings - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "SmartCampaignSettingServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("SmartCampaignSettingServiceClient",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/base.py b/google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/base.py deleted file mode 100644 index 185bace28..000000000 --- a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/base.py +++ /dev/null @@ -1,195 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - smart_campaign_setting_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class SmartCampaignSettingServiceTransport(abc.ABC): - """Abstract transport class for SmartCampaignSettingService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.get_smart_campaign_status: gapic_v1.method.wrap_method( - self.get_smart_campaign_status, - default_timeout=None, - client_info=client_info, - ), - self.mutate_smart_campaign_settings: gapic_v1.method.wrap_method( - self.mutate_smart_campaign_settings, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def get_smart_campaign_status( - self, - ) -> Callable[ - [smart_campaign_setting_service.GetSmartCampaignStatusRequest], - Union[ - smart_campaign_setting_service.GetSmartCampaignStatusResponse, - Awaitable[ - smart_campaign_setting_service.GetSmartCampaignStatusResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def mutate_smart_campaign_settings( - self, - ) -> Callable[ - [smart_campaign_setting_service.MutateSmartCampaignSettingsRequest], - Union[ - smart_campaign_setting_service.MutateSmartCampaignSettingsResponse, - Awaitable[ - smart_campaign_setting_service.MutateSmartCampaignSettingsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("SmartCampaignSettingServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/grpc.py b/google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/grpc.py deleted file mode 100644 index f85eb3d82..000000000 --- a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/grpc.py +++ /dev/null @@ -1,416 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - smart_campaign_setting_service, -) -from .base import SmartCampaignSettingServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.SmartCampaignSettingService", - "rpcName": str(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.ads.googleads.v19.services.SmartCampaignSettingService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class SmartCampaignSettingServiceGrpcTransport( - SmartCampaignSettingServiceTransport -): - """gRPC backend transport for SmartCampaignSettingService. - - Service to manage Smart campaign settings. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def get_smart_campaign_status( - self, - ) -> Callable[ - [smart_campaign_setting_service.GetSmartCampaignStatusRequest], - smart_campaign_setting_service.GetSmartCampaignStatusResponse, - ]: - r"""Return a callable for the get smart campaign status method over gRPC. - - Returns the status of the requested Smart campaign. - - Returns: - Callable[[~.GetSmartCampaignStatusRequest], - ~.GetSmartCampaignStatusResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_smart_campaign_status" not in self._stubs: - self._stubs["get_smart_campaign_status"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SmartCampaignSettingService/GetSmartCampaignStatus", - request_serializer=smart_campaign_setting_service.GetSmartCampaignStatusRequest.serialize, - response_deserializer=smart_campaign_setting_service.GetSmartCampaignStatusResponse.deserialize, - ) - ) - return self._stubs["get_smart_campaign_status"] - - @property - def mutate_smart_campaign_settings( - self, - ) -> Callable[ - [smart_campaign_setting_service.MutateSmartCampaignSettingsRequest], - smart_campaign_setting_service.MutateSmartCampaignSettingsResponse, - ]: - r"""Return a callable for the mutate smart campaign settings method over gRPC. - - Updates Smart campaign settings for campaigns. - - Returns: - Callable[[~.MutateSmartCampaignSettingsRequest], - ~.MutateSmartCampaignSettingsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_smart_campaign_settings" not in self._stubs: - self._stubs["mutate_smart_campaign_settings"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SmartCampaignSettingService/MutateSmartCampaignSettings", - request_serializer=smart_campaign_setting_service.MutateSmartCampaignSettingsRequest.serialize, - response_deserializer=smart_campaign_setting_service.MutateSmartCampaignSettingsResponse.deserialize, - ) - ) - return self._stubs["mutate_smart_campaign_settings"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("SmartCampaignSettingServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/grpc_asyncio.py deleted file mode 100644 index 5f6fbcfa7..000000000 --- a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,446 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - smart_campaign_setting_service, -) -from .base import SmartCampaignSettingServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.SmartCampaignSettingService", - "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.ads.googleads.v19.services.SmartCampaignSettingService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class SmartCampaignSettingServiceGrpcAsyncIOTransport( - SmartCampaignSettingServiceTransport -): - """gRPC AsyncIO backend transport for SmartCampaignSettingService. - - Service to manage Smart campaign settings. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def get_smart_campaign_status( - self, - ) -> Callable[ - [smart_campaign_setting_service.GetSmartCampaignStatusRequest], - Awaitable[ - smart_campaign_setting_service.GetSmartCampaignStatusResponse - ], - ]: - r"""Return a callable for the get smart campaign status method over gRPC. - - Returns the status of the requested Smart campaign. - - Returns: - Callable[[~.GetSmartCampaignStatusRequest], - Awaitable[~.GetSmartCampaignStatusResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "get_smart_campaign_status" not in self._stubs: - self._stubs["get_smart_campaign_status"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SmartCampaignSettingService/GetSmartCampaignStatus", - request_serializer=smart_campaign_setting_service.GetSmartCampaignStatusRequest.serialize, - response_deserializer=smart_campaign_setting_service.GetSmartCampaignStatusResponse.deserialize, - ) - ) - return self._stubs["get_smart_campaign_status"] - - @property - def mutate_smart_campaign_settings( - self, - ) -> Callable[ - [smart_campaign_setting_service.MutateSmartCampaignSettingsRequest], - Awaitable[ - smart_campaign_setting_service.MutateSmartCampaignSettingsResponse - ], - ]: - r"""Return a callable for the mutate smart campaign settings method over gRPC. - - Updates Smart campaign settings for campaigns. - - Returns: - Callable[[~.MutateSmartCampaignSettingsRequest], - Awaitable[~.MutateSmartCampaignSettingsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_smart_campaign_settings" not in self._stubs: - self._stubs["mutate_smart_campaign_settings"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SmartCampaignSettingService/MutateSmartCampaignSettings", - request_serializer=smart_campaign_setting_service.MutateSmartCampaignSettingsRequest.serialize, - response_deserializer=smart_campaign_setting_service.MutateSmartCampaignSettingsResponse.deserialize, - ) - ) - return self._stubs["mutate_smart_campaign_settings"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.get_smart_campaign_status: self._wrap_method( - self.get_smart_campaign_status, - default_timeout=None, - client_info=client_info, - ), - self.mutate_smart_campaign_settings: self._wrap_method( - self.mutate_smart_campaign_settings, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("SmartCampaignSettingServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/async_client.py b/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/async_client.py deleted file mode 100644 index 980a3189b..000000000 --- a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/async_client.py +++ /dev/null @@ -1,632 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - smart_campaign_suggest_service, -) -from .transports.base import ( - SmartCampaignSuggestServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import SmartCampaignSuggestServiceClient - -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 SmartCampaignSuggestServiceAsyncClient: - """Service to get suggestions for Smart Campaigns.""" - - _client: SmartCampaignSuggestServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = SmartCampaignSuggestServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - SmartCampaignSuggestServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - SmartCampaignSuggestServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = SmartCampaignSuggestServiceClient._DEFAULT_UNIVERSE - - campaign_path = staticmethod( - SmartCampaignSuggestServiceClient.campaign_path - ) - parse_campaign_path = staticmethod( - SmartCampaignSuggestServiceClient.parse_campaign_path - ) - keyword_theme_constant_path = staticmethod( - SmartCampaignSuggestServiceClient.keyword_theme_constant_path - ) - parse_keyword_theme_constant_path = staticmethod( - SmartCampaignSuggestServiceClient.parse_keyword_theme_constant_path - ) - common_billing_account_path = staticmethod( - SmartCampaignSuggestServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - SmartCampaignSuggestServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - SmartCampaignSuggestServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - SmartCampaignSuggestServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - SmartCampaignSuggestServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - SmartCampaignSuggestServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - SmartCampaignSuggestServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - SmartCampaignSuggestServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - SmartCampaignSuggestServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - SmartCampaignSuggestServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SmartCampaignSuggestServiceAsyncClient: The constructed client. - """ - return SmartCampaignSuggestServiceClient.from_service_account_info.__func__(SmartCampaignSuggestServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SmartCampaignSuggestServiceAsyncClient: The constructed client. - """ - return SmartCampaignSuggestServiceClient.from_service_account_file.__func__(SmartCampaignSuggestServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return SmartCampaignSuggestServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> SmartCampaignSuggestServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SmartCampaignSuggestServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = SmartCampaignSuggestServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - SmartCampaignSuggestServiceTransport, - Callable[..., SmartCampaignSuggestServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the smart campaign suggest service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,SmartCampaignSuggestServiceTransport,Callable[..., SmartCampaignSuggestServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the SmartCampaignSuggestServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = SmartCampaignSuggestServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.SmartCampaignSuggestServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.SmartCampaignSuggestService", - "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.ads.googleads.v19.services.SmartCampaignSuggestService", - "credentialsType": None, - } - ), - ) - - async def suggest_smart_campaign_budget_options( - self, - request: Optional[ - Union[ - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse - ): - r"""Returns BudgetOption suggestions. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.SuggestSmartCampaignBudgetOptionsRequest, dict]]): - The request object. Request message for - [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestSmartCampaignBudgetOptionsResponse: - Response message for - [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. - Depending on whether the system could suggest the - options, either all of the options or none of them - might be returned. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest, - ): - request = smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.suggest_smart_campaign_budget_options - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def suggest_smart_campaign_ad( - self, - request: Optional[ - Union[ - smart_campaign_suggest_service.SuggestSmartCampaignAdRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - suggestion_info: Optional[ - smart_campaign_suggest_service.SmartCampaignSuggestionInfo - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> smart_campaign_suggest_service.SuggestSmartCampaignAdResponse: - r"""Suggests a Smart campaign ad compatible with the Ad - family of resources, based on data points such as - targeting and the business to advertise. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.SuggestSmartCampaignAdRequest, dict]]): - The request object. Request message for - [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. - customer_id (:class:`str`): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - suggestion_info (:class:`google.ads.googleads.v19.services.types.SmartCampaignSuggestionInfo`): - Required. Inputs used to suggest a Smart campaign ad. - Required fields: final_url, language_code, - keyword_themes. Optional but recommended fields to - improve the quality of the suggestion: business_setting - and geo_target. - - This corresponds to the ``suggestion_info`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestSmartCampaignAdResponse: - Response message for - [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, suggestion_info] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - smart_campaign_suggest_service.SuggestSmartCampaignAdRequest, - ): - request = ( - smart_campaign_suggest_service.SuggestSmartCampaignAdRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if suggestion_info is not None: - request.suggestion_info = suggestion_info - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.suggest_smart_campaign_ad - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def suggest_keyword_themes( - self, - request: Optional[ - Union[ - smart_campaign_suggest_service.SuggestKeywordThemesRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - suggestion_info: Optional[ - smart_campaign_suggest_service.SmartCampaignSuggestionInfo - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> smart_campaign_suggest_service.SuggestKeywordThemesResponse: - r"""Suggests keyword themes to advertise on. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.SuggestKeywordThemesRequest, dict]]): - The request object. Request message for - [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestKeywordThemes]. - customer_id (:class:`str`): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - suggestion_info (:class:`google.ads.googleads.v19.services.types.SmartCampaignSuggestionInfo`): - Required. Information to get keyword theme suggestions. - Required fields: - - - suggestion_info.final_url - - suggestion_info.language_code - - suggestion_info.geo_target - - Recommended fields: - - - suggestion_info.business_setting - - This corresponds to the ``suggestion_info`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestKeywordThemesResponse: - Response message for - [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestKeywordThemes]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, suggestion_info] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, smart_campaign_suggest_service.SuggestKeywordThemesRequest - ): - request = ( - smart_campaign_suggest_service.SuggestKeywordThemesRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if suggestion_info is not None: - request.suggestion_info = suggestion_info - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.suggest_keyword_themes - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "SmartCampaignSuggestServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("SmartCampaignSuggestServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/client.py b/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/client.py deleted file mode 100644 index f61bb8d9b..000000000 --- a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/client.py +++ /dev/null @@ -1,1098 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - smart_campaign_suggest_service, -) -from .transports.base import ( - SmartCampaignSuggestServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import SmartCampaignSuggestServiceGrpcTransport -from .transports.grpc_asyncio import ( - SmartCampaignSuggestServiceGrpcAsyncIOTransport, -) - - -class SmartCampaignSuggestServiceClientMeta(type): - """Metaclass for the SmartCampaignSuggestService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[SmartCampaignSuggestServiceTransport]] - _transport_registry["grpc"] = SmartCampaignSuggestServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - SmartCampaignSuggestServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[SmartCampaignSuggestServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class SmartCampaignSuggestServiceClient( - metaclass=SmartCampaignSuggestServiceClientMeta -): - """Service to get suggestions for Smart Campaigns.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SmartCampaignSuggestServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - SmartCampaignSuggestServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> SmartCampaignSuggestServiceTransport: - """Returns the transport used by the client instance. - - Returns: - SmartCampaignSuggestServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def campaign_path( - customer_id: str, - campaign_id: str, - ) -> str: - """Returns a fully-qualified campaign string.""" - return "customers/{customer_id}/campaigns/{campaign_id}".format( - customer_id=customer_id, - campaign_id=campaign_id, - ) - - @staticmethod - def parse_campaign_path(path: str) -> Dict[str, str]: - """Parses a campaign path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/campaigns/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def keyword_theme_constant_path( - express_category_id: str, - express_sub_category_id: str, - ) -> str: - """Returns a fully-qualified keyword_theme_constant string.""" - return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( - express_category_id=express_category_id, - express_sub_category_id=express_sub_category_id, - ) - - @staticmethod - def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: - """Parses a keyword_theme_constant path into its component segments.""" - m = re.match( - r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - SmartCampaignSuggestServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - SmartCampaignSuggestServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = SmartCampaignSuggestServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = SmartCampaignSuggestServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - SmartCampaignSuggestServiceTransport, - Callable[..., SmartCampaignSuggestServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the smart campaign suggest service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,SmartCampaignSuggestServiceTransport,Callable[..., SmartCampaignSuggestServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the SmartCampaignSuggestServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = SmartCampaignSuggestServiceClient._read_environment_variables() - self._client_cert_source = ( - SmartCampaignSuggestServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - SmartCampaignSuggestServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, SmartCampaignSuggestServiceTransport - ) - if transport_provided: - # transport is a SmartCampaignSuggestServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - SmartCampaignSuggestServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or SmartCampaignSuggestServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[SmartCampaignSuggestServiceTransport], - Callable[..., SmartCampaignSuggestServiceTransport], - ] = ( - SmartCampaignSuggestServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., SmartCampaignSuggestServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.SmartCampaignSuggestServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.SmartCampaignSuggestService", - "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.ads.googleads.v19.services.SmartCampaignSuggestService", - "credentialsType": None, - } - ), - ) - - def suggest_smart_campaign_budget_options( - self, - request: Optional[ - Union[ - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse - ): - r"""Returns BudgetOption suggestions. - - Args: - request (Union[google.ads.googleads.v19.services.types.SuggestSmartCampaignBudgetOptionsRequest, dict]): - The request object. Request message for - [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestSmartCampaignBudgetOptionsResponse: - Response message for - [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. - Depending on whether the system could suggest the - options, either all of the options or none of them - might be returned. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest, - ): - request = smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.suggest_smart_campaign_budget_options - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def suggest_smart_campaign_ad( - self, - request: Optional[ - Union[ - smart_campaign_suggest_service.SuggestSmartCampaignAdRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - suggestion_info: Optional[ - smart_campaign_suggest_service.SmartCampaignSuggestionInfo - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> smart_campaign_suggest_service.SuggestSmartCampaignAdResponse: - r"""Suggests a Smart campaign ad compatible with the Ad - family of resources, based on data points such as - targeting and the business to advertise. - - Args: - request (Union[google.ads.googleads.v19.services.types.SuggestSmartCampaignAdRequest, dict]): - The request object. Request message for - [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. - customer_id (str): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - suggestion_info (google.ads.googleads.v19.services.types.SmartCampaignSuggestionInfo): - Required. Inputs used to suggest a Smart campaign ad. - Required fields: final_url, language_code, - keyword_themes. Optional but recommended fields to - improve the quality of the suggestion: business_setting - and geo_target. - - This corresponds to the ``suggestion_info`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestSmartCampaignAdResponse: - Response message for - [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, suggestion_info] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - smart_campaign_suggest_service.SuggestSmartCampaignAdRequest, - ): - request = ( - smart_campaign_suggest_service.SuggestSmartCampaignAdRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if suggestion_info is not None: - request.suggestion_info = suggestion_info - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.suggest_smart_campaign_ad - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def suggest_keyword_themes( - self, - request: Optional[ - Union[ - smart_campaign_suggest_service.SuggestKeywordThemesRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - suggestion_info: Optional[ - smart_campaign_suggest_service.SmartCampaignSuggestionInfo - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> smart_campaign_suggest_service.SuggestKeywordThemesResponse: - r"""Suggests keyword themes to advertise on. - - Args: - request (Union[google.ads.googleads.v19.services.types.SuggestKeywordThemesRequest, dict]): - The request object. Request message for - [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestKeywordThemes]. - customer_id (str): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - suggestion_info (google.ads.googleads.v19.services.types.SmartCampaignSuggestionInfo): - Required. Information to get keyword theme suggestions. - Required fields: - - - suggestion_info.final_url - - suggestion_info.language_code - - suggestion_info.geo_target - - Recommended fields: - - - suggestion_info.business_setting - - This corresponds to the ``suggestion_info`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestKeywordThemesResponse: - Response message for - [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestKeywordThemes]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, suggestion_info] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, smart_campaign_suggest_service.SuggestKeywordThemesRequest - ): - request = ( - smart_campaign_suggest_service.SuggestKeywordThemesRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if suggestion_info is not None: - request.suggestion_info = suggestion_info - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.suggest_keyword_themes - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "SmartCampaignSuggestServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("SmartCampaignSuggestServiceClient",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/base.py b/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/base.py deleted file mode 100644 index af0516885..000000000 --- a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/base.py +++ /dev/null @@ -1,216 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - smart_campaign_suggest_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class SmartCampaignSuggestServiceTransport(abc.ABC): - """Abstract transport class for SmartCampaignSuggestService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.suggest_smart_campaign_budget_options: gapic_v1.method.wrap_method( - self.suggest_smart_campaign_budget_options, - default_timeout=None, - client_info=client_info, - ), - self.suggest_smart_campaign_ad: gapic_v1.method.wrap_method( - self.suggest_smart_campaign_ad, - default_timeout=None, - client_info=client_info, - ), - self.suggest_keyword_themes: gapic_v1.method.wrap_method( - self.suggest_keyword_themes, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def suggest_smart_campaign_budget_options( - self, - ) -> Callable[ - [ - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest - ], - Union[ - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse, - Awaitable[ - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def suggest_smart_campaign_ad( - self, - ) -> Callable[ - [smart_campaign_suggest_service.SuggestSmartCampaignAdRequest], - Union[ - smart_campaign_suggest_service.SuggestSmartCampaignAdResponse, - Awaitable[ - smart_campaign_suggest_service.SuggestSmartCampaignAdResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def suggest_keyword_themes( - self, - ) -> Callable[ - [smart_campaign_suggest_service.SuggestKeywordThemesRequest], - Union[ - smart_campaign_suggest_service.SuggestKeywordThemesResponse, - Awaitable[ - smart_campaign_suggest_service.SuggestKeywordThemesResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("SmartCampaignSuggestServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/grpc.py b/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/grpc.py deleted file mode 100644 index 164a01c46..000000000 --- a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/grpc.py +++ /dev/null @@ -1,452 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - smart_campaign_suggest_service, -) -from .base import SmartCampaignSuggestServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.SmartCampaignSuggestService", - "rpcName": str(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.ads.googleads.v19.services.SmartCampaignSuggestService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class SmartCampaignSuggestServiceGrpcTransport( - SmartCampaignSuggestServiceTransport -): - """gRPC backend transport for SmartCampaignSuggestService. - - Service to get suggestions for Smart Campaigns. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def suggest_smart_campaign_budget_options( - self, - ) -> Callable[ - [ - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest - ], - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse, - ]: - r"""Return a callable for the suggest smart campaign budget - options method over gRPC. - - Returns BudgetOption suggestions. - - Returns: - Callable[[~.SuggestSmartCampaignBudgetOptionsRequest], - ~.SuggestSmartCampaignBudgetOptionsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_smart_campaign_budget_options" not in self._stubs: - self._stubs["suggest_smart_campaign_budget_options"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SmartCampaignSuggestService/SuggestSmartCampaignBudgetOptions", - request_serializer=smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest.serialize, - response_deserializer=smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse.deserialize, - ) - ) - return self._stubs["suggest_smart_campaign_budget_options"] - - @property - def suggest_smart_campaign_ad( - self, - ) -> Callable[ - [smart_campaign_suggest_service.SuggestSmartCampaignAdRequest], - smart_campaign_suggest_service.SuggestSmartCampaignAdResponse, - ]: - r"""Return a callable for the suggest smart campaign ad method over gRPC. - - Suggests a Smart campaign ad compatible with the Ad - family of resources, based on data points such as - targeting and the business to advertise. - - Returns: - Callable[[~.SuggestSmartCampaignAdRequest], - ~.SuggestSmartCampaignAdResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_smart_campaign_ad" not in self._stubs: - self._stubs["suggest_smart_campaign_ad"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SmartCampaignSuggestService/SuggestSmartCampaignAd", - request_serializer=smart_campaign_suggest_service.SuggestSmartCampaignAdRequest.serialize, - response_deserializer=smart_campaign_suggest_service.SuggestSmartCampaignAdResponse.deserialize, - ) - ) - return self._stubs["suggest_smart_campaign_ad"] - - @property - def suggest_keyword_themes( - self, - ) -> Callable[ - [smart_campaign_suggest_service.SuggestKeywordThemesRequest], - smart_campaign_suggest_service.SuggestKeywordThemesResponse, - ]: - r"""Return a callable for the suggest keyword themes method over gRPC. - - Suggests keyword themes to advertise on. - - Returns: - Callable[[~.SuggestKeywordThemesRequest], - ~.SuggestKeywordThemesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_keyword_themes" not in self._stubs: - self._stubs["suggest_keyword_themes"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SmartCampaignSuggestService/SuggestKeywordThemes", - request_serializer=smart_campaign_suggest_service.SuggestKeywordThemesRequest.serialize, - response_deserializer=smart_campaign_suggest_service.SuggestKeywordThemesResponse.deserialize, - ) - ) - return self._stubs["suggest_keyword_themes"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("SmartCampaignSuggestServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/grpc_asyncio.py deleted file mode 100644 index 33a0d259b..000000000 --- a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,487 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - smart_campaign_suggest_service, -) -from .base import SmartCampaignSuggestServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.SmartCampaignSuggestService", - "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.ads.googleads.v19.services.SmartCampaignSuggestService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class SmartCampaignSuggestServiceGrpcAsyncIOTransport( - SmartCampaignSuggestServiceTransport -): - """gRPC AsyncIO backend transport for SmartCampaignSuggestService. - - Service to get suggestions for Smart Campaigns. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def suggest_smart_campaign_budget_options( - self, - ) -> Callable[ - [ - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest - ], - Awaitable[ - smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse - ], - ]: - r"""Return a callable for the suggest smart campaign budget - options method over gRPC. - - Returns BudgetOption suggestions. - - Returns: - Callable[[~.SuggestSmartCampaignBudgetOptionsRequest], - Awaitable[~.SuggestSmartCampaignBudgetOptionsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_smart_campaign_budget_options" not in self._stubs: - self._stubs["suggest_smart_campaign_budget_options"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SmartCampaignSuggestService/SuggestSmartCampaignBudgetOptions", - request_serializer=smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest.serialize, - response_deserializer=smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse.deserialize, - ) - ) - return self._stubs["suggest_smart_campaign_budget_options"] - - @property - def suggest_smart_campaign_ad( - self, - ) -> Callable[ - [smart_campaign_suggest_service.SuggestSmartCampaignAdRequest], - Awaitable[ - smart_campaign_suggest_service.SuggestSmartCampaignAdResponse - ], - ]: - r"""Return a callable for the suggest smart campaign ad method over gRPC. - - Suggests a Smart campaign ad compatible with the Ad - family of resources, based on data points such as - targeting and the business to advertise. - - Returns: - Callable[[~.SuggestSmartCampaignAdRequest], - Awaitable[~.SuggestSmartCampaignAdResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_smart_campaign_ad" not in self._stubs: - self._stubs["suggest_smart_campaign_ad"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SmartCampaignSuggestService/SuggestSmartCampaignAd", - request_serializer=smart_campaign_suggest_service.SuggestSmartCampaignAdRequest.serialize, - response_deserializer=smart_campaign_suggest_service.SuggestSmartCampaignAdResponse.deserialize, - ) - ) - return self._stubs["suggest_smart_campaign_ad"] - - @property - def suggest_keyword_themes( - self, - ) -> Callable[ - [smart_campaign_suggest_service.SuggestKeywordThemesRequest], - Awaitable[smart_campaign_suggest_service.SuggestKeywordThemesResponse], - ]: - r"""Return a callable for the suggest keyword themes method over gRPC. - - Suggests keyword themes to advertise on. - - Returns: - Callable[[~.SuggestKeywordThemesRequest], - Awaitable[~.SuggestKeywordThemesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_keyword_themes" not in self._stubs: - self._stubs["suggest_keyword_themes"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.SmartCampaignSuggestService/SuggestKeywordThemes", - request_serializer=smart_campaign_suggest_service.SuggestKeywordThemesRequest.serialize, - response_deserializer=smart_campaign_suggest_service.SuggestKeywordThemesResponse.deserialize, - ) - ) - return self._stubs["suggest_keyword_themes"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.suggest_smart_campaign_budget_options: self._wrap_method( - self.suggest_smart_campaign_budget_options, - default_timeout=None, - client_info=client_info, - ), - self.suggest_smart_campaign_ad: self._wrap_method( - self.suggest_smart_campaign_ad, - default_timeout=None, - client_info=client_info, - ), - self.suggest_keyword_themes: self._wrap_method( - self.suggest_keyword_themes, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("SmartCampaignSuggestServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/async_client.py b/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/async_client.py deleted file mode 100644 index 6531c3cef..000000000 --- a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/async_client.py +++ /dev/null @@ -1,408 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - third_party_app_analytics_link_service, -) -from .transports.base import ( - ThirdPartyAppAnalyticsLinkServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import ThirdPartyAppAnalyticsLinkServiceClient - -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 ThirdPartyAppAnalyticsLinkServiceAsyncClient: - """This service allows management of links between Google Ads - and third party app analytics. - """ - - _client: ThirdPartyAppAnalyticsLinkServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = ThirdPartyAppAnalyticsLinkServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - ThirdPartyAppAnalyticsLinkServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - ThirdPartyAppAnalyticsLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = ( - ThirdPartyAppAnalyticsLinkServiceClient._DEFAULT_UNIVERSE - ) - - third_party_app_analytics_link_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.third_party_app_analytics_link_path - ) - parse_third_party_app_analytics_link_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.parse_third_party_app_analytics_link_path - ) - common_billing_account_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - ThirdPartyAppAnalyticsLinkServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ThirdPartyAppAnalyticsLinkServiceAsyncClient: The constructed client. - """ - return ThirdPartyAppAnalyticsLinkServiceClient.from_service_account_info.__func__(ThirdPartyAppAnalyticsLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ThirdPartyAppAnalyticsLinkServiceAsyncClient: The constructed client. - """ - return ThirdPartyAppAnalyticsLinkServiceClient.from_service_account_file.__func__(ThirdPartyAppAnalyticsLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return ThirdPartyAppAnalyticsLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> ThirdPartyAppAnalyticsLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ThirdPartyAppAnalyticsLinkServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = ( - ThirdPartyAppAnalyticsLinkServiceClient.get_transport_class - ) - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ThirdPartyAppAnalyticsLinkServiceTransport, - Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the third party app analytics link service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ThirdPartyAppAnalyticsLinkServiceTransport,Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ThirdPartyAppAnalyticsLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = ThirdPartyAppAnalyticsLinkServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService", - "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.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService", - "credentialsType": None, - } - ), - ) - - async def regenerate_shareable_link_id( - self, - request: Optional[ - Union[ - third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse - ): - r"""Regenerate ThirdPartyAppAnalyticsLink.shareable_link_id that - should be provided to the third party when setting up app - analytics. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.RegenerateShareableLinkIdRequest, dict]]): - The request object. Request message for - [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.RegenerateShareableLinkIdResponse: - Response message for - [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest, - ): - request = third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.regenerate_shareable_link_id - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__( - self, - ) -> "ThirdPartyAppAnalyticsLinkServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("ThirdPartyAppAnalyticsLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/client.py b/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/client.py deleted file mode 100644 index 7a53665c3..000000000 --- a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/client.py +++ /dev/null @@ -1,862 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - third_party_app_analytics_link_service, -) -from .transports.base import ( - ThirdPartyAppAnalyticsLinkServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import ThirdPartyAppAnalyticsLinkServiceGrpcTransport -from .transports.grpc_asyncio import ( - ThirdPartyAppAnalyticsLinkServiceGrpcAsyncIOTransport, -) - - -class ThirdPartyAppAnalyticsLinkServiceClientMeta(type): - """Metaclass for the ThirdPartyAppAnalyticsLinkService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[ThirdPartyAppAnalyticsLinkServiceTransport]] - _transport_registry["grpc"] = ThirdPartyAppAnalyticsLinkServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - ThirdPartyAppAnalyticsLinkServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[ThirdPartyAppAnalyticsLinkServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class ThirdPartyAppAnalyticsLinkServiceClient( - metaclass=ThirdPartyAppAnalyticsLinkServiceClientMeta -): - """This service allows management of links between Google Ads - and third party app analytics. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ThirdPartyAppAnalyticsLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - ThirdPartyAppAnalyticsLinkServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> ThirdPartyAppAnalyticsLinkServiceTransport: - """Returns the transport used by the client instance. - - Returns: - ThirdPartyAppAnalyticsLinkServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def third_party_app_analytics_link_path( - customer_id: str, - customer_link_id: str, - ) -> str: - """Returns a fully-qualified third_party_app_analytics_link string.""" - return "customers/{customer_id}/thirdPartyAppAnalyticsLinks/{customer_link_id}".format( - customer_id=customer_id, - customer_link_id=customer_link_id, - ) - - @staticmethod - def parse_third_party_app_analytics_link_path(path: str) -> Dict[str, str]: - """Parses a third_party_app_analytics_link path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/thirdPartyAppAnalyticsLinks/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - ThirdPartyAppAnalyticsLinkServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - ThirdPartyAppAnalyticsLinkServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = ThirdPartyAppAnalyticsLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = ( - ThirdPartyAppAnalyticsLinkServiceClient._DEFAULT_UNIVERSE - ) - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - ThirdPartyAppAnalyticsLinkServiceTransport, - Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the third party app analytics link service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,ThirdPartyAppAnalyticsLinkServiceTransport,Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the ThirdPartyAppAnalyticsLinkServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = ( - ThirdPartyAppAnalyticsLinkServiceClient._read_environment_variables() - ) - self._client_cert_source = ( - ThirdPartyAppAnalyticsLinkServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - ThirdPartyAppAnalyticsLinkServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, ThirdPartyAppAnalyticsLinkServiceTransport - ) - if transport_provided: - # transport is a ThirdPartyAppAnalyticsLinkServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - ThirdPartyAppAnalyticsLinkServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or ThirdPartyAppAnalyticsLinkServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[ThirdPartyAppAnalyticsLinkServiceTransport], - Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport], - ] = ( - ThirdPartyAppAnalyticsLinkServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService", - "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.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService", - "credentialsType": None, - } - ), - ) - - def regenerate_shareable_link_id( - self, - request: Optional[ - Union[ - third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest, - dict, - ] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> ( - third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse - ): - r"""Regenerate ThirdPartyAppAnalyticsLink.shareable_link_id that - should be provided to the third party when setting up app - analytics. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.RegenerateShareableLinkIdRequest, dict]): - The request object. Request message for - [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.RegenerateShareableLinkIdResponse: - Response message for - [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest, - ): - request = third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest( - request - ) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.regenerate_shareable_link_id - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("resource_name", request.resource_name),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "ThirdPartyAppAnalyticsLinkServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("ThirdPartyAppAnalyticsLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/base.py b/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/base.py deleted file mode 100644 index c2383d86c..000000000 --- a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/base.py +++ /dev/null @@ -1,178 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - third_party_app_analytics_link_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class ThirdPartyAppAnalyticsLinkServiceTransport(abc.ABC): - """Abstract transport class for ThirdPartyAppAnalyticsLinkService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.regenerate_shareable_link_id: gapic_v1.method.wrap_method( - self.regenerate_shareable_link_id, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def regenerate_shareable_link_id( - self, - ) -> Callable[ - [ - third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest - ], - Union[ - third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse, - Awaitable[ - third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("ThirdPartyAppAnalyticsLinkServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/grpc.py b/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/grpc.py deleted file mode 100644 index 07827a1a8..000000000 --- a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/grpc.py +++ /dev/null @@ -1,397 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - third_party_app_analytics_link_service, -) -from .base import ( - ThirdPartyAppAnalyticsLinkServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService", - "rpcName": str(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.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ThirdPartyAppAnalyticsLinkServiceGrpcTransport( - ThirdPartyAppAnalyticsLinkServiceTransport -): - """gRPC backend transport for ThirdPartyAppAnalyticsLinkService. - - This service allows management of links between Google Ads - and third party app analytics. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def regenerate_shareable_link_id( - self, - ) -> Callable[ - [ - third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest - ], - third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse, - ]: - r"""Return a callable for the regenerate shareable link id method over gRPC. - - Regenerate ThirdPartyAppAnalyticsLink.shareable_link_id that - should be provided to the third party when setting up app - analytics. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.RegenerateShareableLinkIdRequest], - ~.RegenerateShareableLinkIdResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "regenerate_shareable_link_id" not in self._stubs: - self._stubs["regenerate_shareable_link_id"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService/RegenerateShareableLinkId", - request_serializer=third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest.serialize, - response_deserializer=third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse.deserialize, - ) - ) - return self._stubs["regenerate_shareable_link_id"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("ThirdPartyAppAnalyticsLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/grpc_asyncio.py deleted file mode 100644 index 6e73dd17e..000000000 --- a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,420 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - third_party_app_analytics_link_service, -) -from .base import ( - ThirdPartyAppAnalyticsLinkServiceTransport, - DEFAULT_CLIENT_INFO, -) - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService", - "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.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class ThirdPartyAppAnalyticsLinkServiceGrpcAsyncIOTransport( - ThirdPartyAppAnalyticsLinkServiceTransport -): - """gRPC AsyncIO backend transport for ThirdPartyAppAnalyticsLinkService. - - This service allows management of links between Google Ads - and third party app analytics. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def regenerate_shareable_link_id( - self, - ) -> Callable[ - [ - third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest - ], - Awaitable[ - third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse - ], - ]: - r"""Return a callable for the regenerate shareable link id method over gRPC. - - Regenerate ThirdPartyAppAnalyticsLink.shareable_link_id that - should be provided to the third party when setting up app - analytics. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `HeaderError <>`__ - `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ - - Returns: - Callable[[~.RegenerateShareableLinkIdRequest], - Awaitable[~.RegenerateShareableLinkIdResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "regenerate_shareable_link_id" not in self._stubs: - self._stubs["regenerate_shareable_link_id"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService/RegenerateShareableLinkId", - request_serializer=third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest.serialize, - response_deserializer=third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse.deserialize, - ) - ) - return self._stubs["regenerate_shareable_link_id"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.regenerate_shareable_link_id: self._wrap_method( - self.regenerate_shareable_link_id, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("ThirdPartyAppAnalyticsLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/async_client.py b/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/async_client.py deleted file mode 100644 index 3e82c9151..000000000 --- a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/async_client.py +++ /dev/null @@ -1,426 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - travel_asset_suggestion_service, -) -from .transports.base import ( - TravelAssetSuggestionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import TravelAssetSuggestionServiceClient - -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 TravelAssetSuggestionServiceAsyncClient: - """Service to retrieve Travel asset suggestions.""" - - _client: TravelAssetSuggestionServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = TravelAssetSuggestionServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - TravelAssetSuggestionServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - TravelAssetSuggestionServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = TravelAssetSuggestionServiceClient._DEFAULT_UNIVERSE - - common_billing_account_path = staticmethod( - TravelAssetSuggestionServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - TravelAssetSuggestionServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - TravelAssetSuggestionServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - TravelAssetSuggestionServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - TravelAssetSuggestionServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - TravelAssetSuggestionServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - TravelAssetSuggestionServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - TravelAssetSuggestionServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - TravelAssetSuggestionServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - TravelAssetSuggestionServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - TravelAssetSuggestionServiceAsyncClient: The constructed client. - """ - return TravelAssetSuggestionServiceClient.from_service_account_info.__func__(TravelAssetSuggestionServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - TravelAssetSuggestionServiceAsyncClient: The constructed client. - """ - return TravelAssetSuggestionServiceClient.from_service_account_file.__func__(TravelAssetSuggestionServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return TravelAssetSuggestionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> TravelAssetSuggestionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - TravelAssetSuggestionServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = TravelAssetSuggestionServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - TravelAssetSuggestionServiceTransport, - Callable[..., TravelAssetSuggestionServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the travel asset suggestion service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,TravelAssetSuggestionServiceTransport,Callable[..., TravelAssetSuggestionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the TravelAssetSuggestionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = TravelAssetSuggestionServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.TravelAssetSuggestionServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.TravelAssetSuggestionService", - "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.ads.googleads.v19.services.TravelAssetSuggestionService", - "credentialsType": None, - } - ), - ) - - async def suggest_travel_assets( - self, - request: Optional[ - Union[ - travel_asset_suggestion_service.SuggestTravelAssetsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - language_option: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> travel_asset_suggestion_service.SuggestTravelAssetsResponse: - r"""Returns Travel Asset suggestions. Asset - suggestions are returned on a best-effort basis. There - are no guarantees that all possible asset types will be - returned for any given hotel property. - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.SuggestTravelAssetsRequest, dict]]): - The request object. Request message for - [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v19.services.TravelAssetSuggestionService.SuggestTravelAssets]. - customer_id (:class:`str`): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - language_option (:class:`str`): - Required. The language specifications - in BCP 47 format (for example, en-US, - zh-CN, etc.) for the asset suggestions. - Text will be in this language. Usually - matches one of the campaign target - languages. - - This corresponds to the ``language_option`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestTravelAssetsResponse: - Response message for - [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v19.services.TravelAssetSuggestionService.SuggestTravelAssets]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, language_option] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, travel_asset_suggestion_service.SuggestTravelAssetsRequest - ): - request = ( - travel_asset_suggestion_service.SuggestTravelAssetsRequest( - request - ) - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if language_option is not None: - request.language_option = language_option - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.suggest_travel_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "TravelAssetSuggestionServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("TravelAssetSuggestionServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/client.py b/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/client.py deleted file mode 100644 index 40a645a04..000000000 --- a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/client.py +++ /dev/null @@ -1,867 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - travel_asset_suggestion_service, -) -from .transports.base import ( - TravelAssetSuggestionServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import TravelAssetSuggestionServiceGrpcTransport -from .transports.grpc_asyncio import ( - TravelAssetSuggestionServiceGrpcAsyncIOTransport, -) - - -class TravelAssetSuggestionServiceClientMeta(type): - """Metaclass for the TravelAssetSuggestionService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[TravelAssetSuggestionServiceTransport]] - _transport_registry["grpc"] = TravelAssetSuggestionServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - TravelAssetSuggestionServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[TravelAssetSuggestionServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class TravelAssetSuggestionServiceClient( - metaclass=TravelAssetSuggestionServiceClientMeta -): - """Service to retrieve Travel asset suggestions.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - TravelAssetSuggestionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - TravelAssetSuggestionServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> TravelAssetSuggestionServiceTransport: - """Returns the transport used by the client instance. - - Returns: - TravelAssetSuggestionServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - TravelAssetSuggestionServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - TravelAssetSuggestionServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = TravelAssetSuggestionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = TravelAssetSuggestionServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - TravelAssetSuggestionServiceTransport, - Callable[..., TravelAssetSuggestionServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the travel asset suggestion service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,TravelAssetSuggestionServiceTransport,Callable[..., TravelAssetSuggestionServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the TravelAssetSuggestionServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = TravelAssetSuggestionServiceClient._read_environment_variables() - self._client_cert_source = ( - TravelAssetSuggestionServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - TravelAssetSuggestionServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, TravelAssetSuggestionServiceTransport - ) - if transport_provided: - # transport is a TravelAssetSuggestionServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - TravelAssetSuggestionServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or TravelAssetSuggestionServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[TravelAssetSuggestionServiceTransport], - Callable[..., TravelAssetSuggestionServiceTransport], - ] = ( - TravelAssetSuggestionServiceClient.get_transport_class( - transport - ) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., TravelAssetSuggestionServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.TravelAssetSuggestionServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.TravelAssetSuggestionService", - "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.ads.googleads.v19.services.TravelAssetSuggestionService", - "credentialsType": None, - } - ), - ) - - def suggest_travel_assets( - self, - request: Optional[ - Union[ - travel_asset_suggestion_service.SuggestTravelAssetsRequest, dict - ] - ] = None, - *, - customer_id: Optional[str] = None, - language_option: Optional[str] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> travel_asset_suggestion_service.SuggestTravelAssetsResponse: - r"""Returns Travel Asset suggestions. Asset - suggestions are returned on a best-effort basis. There - are no guarantees that all possible asset types will be - returned for any given hotel property. - - Args: - request (Union[google.ads.googleads.v19.services.types.SuggestTravelAssetsRequest, dict]): - The request object. Request message for - [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v19.services.TravelAssetSuggestionService.SuggestTravelAssets]. - customer_id (str): - Required. The ID of the customer. - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - language_option (str): - Required. The language specifications - in BCP 47 format (for example, en-US, - zh-CN, etc.) for the asset suggestions. - Text will be in this language. Usually - matches one of the campaign target - languages. - - This corresponds to the ``language_option`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.SuggestTravelAssetsResponse: - Response message for - [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v19.services.TravelAssetSuggestionService.SuggestTravelAssets]. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, language_option] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, travel_asset_suggestion_service.SuggestTravelAssetsRequest - ): - request = ( - travel_asset_suggestion_service.SuggestTravelAssetsRequest( - request - ) - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if language_option is not None: - request.language_option = language_option - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.suggest_travel_assets - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "TravelAssetSuggestionServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("TravelAssetSuggestionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/base.py b/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/base.py deleted file mode 100644 index d3a6996b4..000000000 --- a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - travel_asset_suggestion_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class TravelAssetSuggestionServiceTransport(abc.ABC): - """Abstract transport class for TravelAssetSuggestionService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.suggest_travel_assets: gapic_v1.method.wrap_method( - self.suggest_travel_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def suggest_travel_assets( - self, - ) -> Callable[ - [travel_asset_suggestion_service.SuggestTravelAssetsRequest], - Union[ - travel_asset_suggestion_service.SuggestTravelAssetsResponse, - Awaitable[ - travel_asset_suggestion_service.SuggestTravelAssetsResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("TravelAssetSuggestionServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/grpc.py b/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/grpc.py deleted file mode 100644 index 7f5c4d3e7..000000000 --- a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/grpc.py +++ /dev/null @@ -1,388 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - travel_asset_suggestion_service, -) -from .base import TravelAssetSuggestionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.TravelAssetSuggestionService", - "rpcName": str(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.ads.googleads.v19.services.TravelAssetSuggestionService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class TravelAssetSuggestionServiceGrpcTransport( - TravelAssetSuggestionServiceTransport -): - """gRPC backend transport for TravelAssetSuggestionService. - - Service to retrieve Travel asset suggestions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def suggest_travel_assets( - self, - ) -> Callable[ - [travel_asset_suggestion_service.SuggestTravelAssetsRequest], - travel_asset_suggestion_service.SuggestTravelAssetsResponse, - ]: - r"""Return a callable for the suggest travel assets method over gRPC. - - Returns Travel Asset suggestions. Asset - suggestions are returned on a best-effort basis. There - are no guarantees that all possible asset types will be - returned for any given hotel property. - - Returns: - Callable[[~.SuggestTravelAssetsRequest], - ~.SuggestTravelAssetsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_travel_assets" not in self._stubs: - self._stubs["suggest_travel_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.TravelAssetSuggestionService/SuggestTravelAssets", - request_serializer=travel_asset_suggestion_service.SuggestTravelAssetsRequest.serialize, - response_deserializer=travel_asset_suggestion_service.SuggestTravelAssetsResponse.deserialize, - ) - ) - return self._stubs["suggest_travel_assets"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("TravelAssetSuggestionServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/grpc_asyncio.py deleted file mode 100644 index 6f98970b4..000000000 --- a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,409 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - travel_asset_suggestion_service, -) -from .base import TravelAssetSuggestionServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.TravelAssetSuggestionService", - "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.ads.googleads.v19.services.TravelAssetSuggestionService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class TravelAssetSuggestionServiceGrpcAsyncIOTransport( - TravelAssetSuggestionServiceTransport -): - """gRPC AsyncIO backend transport for TravelAssetSuggestionService. - - Service to retrieve Travel asset suggestions. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def suggest_travel_assets( - self, - ) -> Callable[ - [travel_asset_suggestion_service.SuggestTravelAssetsRequest], - Awaitable[travel_asset_suggestion_service.SuggestTravelAssetsResponse], - ]: - r"""Return a callable for the suggest travel assets method over gRPC. - - Returns Travel Asset suggestions. Asset - suggestions are returned on a best-effort basis. There - are no guarantees that all possible asset types will be - returned for any given hotel property. - - Returns: - Callable[[~.SuggestTravelAssetsRequest], - Awaitable[~.SuggestTravelAssetsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "suggest_travel_assets" not in self._stubs: - self._stubs["suggest_travel_assets"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.TravelAssetSuggestionService/SuggestTravelAssets", - request_serializer=travel_asset_suggestion_service.SuggestTravelAssetsRequest.serialize, - response_deserializer=travel_asset_suggestion_service.SuggestTravelAssetsResponse.deserialize, - ) - ) - return self._stubs["suggest_travel_assets"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.suggest_travel_assets: self._wrap_method( - self.suggest_travel_assets, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("TravelAssetSuggestionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/user_data_service/async_client.py b/google/ads/googleads/v19/services/services/user_data_service/async_client.py deleted file mode 100644 index c71d025bd..000000000 --- a/google/ads/googleads/v19/services/services/user_data_service/async_client.py +++ /dev/null @@ -1,386 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import user_data_service -from .transports.base import UserDataServiceTransport, DEFAULT_CLIENT_INFO -from .client import UserDataServiceClient - -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 UserDataServiceAsyncClient: - """Service to manage user data uploads. - Any uploads made to a Customer Match list through this service - will be eligible for matching as per the customer matching - process. See - https://support.google.com/google-ads/answer/7474263. However, - the uploads made through this service will not be visible under - the 'Segment members' section for the Customer Match List in the - Google Ads UI. - """ - - _client: UserDataServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = UserDataServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = UserDataServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - UserDataServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = UserDataServiceClient._DEFAULT_UNIVERSE - - common_billing_account_path = staticmethod( - UserDataServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - UserDataServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(UserDataServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - UserDataServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - UserDataServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - UserDataServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - UserDataServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - UserDataServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - UserDataServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - UserDataServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserDataServiceAsyncClient: The constructed client. - """ - return UserDataServiceClient.from_service_account_info.__func__(UserDataServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserDataServiceAsyncClient: The constructed client. - """ - return UserDataServiceClient.from_service_account_file.__func__(UserDataServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return UserDataServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> UserDataServiceTransport: - """Returns the transport used by the client instance. - - Returns: - UserDataServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = UserDataServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - UserDataServiceTransport, - Callable[..., UserDataServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the user data service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,UserDataServiceTransport,Callable[..., UserDataServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the UserDataServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = UserDataServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.UserDataServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.UserDataService", - "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.ads.googleads.v19.services.UserDataService", - "credentialsType": None, - } - ), - ) - - async def upload_user_data( - self, - request: Optional[ - Union[user_data_service.UploadUserDataRequest, dict] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> user_data_service.UploadUserDataResponse: - r"""Uploads the given user data. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `OfflineUserDataJobError <>`__ - `QuotaError <>`__ `RequestError <>`__ `UserDataError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.UploadUserDataRequest, dict]]): - The request object. Request message for - [UserDataService.UploadUserData][google.ads.googleads.v19.services.UserDataService.UploadUserData] - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UploadUserDataResponse: - Response message for - [UserDataService.UploadUserData][google.ads.googleads.v19.services.UserDataService.UploadUserData] - Uploads made through this service will not be visible - under the 'Segment members' section for the Customer - Match List in the Google Ads UI. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, user_data_service.UploadUserDataRequest): - request = user_data_service.UploadUserDataRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.upload_user_data - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "UserDataServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("UserDataServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/user_data_service/client.py b/google/ads/googleads/v19/services/services/user_data_service/client.py deleted file mode 100644 index 3ea4bb9f7..000000000 --- a/google/ads/googleads/v19/services/services/user_data_service/client.py +++ /dev/null @@ -1,811 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import user_data_service -from .transports.base import UserDataServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import UserDataServiceGrpcTransport -from .transports.grpc_asyncio import UserDataServiceGrpcAsyncIOTransport - - -class UserDataServiceClientMeta(type): - """Metaclass for the UserDataService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[UserDataServiceTransport]] - _transport_registry["grpc"] = UserDataServiceGrpcTransport - _transport_registry["grpc_asyncio"] = UserDataServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[UserDataServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class UserDataServiceClient(metaclass=UserDataServiceClientMeta): - """Service to manage user data uploads. - Any uploads made to a Customer Match list through this service - will be eligible for matching as per the customer matching - process. See - https://support.google.com/google-ads/answer/7474263. However, - the uploads made through this service will not be visible under - the 'Segment members' section for the Customer Match List in the - Google Ads UI. - """ - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserDataServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserDataServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> UserDataServiceTransport: - """Returns the transport used by the client instance. - - Returns: - UserDataServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = UserDataServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = UserDataServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - UserDataServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = UserDataServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - UserDataServiceTransport, - Callable[..., UserDataServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the user data service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,UserDataServiceTransport,Callable[..., UserDataServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the UserDataServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = UserDataServiceClient._read_environment_variables() - self._client_cert_source = ( - UserDataServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = UserDataServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, UserDataServiceTransport) - if transport_provided: - # transport is a UserDataServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(UserDataServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or UserDataServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[UserDataServiceTransport], - Callable[..., UserDataServiceTransport], - ] = ( - UserDataServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., UserDataServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.UserDataServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.UserDataService", - "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.ads.googleads.v19.services.UserDataService", - "credentialsType": None, - } - ), - ) - - def upload_user_data( - self, - request: Optional[ - Union[user_data_service.UploadUserDataRequest, dict] - ] = None, - *, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> user_data_service.UploadUserDataResponse: - r"""Uploads the given user data. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `OfflineUserDataJobError <>`__ - `QuotaError <>`__ `RequestError <>`__ `UserDataError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.UploadUserDataRequest, dict]): - The request object. Request message for - [UserDataService.UploadUserData][google.ads.googleads.v19.services.UserDataService.UploadUserData] - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.UploadUserDataResponse: - Response message for - [UserDataService.UploadUserData][google.ads.googleads.v19.services.UserDataService.UploadUserData] - Uploads made through this service will not be visible - under the 'Segment members' section for the Customer - Match List in the Google Ads UI. - - """ - # Create or coerce a protobuf request object. - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, user_data_service.UploadUserDataRequest): - request = user_data_service.UploadUserDataRequest(request) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[self._transport.upload_user_data] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "UserDataServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("UserDataServiceClient",) diff --git a/google/ads/googleads/v19/services/services/user_data_service/transports/base.py b/google/ads/googleads/v19/services/services/user_data_service/transports/base.py deleted file mode 100644 index fce81f604..000000000 --- a/google/ads/googleads/v19/services/services/user_data_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import user_data_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class UserDataServiceTransport(abc.ABC): - """Abstract transport class for UserDataService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.upload_user_data: gapic_v1.method.wrap_method( - self.upload_user_data, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def upload_user_data( - self, - ) -> Callable[ - [user_data_service.UploadUserDataRequest], - Union[ - user_data_service.UploadUserDataResponse, - Awaitable[user_data_service.UploadUserDataResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("UserDataServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/user_data_service/transports/grpc.py b/google/ads/googleads/v19/services/services/user_data_service/transports/grpc.py deleted file mode 100644 index 323ed350b..000000000 --- a/google/ads/googleads/v19/services/services/user_data_service/transports/grpc.py +++ /dev/null @@ -1,392 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import user_data_service -from .base import UserDataServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.UserDataService", - "rpcName": str(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.ads.googleads.v19.services.UserDataService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class UserDataServiceGrpcTransport(UserDataServiceTransport): - """gRPC backend transport for UserDataService. - - Service to manage user data uploads. - Any uploads made to a Customer Match list through this service - will be eligible for matching as per the customer matching - process. See - https://support.google.com/google-ads/answer/7474263. However, - the uploads made through this service will not be visible under - the 'Segment members' section for the Customer Match List in the - Google Ads UI. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def upload_user_data( - self, - ) -> Callable[ - [user_data_service.UploadUserDataRequest], - user_data_service.UploadUserDataResponse, - ]: - r"""Return a callable for the upload user data method over gRPC. - - Uploads the given user data. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `OfflineUserDataJobError <>`__ - `QuotaError <>`__ `RequestError <>`__ `UserDataError <>`__ - - Returns: - Callable[[~.UploadUserDataRequest], - ~.UploadUserDataResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "upload_user_data" not in self._stubs: - self._stubs["upload_user_data"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.UserDataService/UploadUserData", - request_serializer=user_data_service.UploadUserDataRequest.serialize, - response_deserializer=user_data_service.UploadUserDataResponse.deserialize, - ) - return self._stubs["upload_user_data"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("UserDataServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/user_data_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/user_data_service/transports/grpc_asyncio.py deleted file mode 100644 index 2c87f6b38..000000000 --- a/google/ads/googleads/v19/services/services/user_data_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,413 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import user_data_service -from .base import UserDataServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.UserDataService", - "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.ads.googleads.v19.services.UserDataService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class UserDataServiceGrpcAsyncIOTransport(UserDataServiceTransport): - """gRPC AsyncIO backend transport for UserDataService. - - Service to manage user data uploads. - Any uploads made to a Customer Match list through this service - will be eligible for matching as per the customer matching - process. See - https://support.google.com/google-ads/answer/7474263. However, - the uploads made through this service will not be visible under - the 'Segment members' section for the Customer Match List in the - Google Ads UI. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def upload_user_data( - self, - ) -> Callable[ - [user_data_service.UploadUserDataRequest], - Awaitable[user_data_service.UploadUserDataResponse], - ]: - r"""Return a callable for the upload user data method over gRPC. - - Uploads the given user data. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `OfflineUserDataJobError <>`__ - `QuotaError <>`__ `RequestError <>`__ `UserDataError <>`__ - - Returns: - Callable[[~.UploadUserDataRequest], - Awaitable[~.UploadUserDataResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "upload_user_data" not in self._stubs: - self._stubs["upload_user_data"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.UserDataService/UploadUserData", - request_serializer=user_data_service.UploadUserDataRequest.serialize, - response_deserializer=user_data_service.UploadUserDataResponse.deserialize, - ) - return self._stubs["upload_user_data"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.upload_user_data: self._wrap_method( - self.upload_user_data, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("UserDataServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/user_list_customer_type_service/async_client.py b/google/ads/googleads/v19/services/services/user_list_customer_type_service/async_client.py deleted file mode 100644 index 84eb30ff5..000000000 --- a/google/ads/googleads/v19/services/services/user_list_customer_type_service/async_client.py +++ /dev/null @@ -1,445 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import ( - user_list_customer_type_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - UserListCustomerTypeServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .client import UserListCustomerTypeServiceClient - -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 UserListCustomerTypeServiceAsyncClient: - """Service to manage user list customer types.""" - - _client: UserListCustomerTypeServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = UserListCustomerTypeServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = ( - UserListCustomerTypeServiceClient.DEFAULT_MTLS_ENDPOINT - ) - _DEFAULT_ENDPOINT_TEMPLATE = ( - UserListCustomerTypeServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = UserListCustomerTypeServiceClient._DEFAULT_UNIVERSE - - user_list_path = staticmethod( - UserListCustomerTypeServiceClient.user_list_path - ) - parse_user_list_path = staticmethod( - UserListCustomerTypeServiceClient.parse_user_list_path - ) - user_list_customer_type_path = staticmethod( - UserListCustomerTypeServiceClient.user_list_customer_type_path - ) - parse_user_list_customer_type_path = staticmethod( - UserListCustomerTypeServiceClient.parse_user_list_customer_type_path - ) - common_billing_account_path = staticmethod( - UserListCustomerTypeServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - UserListCustomerTypeServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod( - UserListCustomerTypeServiceClient.common_folder_path - ) - parse_common_folder_path = staticmethod( - UserListCustomerTypeServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - UserListCustomerTypeServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - UserListCustomerTypeServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - UserListCustomerTypeServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - UserListCustomerTypeServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - UserListCustomerTypeServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - UserListCustomerTypeServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserListCustomerTypeServiceAsyncClient: The constructed client. - """ - return UserListCustomerTypeServiceClient.from_service_account_info.__func__(UserListCustomerTypeServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserListCustomerTypeServiceAsyncClient: The constructed client. - """ - return UserListCustomerTypeServiceClient.from_service_account_file.__func__(UserListCustomerTypeServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return UserListCustomerTypeServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> UserListCustomerTypeServiceTransport: - """Returns the transport used by the client instance. - - Returns: - UserListCustomerTypeServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = UserListCustomerTypeServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - UserListCustomerTypeServiceTransport, - Callable[..., UserListCustomerTypeServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the user list customer type service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,UserListCustomerTypeServiceTransport,Callable[..., UserListCustomerTypeServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the UserListCustomerTypeServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = UserListCustomerTypeServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.UserListCustomerTypeServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.UserListCustomerTypeService", - "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.ads.googleads.v19.services.UserListCustomerTypeService", - "credentialsType": None, - } - ), - ) - - async def mutate_user_list_customer_types( - self, - request: Optional[ - Union[ - user_list_customer_type_service.MutateUserListCustomerTypesRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - user_list_customer_type_service.UserListCustomerTypeOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> user_list_customer_type_service.MutateUserListCustomerTypesResponse: - r"""Attach or remove user list customer types. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `UserListCustomerTypeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateUserListCustomerTypesRequest, dict]]): - The request object. Request message for - [UserListCustomerTypeService.MutateUserListCustomerTypes][google.ads.googleads.v19.services.UserListCustomerTypeService.MutateUserListCustomerTypes]. - customer_id (:class:`str`): - Required. The ID of the customer - whose user list customer types are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.UserListCustomerTypeOperation]`): - Required. The list of operations to - perform on the user list customer types. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateUserListCustomerTypesResponse: - Response message for a user list - customer type mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - user_list_customer_type_service.MutateUserListCustomerTypesRequest, - ): - request = user_list_customer_type_service.MutateUserListCustomerTypesRequest( - request - ) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_user_list_customer_types - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "UserListCustomerTypeServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("UserListCustomerTypeServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/user_list_customer_type_service/client.py b/google/ads/googleads/v19/services/services/user_list_customer_type_service/client.py deleted file mode 100644 index c46a13931..000000000 --- a/google/ads/googleads/v19/services/services/user_list_customer_type_service/client.py +++ /dev/null @@ -1,924 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import ( - user_list_customer_type_service, -) -from google.rpc import status_pb2 # type: ignore -from .transports.base import ( - UserListCustomerTypeServiceTransport, - DEFAULT_CLIENT_INFO, -) -from .transports.grpc import UserListCustomerTypeServiceGrpcTransport -from .transports.grpc_asyncio import ( - UserListCustomerTypeServiceGrpcAsyncIOTransport, -) - - -class UserListCustomerTypeServiceClientMeta(type): - """Metaclass for the UserListCustomerTypeService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[UserListCustomerTypeServiceTransport]] - _transport_registry["grpc"] = UserListCustomerTypeServiceGrpcTransport - _transport_registry["grpc_asyncio"] = ( - UserListCustomerTypeServiceGrpcAsyncIOTransport - ) - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[UserListCustomerTypeServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class UserListCustomerTypeServiceClient( - metaclass=UserListCustomerTypeServiceClientMeta -): - """Service to manage user list customer types.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserListCustomerTypeServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserListCustomerTypeServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> UserListCustomerTypeServiceTransport: - """Returns the transport used by the client instance. - - Returns: - UserListCustomerTypeServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def user_list_path( - customer_id: str, - user_list_id: str, - ) -> str: - """Returns a fully-qualified user_list string.""" - return "customers/{customer_id}/userLists/{user_list_id}".format( - customer_id=customer_id, - user_list_id=user_list_id, - ) - - @staticmethod - def parse_user_list_path(path: str) -> Dict[str, str]: - """Parses a user_list path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/userLists/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def user_list_customer_type_path( - customer_id: str, - user_list_id: str, - semantic_label: str, - ) -> str: - """Returns a fully-qualified user_list_customer_type string.""" - return "customers/{customer_id}/userListCustomerTypes/{user_list_id}~{semantic_label}".format( - customer_id=customer_id, - user_list_id=user_list_id, - semantic_label=semantic_label, - ) - - @staticmethod - def parse_user_list_customer_type_path(path: str) -> Dict[str, str]: - """Parses a user_list_customer_type path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/userListCustomerTypes/(?P.+?)~(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = ( - UserListCustomerTypeServiceClient._DEFAULT_UNIVERSE - ) - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = ( - UserListCustomerTypeServiceClient.DEFAULT_MTLS_ENDPOINT - ) - else: - api_endpoint = UserListCustomerTypeServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = UserListCustomerTypeServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - UserListCustomerTypeServiceTransport, - Callable[..., UserListCustomerTypeServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the user list customer type service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,UserListCustomerTypeServiceTransport,Callable[..., UserListCustomerTypeServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the UserListCustomerTypeServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = UserListCustomerTypeServiceClient._read_environment_variables() - self._client_cert_source = ( - UserListCustomerTypeServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = ( - UserListCustomerTypeServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance( - transport, UserListCustomerTypeServiceTransport - ) - if transport_provided: - # transport is a UserListCustomerTypeServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast( - UserListCustomerTypeServiceTransport, transport - ) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or UserListCustomerTypeServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[UserListCustomerTypeServiceTransport], - Callable[..., UserListCustomerTypeServiceTransport], - ] = ( - UserListCustomerTypeServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast( - Callable[..., UserListCustomerTypeServiceTransport], - transport, - ) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.UserListCustomerTypeServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.UserListCustomerTypeService", - "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.ads.googleads.v19.services.UserListCustomerTypeService", - "credentialsType": None, - } - ), - ) - - def mutate_user_list_customer_types( - self, - request: Optional[ - Union[ - user_list_customer_type_service.MutateUserListCustomerTypesRequest, - dict, - ] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[ - user_list_customer_type_service.UserListCustomerTypeOperation - ] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> user_list_customer_type_service.MutateUserListCustomerTypesResponse: - r"""Attach or remove user list customer types. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `UserListCustomerTypeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateUserListCustomerTypesRequest, dict]): - The request object. Request message for - [UserListCustomerTypeService.MutateUserListCustomerTypes][google.ads.googleads.v19.services.UserListCustomerTypeService.MutateUserListCustomerTypes]. - customer_id (str): - Required. The ID of the customer - whose user list customer types are being - modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.UserListCustomerTypeOperation]): - Required. The list of operations to - perform on the user list customer types. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateUserListCustomerTypesResponse: - Response message for a user list - customer type mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance( - request, - user_list_customer_type_service.MutateUserListCustomerTypesRequest, - ): - request = user_list_customer_type_service.MutateUserListCustomerTypesRequest( - request - ) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_user_list_customer_types - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "UserListCustomerTypeServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("UserListCustomerTypeServiceClient",) diff --git a/google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/base.py b/google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/base.py deleted file mode 100644 index 03800dc87..000000000 --- a/google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/base.py +++ /dev/null @@ -1,176 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import ( - user_list_customer_type_service, -) - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class UserListCustomerTypeServiceTransport(abc.ABC): - """Abstract transport class for UserListCustomerTypeService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_user_list_customer_types: gapic_v1.method.wrap_method( - self.mutate_user_list_customer_types, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_user_list_customer_types( - self, - ) -> Callable[ - [user_list_customer_type_service.MutateUserListCustomerTypesRequest], - Union[ - user_list_customer_type_service.MutateUserListCustomerTypesResponse, - Awaitable[ - user_list_customer_type_service.MutateUserListCustomerTypesResponse - ], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("UserListCustomerTypeServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/grpc.py b/google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/grpc.py deleted file mode 100644 index 1237a5513..000000000 --- a/google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/grpc.py +++ /dev/null @@ -1,392 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import ( - user_list_customer_type_service, -) -from .base import UserListCustomerTypeServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.UserListCustomerTypeService", - "rpcName": str(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.ads.googleads.v19.services.UserListCustomerTypeService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class UserListCustomerTypeServiceGrpcTransport( - UserListCustomerTypeServiceTransport -): - """gRPC backend transport for UserListCustomerTypeService. - - Service to manage user list customer types. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_user_list_customer_types( - self, - ) -> Callable[ - [user_list_customer_type_service.MutateUserListCustomerTypesRequest], - user_list_customer_type_service.MutateUserListCustomerTypesResponse, - ]: - r"""Return a callable for the mutate user list customer - types method over gRPC. - - Attach or remove user list customer types. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `UserListCustomerTypeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateUserListCustomerTypesRequest], - ~.MutateUserListCustomerTypesResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_user_list_customer_types" not in self._stubs: - self._stubs["mutate_user_list_customer_types"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.UserListCustomerTypeService/MutateUserListCustomerTypes", - request_serializer=user_list_customer_type_service.MutateUserListCustomerTypesRequest.serialize, - response_deserializer=user_list_customer_type_service.MutateUserListCustomerTypesResponse.deserialize, - ) - ) - return self._stubs["mutate_user_list_customer_types"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("UserListCustomerTypeServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/grpc_asyncio.py deleted file mode 100644 index 927be24c7..000000000 --- a/google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,415 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import ( - user_list_customer_type_service, -) -from .base import UserListCustomerTypeServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.UserListCustomerTypeService", - "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.ads.googleads.v19.services.UserListCustomerTypeService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class UserListCustomerTypeServiceGrpcAsyncIOTransport( - UserListCustomerTypeServiceTransport -): - """gRPC AsyncIO backend transport for UserListCustomerTypeService. - - Service to manage user list customer types. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_user_list_customer_types( - self, - ) -> Callable[ - [user_list_customer_type_service.MutateUserListCustomerTypesRequest], - Awaitable[ - user_list_customer_type_service.MutateUserListCustomerTypesResponse - ], - ]: - r"""Return a callable for the mutate user list customer - types method over gRPC. - - Attach or remove user list customer types. Operation statuses - are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `UserListCustomerTypeError <>`__ - `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ - `RequestError <>`__ - - Returns: - Callable[[~.MutateUserListCustomerTypesRequest], - Awaitable[~.MutateUserListCustomerTypesResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_user_list_customer_types" not in self._stubs: - self._stubs["mutate_user_list_customer_types"] = ( - self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.UserListCustomerTypeService/MutateUserListCustomerTypes", - request_serializer=user_list_customer_type_service.MutateUserListCustomerTypesRequest.serialize, - response_deserializer=user_list_customer_type_service.MutateUserListCustomerTypesResponse.deserialize, - ) - ) - return self._stubs["mutate_user_list_customer_types"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_user_list_customer_types: self._wrap_method( - self.mutate_user_list_customer_types, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("UserListCustomerTypeServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/user_list_service/async_client.py b/google/ads/googleads/v19/services/services/user_list_service/async_client.py deleted file mode 100644 index f67d53657..000000000 --- a/google/ads/googleads/v19/services/services/user_list_service/async_client.py +++ /dev/null @@ -1,421 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core.client_options import ClientOptions -from google.api_core import gapic_v1 -from google.api_core import retry_async as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - - -try: - OptionalRetry = Union[ - retries.AsyncRetry, gapic_v1.method._MethodDefault, None - ] -except AttributeError: # pragma: NO COVER - OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore - -from google.ads.googleads.v19.services.types import user_list_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import UserListServiceTransport, DEFAULT_CLIENT_INFO -from .client import UserListServiceClient - -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 UserListServiceAsyncClient: - """Service to manage user lists.""" - - _client: UserListServiceClient - - # Copy defaults from the synchronous client for use here. - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = UserListServiceClient.DEFAULT_ENDPOINT - DEFAULT_MTLS_ENDPOINT = UserListServiceClient.DEFAULT_MTLS_ENDPOINT - _DEFAULT_ENDPOINT_TEMPLATE = ( - UserListServiceClient._DEFAULT_ENDPOINT_TEMPLATE - ) - _DEFAULT_UNIVERSE = UserListServiceClient._DEFAULT_UNIVERSE - - user_list_path = staticmethod(UserListServiceClient.user_list_path) - parse_user_list_path = staticmethod( - UserListServiceClient.parse_user_list_path - ) - common_billing_account_path = staticmethod( - UserListServiceClient.common_billing_account_path - ) - parse_common_billing_account_path = staticmethod( - UserListServiceClient.parse_common_billing_account_path - ) - common_folder_path = staticmethod(UserListServiceClient.common_folder_path) - parse_common_folder_path = staticmethod( - UserListServiceClient.parse_common_folder_path - ) - common_organization_path = staticmethod( - UserListServiceClient.common_organization_path - ) - parse_common_organization_path = staticmethod( - UserListServiceClient.parse_common_organization_path - ) - common_project_path = staticmethod( - UserListServiceClient.common_project_path - ) - parse_common_project_path = staticmethod( - UserListServiceClient.parse_common_project_path - ) - common_location_path = staticmethod( - UserListServiceClient.common_location_path - ) - parse_common_location_path = staticmethod( - UserListServiceClient.parse_common_location_path - ) - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserListServiceAsyncClient: The constructed client. - """ - return UserListServiceClient.from_service_account_info.__func__(UserListServiceAsyncClient, info, *args, **kwargs) # type: ignore - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserListServiceAsyncClient: The constructed client. - """ - return UserListServiceClient.from_service_account_file.__func__(UserListServiceAsyncClient, filename, *args, **kwargs) # type: ignore - - from_service_account_json = from_service_account_file - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[ClientOptions] = None - ): - """Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - return UserListServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore - - @property - def transport(self) -> UserListServiceTransport: - """Returns the transport used by the client instance. - - Returns: - UserListServiceTransport: The transport used by the client instance. - """ - return self._client.transport - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._client._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used - by the client instance. - """ - return self._client._universe_domain - - get_transport_class = UserListServiceClient.get_transport_class - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - UserListServiceTransport, - Callable[..., UserListServiceTransport], - ] - ] = "grpc_asyncio", - client_options: Optional[ClientOptions] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the user list service async client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,UserListServiceTransport,Callable[..., UserListServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport to use. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the UserListServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client = UserListServiceClient( - credentials=credentials, - transport=transport, - client_options=client_options, - client_info=client_info, - ) - - if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ): # pragma: NO COVER - _LOGGER.debug( - "Created client `google.ads.googleads.v19.services.UserListServiceAsyncClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.UserListService", - "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.ads.googleads.v19.services.UserListService", - "credentialsType": None, - } - ), - ) - - async def mutate_user_lists( - self, - request: Optional[ - Union[user_list_service.MutateUserListsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[user_list_service.UserListOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> user_list_service.MutateUserListsResponse: - r"""Creates or updates user lists. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ - `OperationAccessDeniedError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ `UserListError <>`__ - - Args: - request (Optional[Union[google.ads.googleads.v19.services.types.MutateUserListsRequest, dict]]): - The request object. Request message for - [UserListService.MutateUserLists][google.ads.googleads.v19.services.UserListService.MutateUserLists]. - customer_id (:class:`str`): - Required. The ID of the customer - whose user lists are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (:class:`MutableSequence[google.ads.googleads.v19.services.types.UserListOperation]`): - Required. The list of operations to - perform on individual user lists. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - 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, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateUserListsResponse: - Response message for user list - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, user_list_service.MutateUserListsRequest): - request = user_list_service.MutateUserListsRequest(request) - - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations: - request.operations.extend(operations) - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._client._transport._wrapped_methods[ - self._client._transport.mutate_user_lists - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._client._validate_universe_domain() - - # Send the request. - response = await rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - async def __aenter__(self) -> "UserListServiceAsyncClient": - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -__all__ = ("UserListServiceAsyncClient",) diff --git a/google/ads/googleads/v19/services/services/user_list_service/client.py b/google/ads/googleads/v19/services/services/user_list_service/client.py deleted file mode 100644 index 052c3802b..000000000 --- a/google/ads/googleads/v19/services/services/user_list_service/client.py +++ /dev/null @@ -1,873 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from collections import OrderedDict -from http import HTTPStatus -import json -import logging as std_logging -import os -import re -from typing import ( - Dict, - Callable, - MutableSequence, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) -import warnings - -from google.ads.googleads.v19 import gapic_version as package_version - -from google.api_core import client_options as client_options_lib -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.api_core import retry as retries -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport import mtls # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.auth.exceptions import MutualTLSChannelError # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -try: - OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] -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.ads.googleads.v19.services.types import user_list_service -from google.rpc import status_pb2 # type: ignore -from .transports.base import UserListServiceTransport, DEFAULT_CLIENT_INFO -from .transports.grpc import UserListServiceGrpcTransport -from .transports.grpc_asyncio import UserListServiceGrpcAsyncIOTransport - - -class UserListServiceClientMeta(type): - """Metaclass for the UserListService client. - - This provides class-level methods for building and retrieving - support objects (e.g. transport) without polluting the client instance - objects. - """ - - _transport_registry = ( - OrderedDict() - ) # type: Dict[str, Type[UserListServiceTransport]] - _transport_registry["grpc"] = UserListServiceGrpcTransport - _transport_registry["grpc_asyncio"] = UserListServiceGrpcAsyncIOTransport - - def get_transport_class( - cls, - label: Optional[str] = None, - ) -> Type[UserListServiceTransport]: - """Returns an appropriate transport class. - - Args: - label: The name of the desired transport. If none is - provided, then the first transport in the registry is used. - - Returns: - The transport class to use. - """ - # If a specific transport is requested, return that one. - if label: - return cls._transport_registry[label] - - # No transport is requested; return the default (that is, the first one - # in the dictionary). - return next(iter(cls._transport_registry.values())) - - -class UserListServiceClient(metaclass=UserListServiceClientMeta): - """Service to manage user lists.""" - - @staticmethod - def _get_default_mtls_endpoint(api_endpoint): - """Converts api endpoint to mTLS endpoint. - - Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to - "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. - Args: - api_endpoint (Optional[str]): the api endpoint to convert. - Returns: - str: converted mTLS api endpoint. - """ - if not api_endpoint: - return api_endpoint - - mtls_endpoint_re = re.compile( - r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" - ) - - m = mtls_endpoint_re.match(api_endpoint) - name, mtls, sandbox, googledomain = m.groups() - if mtls or not googledomain: - return api_endpoint - - if sandbox: - return api_endpoint.replace( - "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" - ) - - return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") - - # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. - DEFAULT_ENDPOINT = "googleads.googleapis.com" - DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore - DEFAULT_ENDPOINT - ) - - _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" - _DEFAULT_UNIVERSE = "googleapis.com" - - @classmethod - def from_service_account_info(cls, info: dict, *args, **kwargs): - """Creates an instance of this client using the provided credentials - info. - - Args: - info (dict): The service account private key info. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserListServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_info( - info - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - @classmethod - def from_service_account_file(cls, filename: str, *args, **kwargs): - """Creates an instance of this client using the provided credentials - file. - - Args: - filename (str): The path to the service account private key json - file. - args: Additional arguments to pass to the constructor. - kwargs: Additional arguments to pass to the constructor. - - Returns: - UserListServiceClient: The constructed client. - """ - credentials = service_account.Credentials.from_service_account_file( - filename - ) - kwargs["credentials"] = credentials - return cls(*args, **kwargs) - - from_service_account_json = from_service_account_file - - @property - def transport(self) -> UserListServiceTransport: - """Returns the transport used by the client instance. - - Returns: - UserListServiceTransport: The transport used by the client - instance. - """ - return self._transport - - @staticmethod - def user_list_path( - customer_id: str, - user_list_id: str, - ) -> str: - """Returns a fully-qualified user_list string.""" - return "customers/{customer_id}/userLists/{user_list_id}".format( - customer_id=customer_id, - user_list_id=user_list_id, - ) - - @staticmethod - def parse_user_list_path(path: str) -> Dict[str, str]: - """Parses a user_list path into its component segments.""" - m = re.match( - r"^customers/(?P.+?)/userLists/(?P.+?)$", - path, - ) - return m.groupdict() if m else {} - - @staticmethod - def common_billing_account_path( - billing_account: str, - ) -> str: - """Returns a fully-qualified billing_account string.""" - return "billingAccounts/{billing_account}".format( - billing_account=billing_account, - ) - - @staticmethod - def parse_common_billing_account_path(path: str) -> Dict[str, str]: - """Parse a billing_account path into its component segments.""" - m = re.match(r"^billingAccounts/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_folder_path( - folder: str, - ) -> str: - """Returns a fully-qualified folder string.""" - return "folders/{folder}".format( - folder=folder, - ) - - @staticmethod - def parse_common_folder_path(path: str) -> Dict[str, str]: - """Parse a folder path into its component segments.""" - m = re.match(r"^folders/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_organization_path( - organization: str, - ) -> str: - """Returns a fully-qualified organization string.""" - return "organizations/{organization}".format( - organization=organization, - ) - - @staticmethod - def parse_common_organization_path(path: str) -> Dict[str, str]: - """Parse a organization path into its component segments.""" - m = re.match(r"^organizations/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_project_path( - project: str, - ) -> str: - """Returns a fully-qualified project string.""" - return "projects/{project}".format( - project=project, - ) - - @staticmethod - def parse_common_project_path(path: str) -> Dict[str, str]: - """Parse a project path into its component segments.""" - m = re.match(r"^projects/(?P.+?)$", path) - return m.groupdict() if m else {} - - @staticmethod - def common_location_path( - project: str, - location: str, - ) -> str: - """Returns a fully-qualified location string.""" - return "projects/{project}/locations/{location}".format( - project=project, - location=location, - ) - - @staticmethod - def parse_common_location_path(path: str) -> Dict[str, str]: - """Parse a location path into its component segments.""" - m = re.match( - r"^projects/(?P.+?)/locations/(?P.+?)$", path - ) - return m.groupdict() if m else {} - - @classmethod - def get_mtls_endpoint_and_cert_source( - cls, client_options: Optional[client_options_lib.ClientOptions] = None - ): - """Deprecated. Return the API endpoint and client cert source for mutual TLS. - - The client cert source is determined in the following order: - (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the - client cert source is None. - (2) if `client_options.client_cert_source` is provided, use the provided one; if the - default client cert source exists, use the default one; otherwise the client cert - source is None. - - The API endpoint is determined in the following order: - (1) if `client_options.api_endpoint` if provided, use the provided one. - (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the - default mTLS endpoint; if the environment variable is "never", use the default API - endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise - use the default API endpoint. - - More details can be found at https://google.aip.dev/auth/4114. - - Args: - client_options (google.api_core.client_options.ClientOptions): Custom options for the - client. Only the `api_endpoint` and `client_cert_source` properties may be used - in this method. - - Returns: - Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the - client cert source to use. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If any errors happen. - """ - - warnings.warn( - "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", - DeprecationWarning, - ) - if client_options is None: - client_options = client_options_lib.ClientOptions() - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ) - use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - - # Figure out the client cert source to use. - client_cert_source = None - if use_client_cert == "true": - if client_options.client_cert_source: - client_cert_source = client_options.client_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - - # Figure out which api endpoint to use. - if client_options.api_endpoint is not None: - api_endpoint = client_options.api_endpoint - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - api_endpoint = cls.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = cls.DEFAULT_ENDPOINT - - return api_endpoint, client_cert_source - - @staticmethod - def _read_environment_variables(): - """Returns the environment variables used by the client. - - Returns: - Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, - GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. - - Raises: - ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not - any of ["true", "false"]. - google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT - is not any of ["auto", "never", "always"]. - """ - use_client_cert = os.getenv( - "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" - ).lower() - use_mtls_endpoint = os.getenv( - "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" - ).lower() - universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") - if use_client_cert not in ("true", "false"): - raise ValueError( - "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`" - ) - if use_mtls_endpoint not in ("auto", "never", "always"): - raise MutualTLSChannelError( - "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" - ) - return use_client_cert == "true", use_mtls_endpoint, universe_domain_env - - @staticmethod - def _get_client_cert_source(provided_cert_source, use_cert_flag): - """Return the client cert source to be used by the client. - - Args: - provided_cert_source (bytes): The client certificate source provided. - use_cert_flag (bool): A flag indicating whether to use the client certificate. - - Returns: - bytes or None: The client cert source to be used by the client. - """ - client_cert_source = None - if use_cert_flag: - if provided_cert_source: - client_cert_source = provided_cert_source - elif mtls.has_default_client_cert_source(): - client_cert_source = mtls.default_client_cert_source() - return client_cert_source - - @staticmethod - def _get_api_endpoint( - api_override, client_cert_source, universe_domain, use_mtls_endpoint - ): - """Return the API endpoint used by the client. - - Args: - api_override (str): The API endpoint override. If specified, this is always - the return value of this function and the other arguments are not used. - client_cert_source (bytes): The client certificate source used by the client. - universe_domain (str): The universe domain used by the client. - use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. - Possible values are "always", "auto", or "never". - - Returns: - str: The API endpoint to be used by the client. - """ - if api_override is not None: - api_endpoint = api_override - elif use_mtls_endpoint == "always" or ( - use_mtls_endpoint == "auto" and client_cert_source - ): - _default_universe = UserListServiceClient._DEFAULT_UNIVERSE - if universe_domain != _default_universe: - raise MutualTLSChannelError( - f"mTLS is not supported in any universe other than {_default_universe}." - ) - api_endpoint = UserListServiceClient.DEFAULT_MTLS_ENDPOINT - else: - api_endpoint = ( - UserListServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( - UNIVERSE_DOMAIN=universe_domain - ) - ) - return api_endpoint - - @staticmethod - def _get_universe_domain( - client_universe_domain: Optional[str], - universe_domain_env: Optional[str], - ) -> str: - """Return the universe domain used by the client. - - Args: - client_universe_domain (Optional[str]): The universe domain configured via the client options. - universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. - - Returns: - str: The universe domain to be used by the client. - - Raises: - ValueError: If the universe domain is an empty string. - """ - universe_domain = UserListServiceClient._DEFAULT_UNIVERSE - if client_universe_domain is not None: - universe_domain = client_universe_domain - elif universe_domain_env is not None: - universe_domain = universe_domain_env - if len(universe_domain.strip()) == 0: - raise ValueError("Universe Domain cannot be an empty string.") - return universe_domain - - def _validate_universe_domain(self): - """Validates client's and credentials' universe domains are consistent. - - Returns: - bool: True iff the configured universe domain is valid. - - Raises: - ValueError: If the configured universe domain is not valid. - """ - - # NOTE (b/349488459): universe validation is disabled until further notice. - return True - - def _add_cred_info_for_auth_errors( - self, error: core_exceptions.GoogleAPICallError - ) -> None: - """Adds credential info string to error details for 401/403/404 errors. - - Args: - error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. - """ - if error.code not in [ - HTTPStatus.UNAUTHORIZED, - HTTPStatus.FORBIDDEN, - HTTPStatus.NOT_FOUND, - ]: - return - - cred = self._transport._credentials - - # get_cred_info is only available in google-auth>=2.35.0 - if not hasattr(cred, "get_cred_info"): - return - - # ignore the type check since pypy test fails when get_cred_info - # is not available - cred_info = cred.get_cred_info() # type: ignore - if cred_info and hasattr(error._details, "append"): - error._details.append(json.dumps(cred_info)) - - @property - def api_endpoint(self): - """Return the API endpoint used by the client instance. - - Returns: - str: The API endpoint used by the client instance. - """ - return self._api_endpoint - - @property - def universe_domain(self) -> str: - """Return the universe domain used by the client instance. - - Returns: - str: The universe domain used by the client instance. - """ - return self._universe_domain - - def __init__( - self, - *, - credentials: Optional[ga_credentials.Credentials] = None, - transport: Optional[ - Union[ - str, - UserListServiceTransport, - Callable[..., UserListServiceTransport], - ] - ] = None, - client_options: Optional[ - Union[client_options_lib.ClientOptions, dict] - ] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - ) -> None: - """Instantiates the user list service client. - - Args: - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - transport (Optional[Union[str,UserListServiceTransport,Callable[..., UserListServiceTransport]]]): - The transport to use, or a Callable that constructs and returns a new transport. - If a Callable is given, it will be called with the same set of initialization - arguments as used in the UserListServiceTransport constructor. - If set to None, a transport is chosen automatically. - client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): - Custom options for the client. - - 1. The ``api_endpoint`` property can be used to override the - default endpoint provided by the client when ``transport`` is - not explicitly provided. Only if this property is not set and - ``transport`` was not explicitly provided, the endpoint is - determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment - variable, which have one of the following values: - "always" (always use the default mTLS endpoint), "never" (always - use the default regular endpoint) and "auto" (auto-switch to the - default mTLS endpoint if client certificate is present; this is - the default value). - - 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable - is "true", then the ``client_cert_source`` property can be used - to provide a client certificate for mTLS transport. If - not provided, the default SSL client certificate will be used if - present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not - set, no client certificate will be used. - - 3. The ``universe_domain`` property can be used to override the - default "googleapis.com" universe. Note that the ``api_endpoint`` - property still takes precedence; and ``universe_domain`` is - currently not supported for mTLS. - - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - """ - self._client_options = client_options - if isinstance(self._client_options, dict): - self._client_options = client_options_lib.from_dict( - self._client_options - ) - if self._client_options is None: - self._client_options = client_options_lib.ClientOptions() - self._client_options = cast( - client_options_lib.ClientOptions, self._client_options - ) - - universe_domain_opt = getattr( - self._client_options, "universe_domain", None - ) - - ( - self._use_client_cert, - self._use_mtls_endpoint, - self._universe_domain_env, - ) = UserListServiceClient._read_environment_variables() - self._client_cert_source = ( - UserListServiceClient._get_client_cert_source( - self._client_options.client_cert_source, self._use_client_cert - ) - ) - self._universe_domain = UserListServiceClient._get_universe_domain( - universe_domain_opt, self._universe_domain_env - ) - self._api_endpoint = None # updated below, depending on `transport` - - # 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( - "client_options.api_key and credentials are mutually exclusive" - ) - - # Save or instantiate the transport. - # Ordinarily, we provide the transport, but allowing a custom transport - # instance provides an extensibility point for unusual situations. - transport_provided = isinstance(transport, UserListServiceTransport) - if transport_provided: - # transport is a UserListServiceTransport instance. - if ( - credentials - or self._client_options.credentials_file - or api_key_value - ): - raise ValueError( - "When providing a transport instance, " - "provide its credentials directly." - ) - if self._client_options.scopes: - raise ValueError( - "When providing a transport instance, provide its scopes " - "directly." - ) - self._transport = cast(UserListServiceTransport, transport) - self._api_endpoint = self._transport.host - - self._api_endpoint = ( - self._api_endpoint - or UserListServiceClient._get_api_endpoint( - self._client_options.api_endpoint, - self._client_cert_source, - self._universe_domain, - self._use_mtls_endpoint, - ) - ) - - if not transport_provided: - import google.auth._default # type: ignore - - if api_key_value and hasattr( - google.auth._default, "get_api_key_credentials" - ): - credentials = google.auth._default.get_api_key_credentials( - api_key_value - ) - - transport_init: Union[ - Type[UserListServiceTransport], - Callable[..., UserListServiceTransport], - ] = ( - UserListServiceClient.get_transport_class(transport) - if isinstance(transport, str) or transport is None - else cast(Callable[..., UserListServiceTransport], transport) - ) - # initialize with the provided callable or the passed in class - self._transport = transport_init( - credentials=credentials, - credentials_file=self._client_options.credentials_file, - host=self._api_endpoint, - scopes=self._client_options.scopes, - client_cert_source_for_mtls=self._client_cert_source, - quota_project_id=self._client_options.quota_project_id, - client_info=client_info, - 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 `google.ads.googleads.v19.services.UserListServiceClient`.", - extra=( - { - "serviceName": "google.ads.googleads.v19.services.UserListService", - "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.ads.googleads.v19.services.UserListService", - "credentialsType": None, - } - ), - ) - - def mutate_user_lists( - self, - request: Optional[ - Union[user_list_service.MutateUserListsRequest, dict] - ] = None, - *, - customer_id: Optional[str] = None, - operations: Optional[ - MutableSequence[user_list_service.UserListOperation] - ] = None, - retry: OptionalRetry = gapic_v1.method.DEFAULT, - timeout: Union[float, object] = gapic_v1.method.DEFAULT, - metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), - ) -> user_list_service.MutateUserListsResponse: - r"""Creates or updates user lists. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ - `OperationAccessDeniedError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ `UserListError <>`__ - - Args: - request (Union[google.ads.googleads.v19.services.types.MutateUserListsRequest, dict]): - The request object. Request message for - [UserListService.MutateUserLists][google.ads.googleads.v19.services.UserListService.MutateUserLists]. - customer_id (str): - Required. The ID of the customer - whose user lists are being modified. - - This corresponds to the ``customer_id`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - operations (MutableSequence[google.ads.googleads.v19.services.types.UserListOperation]): - Required. The list of operations to - perform on individual user lists. - - This corresponds to the ``operations`` field - on the ``request`` instance; if ``request`` is provided, this - should not be set. - retry (google.api_core.retry.Retry): Designation of what errors, if any, - should be retried. - timeout (float): The timeout for this request. - metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be - sent along with the request as metadata. Normally, each 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.ads.googleads.v19.services.types.MutateUserListsResponse: - Response message for user list - mutate. - - """ - # Create or coerce a protobuf request object. - # - Quick check: If we got a request object, we should *not* have - # gotten any keyword arguments that map to the request. - flattened_params = [customer_id, operations] - has_flattened_params = ( - len([param for param in flattened_params if param is not None]) > 0 - ) - if request is not None and has_flattened_params: - raise ValueError( - "If the `request` argument is set, then none of " - "the individual field arguments should be set." - ) - - # - Use the request object if provided (there's no risk of modifying the input as - # there are no flattened fields), or create one. - if not isinstance(request, user_list_service.MutateUserListsRequest): - request = user_list_service.MutateUserListsRequest(request) - # If we have keyword arguments corresponding to fields on the - # request, apply these. - if customer_id is not None: - request.customer_id = customer_id - if operations is not None: - request.operations = operations - - # Wrap the RPC method; this adds retry and timeout information, - # and friendly error handling. - rpc = self._transport._wrapped_methods[ - self._transport.mutate_user_lists - ] - - # Certain fields should be provided within the metadata header; - # add these here. - metadata = tuple(metadata) + ( - gapic_v1.routing_header.to_grpc_metadata( - (("customer_id", request.customer_id),) - ), - ) - - # Validate the universe domain. - self._validate_universe_domain() - - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) - - # Done; return the response. - return response - - def __enter__(self) -> "UserListServiceClient": - return self - - def __exit__(self, type, value, traceback): - """Releases underlying transport's resources. - - .. warning:: - ONLY use as a context manager if the transport is NOT shared - with other clients! Exiting the with block will CLOSE the transport - and may cause errors in other clients! - """ - self.transport.close() - - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - -__all__ = ("UserListServiceClient",) diff --git a/google/ads/googleads/v19/services/services/user_list_service/transports/base.py b/google/ads/googleads/v19/services/services/user_list_service/transports/base.py deleted file mode 100644 index 6e7cce28d..000000000 --- a/google/ads/googleads/v19/services/services/user_list_service/transports/base.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import abc -from typing import Awaitable, Callable, Optional, Sequence, Union - -from google.ads.googleads.v19 import gapic_version as package_version - -import google.auth # type: ignore -import google.api_core -from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 -from google.auth import credentials as ga_credentials # type: ignore -from google.oauth2 import service_account # type: ignore -import google.protobuf - -from google.ads.googleads.v19.services.types import user_list_service - -DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( - gapic_version=package_version.__version__ -) - -if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER - DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ - - -class UserListServiceTransport(abc.ABC): - """Abstract transport class for UserListService.""" - - AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) - - DEFAULT_HOST: str = "googleads.googleapis.com" - - def __init__( - self, - *, - host: str = DEFAULT_HOST, - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - **kwargs, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A list of scopes. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - """ - - scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} - - # Save the scopes. - self._scopes = scopes - if not hasattr(self, "_ignore_credentials"): - self._ignore_credentials: bool = False - - # If no credentials are provided, then determine the appropriate - # defaults. - if credentials and credentials_file: - raise core_exceptions.DuplicateCredentialArgs( - "'credentials_file' and 'credentials' are mutually exclusive" - ) - - if credentials_file is not None: - credentials, _ = google.auth.load_credentials_from_file( - credentials_file, - **scopes_kwargs, - quota_project_id=quota_project_id, - ) - elif credentials is None and not self._ignore_credentials: - credentials, _ = google.auth.default( - **scopes_kwargs, quota_project_id=quota_project_id - ) - # Don't apply audience if the credentials file passed from user. - if hasattr(credentials, "with_gdch_audience"): - credentials = credentials.with_gdch_audience( - api_audience if api_audience else host - ) - - # If the credentials are service account credentials, then always try to use self signed JWT. - if ( - always_use_jwt_access - and isinstance(credentials, service_account.Credentials) - and hasattr( - service_account.Credentials, "with_always_use_jwt_access" - ) - ): - credentials = credentials.with_always_use_jwt_access(True) - - # Save the credentials. - self._credentials = credentials - - # Save the hostname. Default to port 443 (HTTPS) if none is specified. - if ":" not in host: - host += ":443" - self._host = host - - @property - def host(self): - return self._host - - def _prep_wrapped_messages(self, client_info): - # Precompute the wrapped methods. - self._wrapped_methods = { - self.mutate_user_lists: gapic_v1.method.wrap_method( - self.mutate_user_lists, - default_timeout=None, - client_info=client_info, - ), - } - - def close(self): - """Closes resources associated with the transport. - - .. warning:: - Only call this method if the transport is NOT shared - with other clients - this may cause errors in other clients! - """ - raise NotImplementedError() - - @property - def mutate_user_lists( - self, - ) -> Callable[ - [user_list_service.MutateUserListsRequest], - Union[ - user_list_service.MutateUserListsResponse, - Awaitable[user_list_service.MutateUserListsResponse], - ], - ]: - raise NotImplementedError() - - @property - def kind(self) -> str: - raise NotImplementedError() - - -__all__ = ("UserListServiceTransport",) diff --git a/google/ads/googleads/v19/services/services/user_list_service/transports/grpc.py b/google/ads/googleads/v19/services/services/user_list_service/transports/grpc.py deleted file mode 100644 index 016054bd5..000000000 --- a/google/ads/googleads/v19/services/services/user_list_service/transports/grpc.py +++ /dev/null @@ -1,389 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import logging as std_logging -import pickle -import warnings -from typing import Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import grpc_helpers -from google.api_core import gapic_v1 -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.ads.googleads.v19.services.types import user_list_service -from .base import UserListServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _LoggingClientInterceptor( - grpc.UnaryUnaryClientInterceptor -): # pragma: NO COVER - def intercept_unary_unary(self, continuation, client_call_details, request): - logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( - std_logging.DEBUG - ) - if logging_enabled: # pragma: NO COVER - request_metadata = client_call_details.metadata - if isinstance(request, proto.Message): - request_payload = type(request).to_json(request) - elif isinstance(request, google.protobuf.message.Message): - request_payload = MessageToJson(request) - else: - request_payload = ( - f"{type(request).__name__}: {pickle.dumps(request)}" - ) - - request_metadata = { - key: ( - value.decode("utf-8") if isinstance(value, bytes) else value - ) - for key, value in request_metadata - } - grpc_request = { - "payload": request_payload, - "requestMethod": "grpc", - "metadata": dict(request_metadata), - } - _LOGGER.debug( - f"Sending request for {client_call_details.method}", - extra={ - "serviceName": "google.ads.googleads.v19.services.UserListService", - "rpcName": str(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.ads.googleads.v19.services.UserListService", - "rpcName": client_call_details.method, - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class UserListServiceGrpcTransport(UserListServiceTransport): - """gRPC backend transport for UserListService. - - Service to manage user lists. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _stubs: Dict[str, Callable] - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[grpc.Channel, Callable[..., grpc.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional(Sequence[str])): A list of scopes. This argument is - ignored if a ``channel`` instance is provided. - channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, grpc.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> grpc.Channel: - """Create and return a gRPC channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is mutually exclusive with credentials. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - grpc.Channel: A gRPC channel object. - - Raises: - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - - return grpc_helpers.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - @property - def grpc_channel(self) -> grpc.Channel: - """Return the channel designed to connect to this service.""" - return self._grpc_channel - - @property - def mutate_user_lists( - self, - ) -> Callable[ - [user_list_service.MutateUserListsRequest], - user_list_service.MutateUserListsResponse, - ]: - r"""Return a callable for the mutate user lists method over gRPC. - - Creates or updates user lists. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ - `OperationAccessDeniedError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ `UserListError <>`__ - - Returns: - Callable[[~.MutateUserListsRequest], - ~.MutateUserListsResponse]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_user_lists" not in self._stubs: - self._stubs["mutate_user_lists"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.UserListService/MutateUserLists", - request_serializer=user_list_service.MutateUserListsRequest.serialize, - response_deserializer=user_list_service.MutateUserListsResponse.deserialize, - ) - return self._stubs["mutate_user_lists"] - - def close(self): - self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc" - - -__all__ = ("UserListServiceGrpcTransport",) diff --git a/google/ads/googleads/v19/services/services/user_list_service/transports/grpc_asyncio.py b/google/ads/googleads/v19/services/services/user_list_service/transports/grpc_asyncio.py deleted file mode 100644 index 7ae61e3da..000000000 --- a/google/ads/googleads/v19/services/services/user_list_service/transports/grpc_asyncio.py +++ /dev/null @@ -1,410 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import inspect -import pickle -import logging as std_logging -import warnings -from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union - -from google.api_core import gapic_v1 -from google.api_core import grpc_helpers_async -from google.auth import credentials as ga_credentials # type: ignore -from google.auth.transport.grpc import SslCredentials # type: ignore -from google.protobuf.json_format import MessageToJson -import google.protobuf.message - -import grpc # type: ignore -import proto # type: ignore -from grpc.experimental import aio # type: ignore - -from google.ads.googleads.v19.services.types import user_list_service -from .base import UserListServiceTransport, DEFAULT_CLIENT_INFO - -try: - from google.api_core import client_logging # type: ignore - - CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER -except ImportError: # pragma: NO COVER - CLIENT_LOGGING_SUPPORTED = False - -_LOGGER = std_logging.getLogger(__name__) - - -class _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.ads.googleads.v19.services.UserListService", - "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.ads.googleads.v19.services.UserListService", - "rpcName": str(client_call_details.method), - "response": grpc_response, - "metadata": grpc_response["metadata"], - }, - ) - return response - - -class UserListServiceGrpcAsyncIOTransport(UserListServiceTransport): - """gRPC AsyncIO backend transport for UserListService. - - Service to manage user lists. - - This class defines the same methods as the primary client, so the - primary client can load the underlying transport implementation - and call it. - - It sends protocol buffers over the wire using gRPC (which is built on - top of HTTP/2); the ``grpcio`` package must be installed. - """ - - _grpc_channel: aio.Channel - _stubs: Dict[str, Callable] = {} - - @classmethod - def create_channel( - cls, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - quota_project_id: Optional[str] = None, - **kwargs, - ) -> aio.Channel: - """Create and return a gRPC AsyncIO channel object. - Args: - host (Optional[str]): The host for the channel to use. - credentials (Optional[~.Credentials]): The - authorization credentials to attach to requests. These - credentials identify this application to the service. If - none are specified, the client will attempt to ascertain - the credentials from the environment. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - kwargs (Optional[dict]): Keyword arguments, which are passed to the - channel creation. - Returns: - aio.Channel: A gRPC AsyncIO channel object. - """ - - return grpc_helpers_async.create_channel( - host, - credentials=credentials, - credentials_file=credentials_file, - quota_project_id=quota_project_id, - default_scopes=cls.AUTH_SCOPES, - scopes=scopes, - default_host=cls.DEFAULT_HOST, - **kwargs, - ) - - def __init__( - self, - *, - host: str = "googleads.googleapis.com", - credentials: Optional[ga_credentials.Credentials] = None, - credentials_file: Optional[str] = None, - scopes: Optional[Sequence[str]] = None, - channel: Optional[ - Union[aio.Channel, Callable[..., aio.Channel]] - ] = None, - api_mtls_endpoint: Optional[str] = None, - client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, - ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, - client_cert_source_for_mtls: Optional[ - Callable[[], Tuple[bytes, bytes]] - ] = None, - quota_project_id: Optional[str] = None, - client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, - always_use_jwt_access: Optional[bool] = False, - api_audience: Optional[str] = None, - ) -> None: - """Instantiate the transport. - - Args: - host (Optional[str]): - The hostname to connect to (default: 'googleads.googleapis.com'). - credentials (Optional[google.auth.credentials.Credentials]): The - authorization credentials to attach to requests. These - credentials identify the application to the service; if none - are specified, the client will attempt to ascertain the - credentials from the environment. - This argument is ignored if a ``channel`` instance is provided. - credentials_file (Optional[str]): A file with credentials that can - be loaded with :func:`google.auth.load_credentials_from_file`. - This argument is ignored if a ``channel`` instance is provided. - scopes (Optional[Sequence[str]]): A optional list of scopes needed for this - service. These are only used when credentials are not specified and - are passed to :func:`google.auth.default`. - channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): - A ``Channel`` instance through which to make calls, or a Callable - that constructs and returns one. If set to None, ``self.create_channel`` - is used to create the channel. If a Callable is given, it will be called - with the same arguments as used in ``self.create_channel``. - api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. - If provided, it overrides the ``host`` argument and tries to create - a mutual TLS channel with client SSL credentials from - ``client_cert_source`` or application default SSL credentials. - client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): - Deprecated. A callback to provide client SSL certificate bytes and - private key bytes, both in PEM format. It is ignored if - ``api_mtls_endpoint`` is None. - ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials - for the grpc channel. It is ignored if a ``channel`` instance is provided. - client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): - A callback to provide client certificate bytes and private key bytes, - both in PEM format. It is used to configure a mutual TLS channel. It is - ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. - quota_project_id (Optional[str]): An optional project to use for billing - and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing - your own client library. - always_use_jwt_access (Optional[bool]): Whether self signed JWT should - be used for service account credentials. - - Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. - google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` - and ``credentials_file`` are passed. - """ - self._grpc_channel = None - self._ssl_channel_credentials = ssl_channel_credentials - self._stubs: Dict[str, Callable] = {} - - if api_mtls_endpoint: - warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) - if client_cert_source: - warnings.warn( - "client_cert_source is deprecated", DeprecationWarning - ) - - if isinstance(channel, aio.Channel): - # Ignore credentials if a channel was passed. - credentials = None - self._ignore_credentials = True - # If a channel was explicitly provided, set it. - self._grpc_channel = channel - self._ssl_channel_credentials = None - else: - if api_mtls_endpoint: - host = api_mtls_endpoint - - # Create SSL credentials with client_cert_source or application - # default SSL credentials. - if client_cert_source: - cert, key = client_cert_source() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - else: - self._ssl_channel_credentials = ( - SslCredentials().ssl_credentials - ) - - else: - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = ( - grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) - ) - - # The base transport sets the host, credentials and scopes - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes, - quota_project_id=quota_project_id, - client_info=client_info, - always_use_jwt_access=always_use_jwt_access, - api_audience=api_audience, - ) - - if not self._grpc_channel: - # initialize with the provided callable or the default channel - channel_init = channel or type(self).create_channel - self._grpc_channel = channel_init( - self._host, - # use the credentials which are saved - credentials=self._credentials, - # Set ``credentials_file`` to ``None`` here as - # the credentials that we saved earlier should be used. - credentials_file=None, - scopes=self._scopes, - ssl_credentials=self._ssl_channel_credentials, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - - 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 - def grpc_channel(self) -> aio.Channel: - """Create the channel designed to connect to this service. - - This property caches on the instance; repeated calls return - the same channel. - """ - # Return the channel from cache. - return self._grpc_channel - - @property - def mutate_user_lists( - self, - ) -> Callable[ - [user_list_service.MutateUserListsRequest], - Awaitable[user_list_service.MutateUserListsResponse], - ]: - r"""Return a callable for the mutate user lists method over gRPC. - - Creates or updates user lists. Operation statuses are returned. - - List of thrown errors: `AuthenticationError <>`__ - `AuthorizationError <>`__ `CollectionSizeError <>`__ - `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ - `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ - `MutateError <>`__ `NewResourceCreationError <>`__ - `NotAllowlistedError <>`__ `NotEmptyError <>`__ - `OperationAccessDeniedError <>`__ `QuotaError <>`__ - `RangeError <>`__ `RequestError <>`__ `StringFormatError <>`__ - `StringLengthError <>`__ `UserListError <>`__ - - Returns: - Callable[[~.MutateUserListsRequest], - Awaitable[~.MutateUserListsResponse]]: - A function that, when called, will call the underlying RPC - on the server. - """ - # Generate a "stub function" on-the-fly which will actually make - # the request. - # gRPC handles serialization and deserialization, so we just need - # to pass in the functions for each. - if "mutate_user_lists" not in self._stubs: - self._stubs["mutate_user_lists"] = self._logged_channel.unary_unary( - "/google.ads.googleads.v19.services.UserListService/MutateUserLists", - request_serializer=user_list_service.MutateUserListsRequest.serialize, - response_deserializer=user_list_service.MutateUserListsResponse.deserialize, - ) - return self._stubs["mutate_user_lists"] - - def _prep_wrapped_messages(self, client_info): - """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" - self._wrapped_methods = { - self.mutate_user_lists: self._wrap_method( - self.mutate_user_lists, - default_timeout=None, - client_info=client_info, - ), - } - - def _wrap_method(self, func, *args, **kwargs): - if self._wrap_with_kind: # pragma: NO COVER - kwargs["kind"] = self.kind - return gapic_v1.method_async.wrap_method(func, *args, **kwargs) - - def close(self): - return self._logged_channel.close() - - @property - def kind(self) -> str: - return "grpc_asyncio" - - -__all__ = ("UserListServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/types/__init__.py b/google/ads/googleads/v19/services/types/__init__.py deleted file mode 100644 index 1168f4457..000000000 --- a/google/ads/googleads/v19/services/types/__init__.py +++ /dev/null @@ -1,1336 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from .account_budget_proposal_service import ( - AccountBudgetProposalOperation, - MutateAccountBudgetProposalRequest, - MutateAccountBudgetProposalResponse, - MutateAccountBudgetProposalResult, -) -from .account_link_service import ( - AccountLinkOperation, - CreateAccountLinkRequest, - CreateAccountLinkResponse, - MutateAccountLinkRequest, - MutateAccountLinkResponse, - MutateAccountLinkResult, -) -from .ad_group_ad_label_service import ( - AdGroupAdLabelOperation, - MutateAdGroupAdLabelResult, - MutateAdGroupAdLabelsRequest, - MutateAdGroupAdLabelsResponse, -) -from .ad_group_ad_service import ( - AdGroupAdOperation, - AssetsWithFieldType, - MutateAdGroupAdResult, - MutateAdGroupAdsRequest, - MutateAdGroupAdsResponse, - RemoveAutomaticallyCreatedAssetsRequest, -) -from .ad_group_asset_service import ( - AdGroupAssetOperation, - MutateAdGroupAssetResult, - MutateAdGroupAssetsRequest, - MutateAdGroupAssetsResponse, -) -from .ad_group_asset_set_service import ( - AdGroupAssetSetOperation, - MutateAdGroupAssetSetResult, - MutateAdGroupAssetSetsRequest, - MutateAdGroupAssetSetsResponse, -) -from .ad_group_bid_modifier_service import ( - AdGroupBidModifierOperation, - MutateAdGroupBidModifierResult, - MutateAdGroupBidModifiersRequest, - MutateAdGroupBidModifiersResponse, -) -from .ad_group_criterion_customizer_service import ( - AdGroupCriterionCustomizerOperation, - MutateAdGroupCriterionCustomizerResult, - MutateAdGroupCriterionCustomizersRequest, - MutateAdGroupCriterionCustomizersResponse, -) -from .ad_group_criterion_label_service import ( - AdGroupCriterionLabelOperation, - MutateAdGroupCriterionLabelResult, - MutateAdGroupCriterionLabelsRequest, - MutateAdGroupCriterionLabelsResponse, -) -from .ad_group_criterion_service import ( - AdGroupCriterionOperation, - MutateAdGroupCriteriaRequest, - MutateAdGroupCriteriaResponse, - MutateAdGroupCriterionResult, -) -from .ad_group_customizer_service import ( - AdGroupCustomizerOperation, - MutateAdGroupCustomizerResult, - MutateAdGroupCustomizersRequest, - MutateAdGroupCustomizersResponse, -) -from .ad_group_label_service import ( - AdGroupLabelOperation, - MutateAdGroupLabelResult, - MutateAdGroupLabelsRequest, - MutateAdGroupLabelsResponse, -) -from .ad_group_service import ( - AdGroupOperation, - MutateAdGroupResult, - MutateAdGroupsRequest, - MutateAdGroupsResponse, -) -from .ad_parameter_service import ( - AdParameterOperation, - MutateAdParameterResult, - MutateAdParametersRequest, - MutateAdParametersResponse, -) -from .ad_service import ( - AdOperation, - MutateAdResult, - MutateAdsRequest, - MutateAdsResponse, -) -from .asset_group_asset_service import ( - AssetGroupAssetOperation, - MutateAssetGroupAssetResult, - MutateAssetGroupAssetsRequest, - MutateAssetGroupAssetsResponse, -) -from .asset_group_listing_group_filter_service import ( - AssetGroupListingGroupFilterOperation, - MutateAssetGroupListingGroupFilterResult, - MutateAssetGroupListingGroupFiltersRequest, - MutateAssetGroupListingGroupFiltersResponse, -) -from .asset_group_service import ( - AssetGroupOperation, - MutateAssetGroupResult, - MutateAssetGroupsRequest, - MutateAssetGroupsResponse, -) -from .asset_group_signal_service import ( - AssetGroupSignalOperation, - MutateAssetGroupSignalResult, - MutateAssetGroupSignalsRequest, - MutateAssetGroupSignalsResponse, -) -from .asset_service import ( - AssetOperation, - MutateAssetResult, - MutateAssetsRequest, - MutateAssetsResponse, -) -from .asset_set_asset_service import ( - AssetSetAssetOperation, - MutateAssetSetAssetResult, - MutateAssetSetAssetsRequest, - MutateAssetSetAssetsResponse, -) -from .asset_set_service import ( - AssetSetOperation, - MutateAssetSetResult, - MutateAssetSetsRequest, - MutateAssetSetsResponse, -) -from .audience_insights_service import ( - AudienceCompositionAttribute, - AudienceCompositionAttributeCluster, - AudienceCompositionMetrics, - AudienceCompositionSection, - AudienceOverlapItem, - BasicInsightsAudience, - DimensionOverlapResult, - GenerateAudienceCompositionInsightsRequest, - GenerateAudienceCompositionInsightsResponse, - GenerateAudienceOverlapInsightsRequest, - GenerateAudienceOverlapInsightsResponse, - GenerateInsightsFinderReportRequest, - GenerateInsightsFinderReportResponse, - GenerateSuggestedTargetingInsightsRequest, - GenerateSuggestedTargetingInsightsResponse, - GenerateTargetingSuggestionMetricsRequest, - GenerateTargetingSuggestionMetricsResponse, - InsightsAudience, - InsightsAudienceAttributeGroup, - InsightsAudienceDefinition, - InsightsAudienceDescription, - ListAudienceInsightsAttributesRequest, - ListAudienceInsightsAttributesResponse, - ListInsightsEligibleDatesRequest, - ListInsightsEligibleDatesResponse, - TargetingSuggestionMetrics, -) -from .audience_service import ( - AudienceOperation, - MutateAudienceResult, - MutateAudiencesRequest, - MutateAudiencesResponse, -) -from .batch_job_service import ( - AddBatchJobOperationsRequest, - AddBatchJobOperationsResponse, - BatchJobOperation, - BatchJobResult, - ListBatchJobResultsRequest, - ListBatchJobResultsResponse, - MutateBatchJobRequest, - MutateBatchJobResponse, - MutateBatchJobResult, - RunBatchJobRequest, -) -from .bidding_data_exclusion_service import ( - BiddingDataExclusionOperation, - MutateBiddingDataExclusionsRequest, - MutateBiddingDataExclusionsResponse, - MutateBiddingDataExclusionsResult, -) -from .bidding_seasonality_adjustment_service import ( - BiddingSeasonalityAdjustmentOperation, - MutateBiddingSeasonalityAdjustmentsRequest, - MutateBiddingSeasonalityAdjustmentsResponse, - MutateBiddingSeasonalityAdjustmentsResult, -) -from .bidding_strategy_service import ( - BiddingStrategyOperation, - MutateBiddingStrategiesRequest, - MutateBiddingStrategiesResponse, - MutateBiddingStrategyResult, -) -from .billing_setup_service import ( - BillingSetupOperation, - MutateBillingSetupRequest, - MutateBillingSetupResponse, - MutateBillingSetupResult, -) -from .brand_suggestion_service import ( - BrandSuggestion, - SuggestBrandsRequest, - SuggestBrandsResponse, -) -from .campaign_asset_service import ( - CampaignAssetOperation, - MutateCampaignAssetResult, - MutateCampaignAssetsRequest, - MutateCampaignAssetsResponse, -) -from .campaign_asset_set_service import ( - CampaignAssetSetOperation, - MutateCampaignAssetSetResult, - MutateCampaignAssetSetsRequest, - MutateCampaignAssetSetsResponse, -) -from .campaign_bid_modifier_service import ( - CampaignBidModifierOperation, - MutateCampaignBidModifierResult, - MutateCampaignBidModifiersRequest, - MutateCampaignBidModifiersResponse, -) -from .campaign_budget_service import ( - CampaignBudgetOperation, - MutateCampaignBudgetResult, - MutateCampaignBudgetsRequest, - MutateCampaignBudgetsResponse, -) -from .campaign_conversion_goal_service import ( - CampaignConversionGoalOperation, - MutateCampaignConversionGoalResult, - MutateCampaignConversionGoalsRequest, - MutateCampaignConversionGoalsResponse, -) -from .campaign_criterion_service import ( - CampaignCriterionOperation, - MutateCampaignCriteriaRequest, - MutateCampaignCriteriaResponse, - MutateCampaignCriterionResult, -) -from .campaign_customizer_service import ( - CampaignCustomizerOperation, - MutateCampaignCustomizerResult, - MutateCampaignCustomizersRequest, - MutateCampaignCustomizersResponse, -) -from .campaign_draft_service import ( - CampaignDraftOperation, - ListCampaignDraftAsyncErrorsRequest, - ListCampaignDraftAsyncErrorsResponse, - MutateCampaignDraftResult, - MutateCampaignDraftsRequest, - MutateCampaignDraftsResponse, - PromoteCampaignDraftRequest, -) -from .campaign_group_service import ( - CampaignGroupOperation, - MutateCampaignGroupResult, - MutateCampaignGroupsRequest, - MutateCampaignGroupsResponse, -) -from .campaign_label_service import ( - CampaignLabelOperation, - MutateCampaignLabelResult, - MutateCampaignLabelsRequest, - MutateCampaignLabelsResponse, -) -from .campaign_lifecycle_goal_service import ( - CampaignLifecycleGoalOperation, - ConfigureCampaignLifecycleGoalsRequest, - ConfigureCampaignLifecycleGoalsResponse, - ConfigureCampaignLifecycleGoalsResult, -) -from .campaign_service import ( - BrandCampaignAssets, - CampaignOperation, - EnablementResult, - EnableOperation, - EnablePMaxBrandGuidelinesRequest, - EnablePMaxBrandGuidelinesResponse, - MutateCampaignResult, - MutateCampaignsRequest, - MutateCampaignsResponse, -) -from .campaign_shared_set_service import ( - CampaignSharedSetOperation, - MutateCampaignSharedSetResult, - MutateCampaignSharedSetsRequest, - MutateCampaignSharedSetsResponse, -) -from .content_creator_insights_service import ( - GenerateCreatorInsightsRequest, - GenerateCreatorInsightsResponse, - GenerateTrendingInsightsRequest, - GenerateTrendingInsightsResponse, - SearchAudience, - SearchTopics, - TrendInsight, - TrendInsightMetrics, - YouTubeChannelInsights, - YouTubeCreatorInsights, - YouTubeMetrics, -) -from .conversion_action_service import ( - ConversionActionOperation, - MutateConversionActionResult, - MutateConversionActionsRequest, - MutateConversionActionsResponse, -) -from .conversion_adjustment_upload_service import ( - ConversionAdjustment, - ConversionAdjustmentResult, - GclidDateTimePair, - RestatementValue, - UploadConversionAdjustmentsRequest, - UploadConversionAdjustmentsResponse, -) -from .conversion_custom_variable_service import ( - ConversionCustomVariableOperation, - MutateConversionCustomVariableResult, - MutateConversionCustomVariablesRequest, - MutateConversionCustomVariablesResponse, -) -from .conversion_goal_campaign_config_service import ( - ConversionGoalCampaignConfigOperation, - MutateConversionGoalCampaignConfigResult, - MutateConversionGoalCampaignConfigsRequest, - MutateConversionGoalCampaignConfigsResponse, -) -from .conversion_upload_service import ( - CallConversion, - CallConversionResult, - CartData, - ClickConversion, - ClickConversionResult, - CustomVariable, - ExternalAttributionData, - SessionAttributeKeyValuePair, - SessionAttributesKeyValuePairs, - UploadCallConversionsRequest, - UploadCallConversionsResponse, - UploadClickConversionsRequest, - UploadClickConversionsResponse, -) -from .conversion_value_rule_service import ( - ConversionValueRuleOperation, - MutateConversionValueRuleResult, - MutateConversionValueRulesRequest, - MutateConversionValueRulesResponse, -) -from .conversion_value_rule_set_service import ( - ConversionValueRuleSetOperation, - MutateConversionValueRuleSetResult, - MutateConversionValueRuleSetsRequest, - MutateConversionValueRuleSetsResponse, -) -from .custom_audience_service import ( - CustomAudienceOperation, - MutateCustomAudienceResult, - MutateCustomAudiencesRequest, - MutateCustomAudiencesResponse, -) -from .custom_conversion_goal_service import ( - CustomConversionGoalOperation, - MutateCustomConversionGoalResult, - MutateCustomConversionGoalsRequest, - MutateCustomConversionGoalsResponse, -) -from .custom_interest_service import ( - CustomInterestOperation, - MutateCustomInterestResult, - MutateCustomInterestsRequest, - MutateCustomInterestsResponse, -) -from .customer_asset_service import ( - CustomerAssetOperation, - MutateCustomerAssetResult, - MutateCustomerAssetsRequest, - MutateCustomerAssetsResponse, -) -from .customer_asset_set_service import ( - CustomerAssetSetOperation, - MutateCustomerAssetSetResult, - MutateCustomerAssetSetsRequest, - MutateCustomerAssetSetsResponse, -) -from .customer_client_link_service import ( - CustomerClientLinkOperation, - MutateCustomerClientLinkRequest, - MutateCustomerClientLinkResponse, - MutateCustomerClientLinkResult, -) -from .customer_conversion_goal_service import ( - CustomerConversionGoalOperation, - MutateCustomerConversionGoalResult, - MutateCustomerConversionGoalsRequest, - MutateCustomerConversionGoalsResponse, -) -from .customer_customizer_service import ( - CustomerCustomizerOperation, - MutateCustomerCustomizerResult, - MutateCustomerCustomizersRequest, - MutateCustomerCustomizersResponse, -) -from .customer_label_service import ( - CustomerLabelOperation, - MutateCustomerLabelResult, - MutateCustomerLabelsRequest, - MutateCustomerLabelsResponse, -) -from .customer_lifecycle_goal_service import ( - ConfigureCustomerLifecycleGoalsRequest, - ConfigureCustomerLifecycleGoalsResponse, - ConfigureCustomerLifecycleGoalsResult, - CustomerLifecycleGoalOperation, -) -from .customer_manager_link_service import ( - CustomerManagerLinkOperation, - MoveManagerLinkRequest, - MoveManagerLinkResponse, - MutateCustomerManagerLinkRequest, - MutateCustomerManagerLinkResponse, - MutateCustomerManagerLinkResult, -) -from .customer_negative_criterion_service import ( - CustomerNegativeCriterionOperation, - MutateCustomerNegativeCriteriaRequest, - MutateCustomerNegativeCriteriaResponse, - MutateCustomerNegativeCriteriaResult, -) -from .customer_service import ( - CreateCustomerClientRequest, - CreateCustomerClientResponse, - CustomerOperation, - ListAccessibleCustomersRequest, - ListAccessibleCustomersResponse, - MutateCustomerRequest, - MutateCustomerResponse, - MutateCustomerResult, -) -from .customer_sk_ad_network_conversion_value_schema_service import ( - CustomerSkAdNetworkConversionValueSchemaOperation, - MutateCustomerSkAdNetworkConversionValueSchemaRequest, - MutateCustomerSkAdNetworkConversionValueSchemaResponse, - MutateCustomerSkAdNetworkConversionValueSchemaResult, -) -from .customer_user_access_invitation_service import ( - CustomerUserAccessInvitationOperation, - MutateCustomerUserAccessInvitationRequest, - MutateCustomerUserAccessInvitationResponse, - MutateCustomerUserAccessInvitationResult, -) -from .customer_user_access_service import ( - CustomerUserAccessOperation, - MutateCustomerUserAccessRequest, - MutateCustomerUserAccessResponse, - MutateCustomerUserAccessResult, -) -from .customizer_attribute_service import ( - CustomizerAttributeOperation, - MutateCustomizerAttributeResult, - MutateCustomizerAttributesRequest, - MutateCustomizerAttributesResponse, -) -from .data_link_service import ( - CreateDataLinkRequest, - CreateDataLinkResponse, - RemoveDataLinkRequest, - RemoveDataLinkResponse, - UpdateDataLinkRequest, - UpdateDataLinkResponse, -) -from .experiment_arm_service import ( - ExperimentArmOperation, - MutateExperimentArmResult, - MutateExperimentArmsRequest, - MutateExperimentArmsResponse, -) -from .experiment_service import ( - CampaignBudgetMapping, - EndExperimentRequest, - ExperimentOperation, - GraduateExperimentRequest, - ListExperimentAsyncErrorsRequest, - ListExperimentAsyncErrorsResponse, - MutateExperimentResult, - MutateExperimentsRequest, - MutateExperimentsResponse, - PromoteExperimentMetadata, - PromoteExperimentRequest, - ScheduleExperimentMetadata, - ScheduleExperimentRequest, -) -from .geo_target_constant_service import ( - GeoTargetConstantSuggestion, - SuggestGeoTargetConstantsRequest, - SuggestGeoTargetConstantsResponse, -) -from .google_ads_field_service import ( - GetGoogleAdsFieldRequest, - SearchGoogleAdsFieldsRequest, - SearchGoogleAdsFieldsResponse, -) -from .google_ads_service import ( - GoogleAdsRow, - MutateGoogleAdsRequest, - MutateGoogleAdsResponse, - MutateOperation, - MutateOperationResponse, - SearchGoogleAdsRequest, - SearchGoogleAdsResponse, - SearchGoogleAdsStreamRequest, - SearchGoogleAdsStreamResponse, - SearchSettings, -) -from .identity_verification_service import ( - GetIdentityVerificationRequest, - GetIdentityVerificationResponse, - IdentityVerification, - IdentityVerificationProgress, - IdentityVerificationRequirement, - StartIdentityVerificationRequest, -) -from .invoice_service import ( - ListInvoicesRequest, - ListInvoicesResponse, -) -from .keyword_plan_ad_group_keyword_service import ( - KeywordPlanAdGroupKeywordOperation, - MutateKeywordPlanAdGroupKeywordResult, - MutateKeywordPlanAdGroupKeywordsRequest, - MutateKeywordPlanAdGroupKeywordsResponse, -) -from .keyword_plan_ad_group_service import ( - KeywordPlanAdGroupOperation, - MutateKeywordPlanAdGroupResult, - MutateKeywordPlanAdGroupsRequest, - MutateKeywordPlanAdGroupsResponse, -) -from .keyword_plan_campaign_keyword_service import ( - KeywordPlanCampaignKeywordOperation, - MutateKeywordPlanCampaignKeywordResult, - MutateKeywordPlanCampaignKeywordsRequest, - MutateKeywordPlanCampaignKeywordsResponse, -) -from .keyword_plan_campaign_service import ( - KeywordPlanCampaignOperation, - MutateKeywordPlanCampaignResult, - MutateKeywordPlanCampaignsRequest, - MutateKeywordPlanCampaignsResponse, -) -from .keyword_plan_idea_service import ( - AdGroupKeywordSuggestion, - BiddableKeyword, - CampaignToForecast, - CriterionBidModifier, - ForecastAdGroup, - GenerateAdGroupThemesRequest, - GenerateAdGroupThemesResponse, - GenerateKeywordForecastMetricsRequest, - GenerateKeywordForecastMetricsResponse, - GenerateKeywordHistoricalMetricsRequest, - GenerateKeywordHistoricalMetricsResponse, - GenerateKeywordHistoricalMetricsResult, - GenerateKeywordIdeaResponse, - GenerateKeywordIdeaResult, - GenerateKeywordIdeasRequest, - KeywordAndUrlSeed, - KeywordForecastMetrics, - KeywordSeed, - ManualCpcBiddingStrategy, - MaximizeClicksBiddingStrategy, - MaximizeConversionsBiddingStrategy, - SiteSeed, - UnusableAdGroup, - UrlSeed, -) -from .keyword_plan_service import ( - KeywordPlanOperation, - MutateKeywordPlansRequest, - MutateKeywordPlansResponse, - MutateKeywordPlansResult, -) -from .keyword_theme_constant_service import ( - SuggestKeywordThemeConstantsRequest, - SuggestKeywordThemeConstantsResponse, -) -from .label_service import ( - LabelOperation, - MutateLabelResult, - MutateLabelsRequest, - MutateLabelsResponse, -) -from .local_services_lead_service import ( - AppendLeadConversationRequest, - AppendLeadConversationResponse, - Conversation, - ConversationOrError, - ProvideLeadFeedbackRequest, - ProvideLeadFeedbackResponse, - SurveyDissatisfied, - SurveySatisfied, -) -from .offline_user_data_job_service import ( - AddOfflineUserDataJobOperationsRequest, - AddOfflineUserDataJobOperationsResponse, - CreateOfflineUserDataJobRequest, - CreateOfflineUserDataJobResponse, - OfflineUserDataJobOperation, - RunOfflineUserDataJobRequest, -) -from .payments_account_service import ( - ListPaymentsAccountsRequest, - ListPaymentsAccountsResponse, -) -from .product_link_invitation_service import ( - CreateProductLinkInvitationRequest, - CreateProductLinkInvitationResponse, - RemoveProductLinkInvitationRequest, - RemoveProductLinkInvitationResponse, - UpdateProductLinkInvitationRequest, - UpdateProductLinkInvitationResponse, -) -from .product_link_service import ( - CreateProductLinkRequest, - CreateProductLinkResponse, - RemoveProductLinkRequest, - RemoveProductLinkResponse, -) -from .reach_plan_service import ( - AdvancedProductTargeting, - AudienceTargeting, - CampaignDuration, - ConversionRateSuggestion, - EffectiveFrequencyBreakdown, - EffectiveFrequencyLimit, - Forecast, - ForecastMetricOptions, - FrequencyCap, - GenerateConversionRatesRequest, - GenerateConversionRatesResponse, - GenerateReachForecastRequest, - GenerateReachForecastResponse, - ListPlannableLocationsRequest, - ListPlannableLocationsResponse, - ListPlannableProductsRequest, - ListPlannableProductsResponse, - OnTargetAudienceMetrics, - PlannableLocation, - PlannableTargeting, - PlannedProduct, - PlannedProductForecast, - PlannedProductReachForecast, - ProductMetadata, - ReachCurve, - ReachForecast, - SurfaceTargeting, - SurfaceTargetingCombinations, - TargetFrequencySettings, - Targeting, - YouTubeSelectLineUp, - YouTubeSelectSettings, -) -from .recommendation_service import ( - ApplyRecommendationOperation, - ApplyRecommendationRequest, - ApplyRecommendationResponse, - ApplyRecommendationResult, - DismissRecommendationRequest, - DismissRecommendationResponse, - GenerateRecommendationsRequest, - GenerateRecommendationsResponse, -) -from .recommendation_subscription_service import ( - MutateRecommendationSubscriptionRequest, - MutateRecommendationSubscriptionResponse, - MutateRecommendationSubscriptionResult, - RecommendationSubscriptionOperation, -) -from .remarketing_action_service import ( - MutateRemarketingActionResult, - MutateRemarketingActionsRequest, - MutateRemarketingActionsResponse, - RemarketingActionOperation, -) -from .shareable_preview_service import ( - AssetGroupIdentifier, - GenerateShareablePreviewsRequest, - GenerateShareablePreviewsResponse, - ShareablePreview, - ShareablePreviewOrError, - ShareablePreviewResult, -) -from .shared_criterion_service import ( - MutateSharedCriteriaRequest, - MutateSharedCriteriaResponse, - MutateSharedCriterionResult, - SharedCriterionOperation, -) -from .shared_set_service import ( - MutateSharedSetResult, - MutateSharedSetsRequest, - MutateSharedSetsResponse, - SharedSetOperation, -) -from .smart_campaign_setting_service import ( - GetSmartCampaignStatusRequest, - GetSmartCampaignStatusResponse, - MutateSmartCampaignSettingResult, - MutateSmartCampaignSettingsRequest, - MutateSmartCampaignSettingsResponse, - SmartCampaignEligibleDetails, - SmartCampaignEndedDetails, - SmartCampaignNotEligibleDetails, - SmartCampaignPausedDetails, - SmartCampaignRemovedDetails, - SmartCampaignSettingOperation, -) -from .smart_campaign_suggest_service import ( - SmartCampaignSuggestionInfo, - SuggestKeywordThemesRequest, - SuggestKeywordThemesResponse, - SuggestSmartCampaignAdRequest, - SuggestSmartCampaignAdResponse, - SuggestSmartCampaignBudgetOptionsRequest, - SuggestSmartCampaignBudgetOptionsResponse, -) -from .third_party_app_analytics_link_service import ( - RegenerateShareableLinkIdRequest, - RegenerateShareableLinkIdResponse, -) -from .travel_asset_suggestion_service import ( - HotelAssetSuggestion, - HotelImageAsset, - HotelTextAsset, - SuggestTravelAssetsRequest, - SuggestTravelAssetsResponse, -) -from .user_data_service import ( - UploadUserDataRequest, - UploadUserDataResponse, - UserDataOperation, -) -from .user_list_customer_type_service import ( - MutateUserListCustomerTypeResult, - MutateUserListCustomerTypesRequest, - MutateUserListCustomerTypesResponse, - UserListCustomerTypeOperation, -) -from .user_list_service import ( - MutateUserListResult, - MutateUserListsRequest, - MutateUserListsResponse, - UserListOperation, -) - -__all__ = ( - "AccountBudgetProposalOperation", - "MutateAccountBudgetProposalRequest", - "MutateAccountBudgetProposalResponse", - "MutateAccountBudgetProposalResult", - "AccountLinkOperation", - "CreateAccountLinkRequest", - "CreateAccountLinkResponse", - "MutateAccountLinkRequest", - "MutateAccountLinkResponse", - "MutateAccountLinkResult", - "AdGroupAdLabelOperation", - "MutateAdGroupAdLabelResult", - "MutateAdGroupAdLabelsRequest", - "MutateAdGroupAdLabelsResponse", - "AdGroupAdOperation", - "AssetsWithFieldType", - "MutateAdGroupAdResult", - "MutateAdGroupAdsRequest", - "MutateAdGroupAdsResponse", - "RemoveAutomaticallyCreatedAssetsRequest", - "AdGroupAssetOperation", - "MutateAdGroupAssetResult", - "MutateAdGroupAssetsRequest", - "MutateAdGroupAssetsResponse", - "AdGroupAssetSetOperation", - "MutateAdGroupAssetSetResult", - "MutateAdGroupAssetSetsRequest", - "MutateAdGroupAssetSetsResponse", - "AdGroupBidModifierOperation", - "MutateAdGroupBidModifierResult", - "MutateAdGroupBidModifiersRequest", - "MutateAdGroupBidModifiersResponse", - "AdGroupCriterionCustomizerOperation", - "MutateAdGroupCriterionCustomizerResult", - "MutateAdGroupCriterionCustomizersRequest", - "MutateAdGroupCriterionCustomizersResponse", - "AdGroupCriterionLabelOperation", - "MutateAdGroupCriterionLabelResult", - "MutateAdGroupCriterionLabelsRequest", - "MutateAdGroupCriterionLabelsResponse", - "AdGroupCriterionOperation", - "MutateAdGroupCriteriaRequest", - "MutateAdGroupCriteriaResponse", - "MutateAdGroupCriterionResult", - "AdGroupCustomizerOperation", - "MutateAdGroupCustomizerResult", - "MutateAdGroupCustomizersRequest", - "MutateAdGroupCustomizersResponse", - "AdGroupLabelOperation", - "MutateAdGroupLabelResult", - "MutateAdGroupLabelsRequest", - "MutateAdGroupLabelsResponse", - "AdGroupOperation", - "MutateAdGroupResult", - "MutateAdGroupsRequest", - "MutateAdGroupsResponse", - "AdParameterOperation", - "MutateAdParameterResult", - "MutateAdParametersRequest", - "MutateAdParametersResponse", - "AdOperation", - "MutateAdResult", - "MutateAdsRequest", - "MutateAdsResponse", - "AssetGroupAssetOperation", - "MutateAssetGroupAssetResult", - "MutateAssetGroupAssetsRequest", - "MutateAssetGroupAssetsResponse", - "AssetGroupListingGroupFilterOperation", - "MutateAssetGroupListingGroupFilterResult", - "MutateAssetGroupListingGroupFiltersRequest", - "MutateAssetGroupListingGroupFiltersResponse", - "AssetGroupOperation", - "MutateAssetGroupResult", - "MutateAssetGroupsRequest", - "MutateAssetGroupsResponse", - "AssetGroupSignalOperation", - "MutateAssetGroupSignalResult", - "MutateAssetGroupSignalsRequest", - "MutateAssetGroupSignalsResponse", - "AssetOperation", - "MutateAssetResult", - "MutateAssetsRequest", - "MutateAssetsResponse", - "AssetSetAssetOperation", - "MutateAssetSetAssetResult", - "MutateAssetSetAssetsRequest", - "MutateAssetSetAssetsResponse", - "AssetSetOperation", - "MutateAssetSetResult", - "MutateAssetSetsRequest", - "MutateAssetSetsResponse", - "AudienceCompositionAttribute", - "AudienceCompositionAttributeCluster", - "AudienceCompositionMetrics", - "AudienceCompositionSection", - "AudienceOverlapItem", - "BasicInsightsAudience", - "DimensionOverlapResult", - "GenerateAudienceCompositionInsightsRequest", - "GenerateAudienceCompositionInsightsResponse", - "GenerateAudienceOverlapInsightsRequest", - "GenerateAudienceOverlapInsightsResponse", - "GenerateInsightsFinderReportRequest", - "GenerateInsightsFinderReportResponse", - "GenerateSuggestedTargetingInsightsRequest", - "GenerateSuggestedTargetingInsightsResponse", - "GenerateTargetingSuggestionMetricsRequest", - "GenerateTargetingSuggestionMetricsResponse", - "InsightsAudience", - "InsightsAudienceAttributeGroup", - "InsightsAudienceDefinition", - "InsightsAudienceDescription", - "ListAudienceInsightsAttributesRequest", - "ListAudienceInsightsAttributesResponse", - "ListInsightsEligibleDatesRequest", - "ListInsightsEligibleDatesResponse", - "TargetingSuggestionMetrics", - "AudienceOperation", - "MutateAudienceResult", - "MutateAudiencesRequest", - "MutateAudiencesResponse", - "AddBatchJobOperationsRequest", - "AddBatchJobOperationsResponse", - "BatchJobOperation", - "BatchJobResult", - "ListBatchJobResultsRequest", - "ListBatchJobResultsResponse", - "MutateBatchJobRequest", - "MutateBatchJobResponse", - "MutateBatchJobResult", - "RunBatchJobRequest", - "BiddingDataExclusionOperation", - "MutateBiddingDataExclusionsRequest", - "MutateBiddingDataExclusionsResponse", - "MutateBiddingDataExclusionsResult", - "BiddingSeasonalityAdjustmentOperation", - "MutateBiddingSeasonalityAdjustmentsRequest", - "MutateBiddingSeasonalityAdjustmentsResponse", - "MutateBiddingSeasonalityAdjustmentsResult", - "BiddingStrategyOperation", - "MutateBiddingStrategiesRequest", - "MutateBiddingStrategiesResponse", - "MutateBiddingStrategyResult", - "BillingSetupOperation", - "MutateBillingSetupRequest", - "MutateBillingSetupResponse", - "MutateBillingSetupResult", - "BrandSuggestion", - "SuggestBrandsRequest", - "SuggestBrandsResponse", - "CampaignAssetOperation", - "MutateCampaignAssetResult", - "MutateCampaignAssetsRequest", - "MutateCampaignAssetsResponse", - "CampaignAssetSetOperation", - "MutateCampaignAssetSetResult", - "MutateCampaignAssetSetsRequest", - "MutateCampaignAssetSetsResponse", - "CampaignBidModifierOperation", - "MutateCampaignBidModifierResult", - "MutateCampaignBidModifiersRequest", - "MutateCampaignBidModifiersResponse", - "CampaignBudgetOperation", - "MutateCampaignBudgetResult", - "MutateCampaignBudgetsRequest", - "MutateCampaignBudgetsResponse", - "CampaignConversionGoalOperation", - "MutateCampaignConversionGoalResult", - "MutateCampaignConversionGoalsRequest", - "MutateCampaignConversionGoalsResponse", - "CampaignCriterionOperation", - "MutateCampaignCriteriaRequest", - "MutateCampaignCriteriaResponse", - "MutateCampaignCriterionResult", - "CampaignCustomizerOperation", - "MutateCampaignCustomizerResult", - "MutateCampaignCustomizersRequest", - "MutateCampaignCustomizersResponse", - "CampaignDraftOperation", - "ListCampaignDraftAsyncErrorsRequest", - "ListCampaignDraftAsyncErrorsResponse", - "MutateCampaignDraftResult", - "MutateCampaignDraftsRequest", - "MutateCampaignDraftsResponse", - "PromoteCampaignDraftRequest", - "CampaignGroupOperation", - "MutateCampaignGroupResult", - "MutateCampaignGroupsRequest", - "MutateCampaignGroupsResponse", - "CampaignLabelOperation", - "MutateCampaignLabelResult", - "MutateCampaignLabelsRequest", - "MutateCampaignLabelsResponse", - "CampaignLifecycleGoalOperation", - "ConfigureCampaignLifecycleGoalsRequest", - "ConfigureCampaignLifecycleGoalsResponse", - "ConfigureCampaignLifecycleGoalsResult", - "BrandCampaignAssets", - "CampaignOperation", - "EnablementResult", - "EnableOperation", - "EnablePMaxBrandGuidelinesRequest", - "EnablePMaxBrandGuidelinesResponse", - "MutateCampaignResult", - "MutateCampaignsRequest", - "MutateCampaignsResponse", - "CampaignSharedSetOperation", - "MutateCampaignSharedSetResult", - "MutateCampaignSharedSetsRequest", - "MutateCampaignSharedSetsResponse", - "GenerateCreatorInsightsRequest", - "GenerateCreatorInsightsResponse", - "GenerateTrendingInsightsRequest", - "GenerateTrendingInsightsResponse", - "SearchAudience", - "SearchTopics", - "TrendInsight", - "TrendInsightMetrics", - "YouTubeChannelInsights", - "YouTubeCreatorInsights", - "YouTubeMetrics", - "ConversionActionOperation", - "MutateConversionActionResult", - "MutateConversionActionsRequest", - "MutateConversionActionsResponse", - "ConversionAdjustment", - "ConversionAdjustmentResult", - "GclidDateTimePair", - "RestatementValue", - "UploadConversionAdjustmentsRequest", - "UploadConversionAdjustmentsResponse", - "ConversionCustomVariableOperation", - "MutateConversionCustomVariableResult", - "MutateConversionCustomVariablesRequest", - "MutateConversionCustomVariablesResponse", - "ConversionGoalCampaignConfigOperation", - "MutateConversionGoalCampaignConfigResult", - "MutateConversionGoalCampaignConfigsRequest", - "MutateConversionGoalCampaignConfigsResponse", - "CallConversion", - "CallConversionResult", - "CartData", - "ClickConversion", - "ClickConversionResult", - "CustomVariable", - "ExternalAttributionData", - "SessionAttributeKeyValuePair", - "SessionAttributesKeyValuePairs", - "UploadCallConversionsRequest", - "UploadCallConversionsResponse", - "UploadClickConversionsRequest", - "UploadClickConversionsResponse", - "ConversionValueRuleOperation", - "MutateConversionValueRuleResult", - "MutateConversionValueRulesRequest", - "MutateConversionValueRulesResponse", - "ConversionValueRuleSetOperation", - "MutateConversionValueRuleSetResult", - "MutateConversionValueRuleSetsRequest", - "MutateConversionValueRuleSetsResponse", - "CustomAudienceOperation", - "MutateCustomAudienceResult", - "MutateCustomAudiencesRequest", - "MutateCustomAudiencesResponse", - "CustomConversionGoalOperation", - "MutateCustomConversionGoalResult", - "MutateCustomConversionGoalsRequest", - "MutateCustomConversionGoalsResponse", - "CustomInterestOperation", - "MutateCustomInterestResult", - "MutateCustomInterestsRequest", - "MutateCustomInterestsResponse", - "CustomerAssetOperation", - "MutateCustomerAssetResult", - "MutateCustomerAssetsRequest", - "MutateCustomerAssetsResponse", - "CustomerAssetSetOperation", - "MutateCustomerAssetSetResult", - "MutateCustomerAssetSetsRequest", - "MutateCustomerAssetSetsResponse", - "CustomerClientLinkOperation", - "MutateCustomerClientLinkRequest", - "MutateCustomerClientLinkResponse", - "MutateCustomerClientLinkResult", - "CustomerConversionGoalOperation", - "MutateCustomerConversionGoalResult", - "MutateCustomerConversionGoalsRequest", - "MutateCustomerConversionGoalsResponse", - "CustomerCustomizerOperation", - "MutateCustomerCustomizerResult", - "MutateCustomerCustomizersRequest", - "MutateCustomerCustomizersResponse", - "CustomerLabelOperation", - "MutateCustomerLabelResult", - "MutateCustomerLabelsRequest", - "MutateCustomerLabelsResponse", - "ConfigureCustomerLifecycleGoalsRequest", - "ConfigureCustomerLifecycleGoalsResponse", - "ConfigureCustomerLifecycleGoalsResult", - "CustomerLifecycleGoalOperation", - "CustomerManagerLinkOperation", - "MoveManagerLinkRequest", - "MoveManagerLinkResponse", - "MutateCustomerManagerLinkRequest", - "MutateCustomerManagerLinkResponse", - "MutateCustomerManagerLinkResult", - "CustomerNegativeCriterionOperation", - "MutateCustomerNegativeCriteriaRequest", - "MutateCustomerNegativeCriteriaResponse", - "MutateCustomerNegativeCriteriaResult", - "CreateCustomerClientRequest", - "CreateCustomerClientResponse", - "CustomerOperation", - "ListAccessibleCustomersRequest", - "ListAccessibleCustomersResponse", - "MutateCustomerRequest", - "MutateCustomerResponse", - "MutateCustomerResult", - "CustomerSkAdNetworkConversionValueSchemaOperation", - "MutateCustomerSkAdNetworkConversionValueSchemaRequest", - "MutateCustomerSkAdNetworkConversionValueSchemaResponse", - "MutateCustomerSkAdNetworkConversionValueSchemaResult", - "CustomerUserAccessInvitationOperation", - "MutateCustomerUserAccessInvitationRequest", - "MutateCustomerUserAccessInvitationResponse", - "MutateCustomerUserAccessInvitationResult", - "CustomerUserAccessOperation", - "MutateCustomerUserAccessRequest", - "MutateCustomerUserAccessResponse", - "MutateCustomerUserAccessResult", - "CustomizerAttributeOperation", - "MutateCustomizerAttributeResult", - "MutateCustomizerAttributesRequest", - "MutateCustomizerAttributesResponse", - "CreateDataLinkRequest", - "CreateDataLinkResponse", - "RemoveDataLinkRequest", - "RemoveDataLinkResponse", - "UpdateDataLinkRequest", - "UpdateDataLinkResponse", - "ExperimentArmOperation", - "MutateExperimentArmResult", - "MutateExperimentArmsRequest", - "MutateExperimentArmsResponse", - "CampaignBudgetMapping", - "EndExperimentRequest", - "ExperimentOperation", - "GraduateExperimentRequest", - "ListExperimentAsyncErrorsRequest", - "ListExperimentAsyncErrorsResponse", - "MutateExperimentResult", - "MutateExperimentsRequest", - "MutateExperimentsResponse", - "PromoteExperimentMetadata", - "PromoteExperimentRequest", - "ScheduleExperimentMetadata", - "ScheduleExperimentRequest", - "GeoTargetConstantSuggestion", - "SuggestGeoTargetConstantsRequest", - "SuggestGeoTargetConstantsResponse", - "GetGoogleAdsFieldRequest", - "SearchGoogleAdsFieldsRequest", - "SearchGoogleAdsFieldsResponse", - "GoogleAdsRow", - "MutateGoogleAdsRequest", - "MutateGoogleAdsResponse", - "MutateOperation", - "MutateOperationResponse", - "SearchGoogleAdsRequest", - "SearchGoogleAdsResponse", - "SearchGoogleAdsStreamRequest", - "SearchGoogleAdsStreamResponse", - "SearchSettings", - "GetIdentityVerificationRequest", - "GetIdentityVerificationResponse", - "IdentityVerification", - "IdentityVerificationProgress", - "IdentityVerificationRequirement", - "StartIdentityVerificationRequest", - "ListInvoicesRequest", - "ListInvoicesResponse", - "KeywordPlanAdGroupKeywordOperation", - "MutateKeywordPlanAdGroupKeywordResult", - "MutateKeywordPlanAdGroupKeywordsRequest", - "MutateKeywordPlanAdGroupKeywordsResponse", - "KeywordPlanAdGroupOperation", - "MutateKeywordPlanAdGroupResult", - "MutateKeywordPlanAdGroupsRequest", - "MutateKeywordPlanAdGroupsResponse", - "KeywordPlanCampaignKeywordOperation", - "MutateKeywordPlanCampaignKeywordResult", - "MutateKeywordPlanCampaignKeywordsRequest", - "MutateKeywordPlanCampaignKeywordsResponse", - "KeywordPlanCampaignOperation", - "MutateKeywordPlanCampaignResult", - "MutateKeywordPlanCampaignsRequest", - "MutateKeywordPlanCampaignsResponse", - "AdGroupKeywordSuggestion", - "BiddableKeyword", - "CampaignToForecast", - "CriterionBidModifier", - "ForecastAdGroup", - "GenerateAdGroupThemesRequest", - "GenerateAdGroupThemesResponse", - "GenerateKeywordForecastMetricsRequest", - "GenerateKeywordForecastMetricsResponse", - "GenerateKeywordHistoricalMetricsRequest", - "GenerateKeywordHistoricalMetricsResponse", - "GenerateKeywordHistoricalMetricsResult", - "GenerateKeywordIdeaResponse", - "GenerateKeywordIdeaResult", - "GenerateKeywordIdeasRequest", - "KeywordAndUrlSeed", - "KeywordForecastMetrics", - "KeywordSeed", - "ManualCpcBiddingStrategy", - "MaximizeClicksBiddingStrategy", - "MaximizeConversionsBiddingStrategy", - "SiteSeed", - "UnusableAdGroup", - "UrlSeed", - "KeywordPlanOperation", - "MutateKeywordPlansRequest", - "MutateKeywordPlansResponse", - "MutateKeywordPlansResult", - "SuggestKeywordThemeConstantsRequest", - "SuggestKeywordThemeConstantsResponse", - "LabelOperation", - "MutateLabelResult", - "MutateLabelsRequest", - "MutateLabelsResponse", - "AppendLeadConversationRequest", - "AppendLeadConversationResponse", - "Conversation", - "ConversationOrError", - "ProvideLeadFeedbackRequest", - "ProvideLeadFeedbackResponse", - "SurveyDissatisfied", - "SurveySatisfied", - "AddOfflineUserDataJobOperationsRequest", - "AddOfflineUserDataJobOperationsResponse", - "CreateOfflineUserDataJobRequest", - "CreateOfflineUserDataJobResponse", - "OfflineUserDataJobOperation", - "RunOfflineUserDataJobRequest", - "ListPaymentsAccountsRequest", - "ListPaymentsAccountsResponse", - "CreateProductLinkInvitationRequest", - "CreateProductLinkInvitationResponse", - "RemoveProductLinkInvitationRequest", - "RemoveProductLinkInvitationResponse", - "UpdateProductLinkInvitationRequest", - "UpdateProductLinkInvitationResponse", - "CreateProductLinkRequest", - "CreateProductLinkResponse", - "RemoveProductLinkRequest", - "RemoveProductLinkResponse", - "AdvancedProductTargeting", - "AudienceTargeting", - "CampaignDuration", - "ConversionRateSuggestion", - "EffectiveFrequencyBreakdown", - "EffectiveFrequencyLimit", - "Forecast", - "ForecastMetricOptions", - "FrequencyCap", - "GenerateConversionRatesRequest", - "GenerateConversionRatesResponse", - "GenerateReachForecastRequest", - "GenerateReachForecastResponse", - "ListPlannableLocationsRequest", - "ListPlannableLocationsResponse", - "ListPlannableProductsRequest", - "ListPlannableProductsResponse", - "OnTargetAudienceMetrics", - "PlannableLocation", - "PlannableTargeting", - "PlannedProduct", - "PlannedProductForecast", - "PlannedProductReachForecast", - "ProductMetadata", - "ReachCurve", - "ReachForecast", - "SurfaceTargeting", - "SurfaceTargetingCombinations", - "TargetFrequencySettings", - "Targeting", - "YouTubeSelectLineUp", - "YouTubeSelectSettings", - "ApplyRecommendationOperation", - "ApplyRecommendationRequest", - "ApplyRecommendationResponse", - "ApplyRecommendationResult", - "DismissRecommendationRequest", - "DismissRecommendationResponse", - "GenerateRecommendationsRequest", - "GenerateRecommendationsResponse", - "MutateRecommendationSubscriptionRequest", - "MutateRecommendationSubscriptionResponse", - "MutateRecommendationSubscriptionResult", - "RecommendationSubscriptionOperation", - "MutateRemarketingActionResult", - "MutateRemarketingActionsRequest", - "MutateRemarketingActionsResponse", - "RemarketingActionOperation", - "AssetGroupIdentifier", - "GenerateShareablePreviewsRequest", - "GenerateShareablePreviewsResponse", - "ShareablePreview", - "ShareablePreviewOrError", - "ShareablePreviewResult", - "MutateSharedCriteriaRequest", - "MutateSharedCriteriaResponse", - "MutateSharedCriterionResult", - "SharedCriterionOperation", - "MutateSharedSetResult", - "MutateSharedSetsRequest", - "MutateSharedSetsResponse", - "SharedSetOperation", - "GetSmartCampaignStatusRequest", - "GetSmartCampaignStatusResponse", - "MutateSmartCampaignSettingResult", - "MutateSmartCampaignSettingsRequest", - "MutateSmartCampaignSettingsResponse", - "SmartCampaignEligibleDetails", - "SmartCampaignEndedDetails", - "SmartCampaignNotEligibleDetails", - "SmartCampaignPausedDetails", - "SmartCampaignRemovedDetails", - "SmartCampaignSettingOperation", - "SmartCampaignSuggestionInfo", - "SuggestKeywordThemesRequest", - "SuggestKeywordThemesResponse", - "SuggestSmartCampaignAdRequest", - "SuggestSmartCampaignAdResponse", - "SuggestSmartCampaignBudgetOptionsRequest", - "SuggestSmartCampaignBudgetOptionsResponse", - "RegenerateShareableLinkIdRequest", - "RegenerateShareableLinkIdResponse", - "HotelAssetSuggestion", - "HotelImageAsset", - "HotelTextAsset", - "SuggestTravelAssetsRequest", - "SuggestTravelAssetsResponse", - "UploadUserDataRequest", - "UploadUserDataResponse", - "UserDataOperation", - "MutateUserListCustomerTypeResult", - "MutateUserListCustomerTypesRequest", - "MutateUserListCustomerTypesResponse", - "UserListCustomerTypeOperation", - "MutateUserListResult", - "MutateUserListsRequest", - "MutateUserListsResponse", - "UserListOperation", -) diff --git a/google/ads/googleads/v19/services/types/audience_insights_service.py b/google/ads/googleads/v19/services/types/audience_insights_service.py deleted file mode 100644 index 1d176885b..000000000 --- a/google/ads/googleads/v19/services/types/audience_insights_service.py +++ /dev/null @@ -1,1068 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -from typing import MutableSequence - -import proto # type: ignore - -from google.ads.googleads.v19.common.types import audience_insights_attribute -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.common.types import dates -from google.ads.googleads.v19.enums.types import audience_insights_dimension -from google.ads.googleads.v19.enums.types import ( - audience_insights_marketing_objective, -) - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", - manifest={ - "GenerateInsightsFinderReportRequest", - "GenerateInsightsFinderReportResponse", - "GenerateAudienceCompositionInsightsRequest", - "GenerateAudienceCompositionInsightsResponse", - "GenerateSuggestedTargetingInsightsRequest", - "GenerateSuggestedTargetingInsightsResponse", - "TargetingSuggestionMetrics", - "ListAudienceInsightsAttributesRequest", - "ListAudienceInsightsAttributesResponse", - "ListInsightsEligibleDatesRequest", - "ListInsightsEligibleDatesResponse", - "GenerateAudienceOverlapInsightsRequest", - "GenerateAudienceOverlapInsightsResponse", - "DimensionOverlapResult", - "AudienceOverlapItem", - "GenerateTargetingSuggestionMetricsRequest", - "GenerateTargetingSuggestionMetricsResponse", - "BasicInsightsAudience", - "InsightsAudienceDefinition", - "InsightsAudienceDescription", - "InsightsAudience", - "InsightsAudienceAttributeGroup", - "AudienceCompositionSection", - "AudienceCompositionAttributeCluster", - "AudienceCompositionMetrics", - "AudienceCompositionAttribute", - }, -) - - -class GenerateInsightsFinderReportRequest(proto.Message): - r"""Request message for - [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v19.services.AudienceInsightsService.GenerateInsightsFinderReport]. - - Attributes: - customer_id (str): - Required. The ID of the customer. - baseline_audience (google.ads.googleads.v19.services.types.BasicInsightsAudience): - Required. A baseline audience for this - report, typically all people in a region. - specific_audience (google.ads.googleads.v19.services.types.BasicInsightsAudience): - Required. The specific audience of interest - for this report. The insights in the report - will be based on attributes more prevalent in - this audience than in the report's baseline - audience. - customer_insights_group (str): - The name of the customer being planned for. - This is a user-defined value. - """ - - customer_id: str = proto.Field( - proto.STRING, - number=1, - ) - baseline_audience: "BasicInsightsAudience" = proto.Field( - proto.MESSAGE, - number=2, - message="BasicInsightsAudience", - ) - specific_audience: "BasicInsightsAudience" = proto.Field( - proto.MESSAGE, - number=3, - message="BasicInsightsAudience", - ) - customer_insights_group: str = proto.Field( - proto.STRING, - number=4, - ) - - -class GenerateInsightsFinderReportResponse(proto.Message): - r"""The response message for - [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v19.services.AudienceInsightsService.GenerateInsightsFinderReport], - containing the shareable URL for the report. - - Attributes: - saved_report_url (str): - An HTTPS URL providing a deep link into the - Insights Finder UI with the report inputs filled - in according to the request. - """ - - saved_report_url: str = proto.Field( - proto.STRING, - number=1, - ) - - -class GenerateAudienceCompositionInsightsRequest(proto.Message): - r"""Request message for - [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. - - Attributes: - customer_id (str): - Required. The ID of the customer. - audience (google.ads.googleads.v19.services.types.InsightsAudience): - Required. The audience of interest for which - insights are being requested. - baseline_audience (google.ads.googleads.v19.services.types.InsightsAudience): - The baseline audience to which the audience - of interest is being compared. - data_month (str): - The one-month range of historical data to use - for insights, in the format "yyyy-mm". If unset, - insights will be returned for the last thirty - days of data. - dimensions (MutableSequence[google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): - Required. The audience dimensions for which composition - insights should be returned. Supported dimensions are - KNOWLEDGE_GRAPH, GEO_TARGET_COUNTRY, SUB_COUNTRY_LOCATION, - YOUTUBE_CHANNEL, YOUTUBE_DYNAMIC_LINEUP, - AFFINITY_USER_INTEREST, IN_MARKET_USER_INTEREST, - PARENTAL_STATUS, INCOME_RANGE, AGE_RANGE, and GENDER. - customer_insights_group (str): - The name of the customer being planned for. - This is a user-defined value. - """ - - customer_id: str = proto.Field( - proto.STRING, - number=1, - ) - audience: "InsightsAudience" = proto.Field( - proto.MESSAGE, - number=2, - message="InsightsAudience", - ) - baseline_audience: "InsightsAudience" = proto.Field( - proto.MESSAGE, - number=6, - message="InsightsAudience", - ) - data_month: str = proto.Field( - proto.STRING, - number=3, - ) - dimensions: MutableSequence[ - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ] = proto.RepeatedField( - proto.ENUM, - number=4, - enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, - ) - customer_insights_group: str = proto.Field( - proto.STRING, - number=5, - ) - - -class GenerateAudienceCompositionInsightsResponse(proto.Message): - r"""Response message for - [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. - - Attributes: - sections (MutableSequence[google.ads.googleads.v19.services.types.AudienceCompositionSection]): - The contents of the insights report, - organized into sections. Each section is - associated with one of the - AudienceInsightsDimension values in the request. - There may be more than one section per - dimension. - """ - - sections: MutableSequence["AudienceCompositionSection"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message="AudienceCompositionSection", - ) - ) - - -class GenerateSuggestedTargetingInsightsRequest(proto.Message): - r"""Request message for - [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - customer_id (str): - Required. The ID of the customer. - customer_insights_group (str): - Optional. The name of the customer being - planned for. This is a user-defined value. - audience_definition (google.ads.googleads.v19.services.types.InsightsAudienceDefinition): - Provide a seed audience to get suggestions - for. - - This field is a member of `oneof`_ ``audience_input``. - audience_description (google.ads.googleads.v19.services.types.InsightsAudienceDescription): - Provide a text description of an audience to - get AI-generated targeting suggestions. This can - take around 5 or more seconds to complete. - - This field is a member of `oneof`_ ``audience_input``. - """ - - customer_id: str = proto.Field( - proto.STRING, - number=1, - ) - customer_insights_group: str = proto.Field( - proto.STRING, - number=5, - ) - audience_definition: "InsightsAudienceDefinition" = proto.Field( - proto.MESSAGE, - number=6, - oneof="audience_input", - message="InsightsAudienceDefinition", - ) - audience_description: "InsightsAudienceDescription" = proto.Field( - proto.MESSAGE, - number=7, - oneof="audience_input", - message="InsightsAudienceDescription", - ) - - -class GenerateSuggestedTargetingInsightsResponse(proto.Message): - r"""Response message for - [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. - - Attributes: - suggestions (MutableSequence[google.ads.googleads.v19.services.types.TargetingSuggestionMetrics]): - Suggested insights for targetable audiences. - """ - - suggestions: MutableSequence["TargetingSuggestionMetrics"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message="TargetingSuggestionMetrics", - ) - ) - - -class TargetingSuggestionMetrics(proto.Message): - r"""A suggested targetable audience relevant to the requested - audience. - - Attributes: - locations (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsAttributeMetadata]): - Suggested location targeting. These attributes all have - dimension GEO_TARGET_COUNTRY or SUB_COUNTRY_LOCATION - age_ranges (MutableSequence[google.ads.googleads.v19.common.types.AgeRangeInfo]): - Suggested age targeting; may be empty - indicating no age targeting. - gender (google.ads.googleads.v19.common.types.GenderInfo): - Suggested gender targeting. If present, this - attribute has dimension GENDER. - parental_status (google.ads.googleads.v19.common.types.ParentalStatusInfo): - A Parental Status value (parent, or not a - parent). - user_interests (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsAttributeMetadata]): - Suggested audience segments to target. These attributes all - have dimension AFFINITY_USER_INTEREST or - IN_MARKET_USER_INTEREST - coverage (float): - The fraction (from 0 to 1 inclusive) of the - requested audience that can be reached using the - suggested targeting. - index (float): - The ratio of coverage to the coverage of the - baseline audience or zero if this ratio is - undefined or is not meaningful. - potential_youtube_reach (int): - The approximate estimated number of people - that can be reached on YouTube using this - targeting. - """ - - locations: MutableSequence[ - audience_insights_attribute.AudienceInsightsAttributeMetadata - ] = proto.RepeatedField( - proto.MESSAGE, - number=9, - message=audience_insights_attribute.AudienceInsightsAttributeMetadata, - ) - age_ranges: MutableSequence[criteria.AgeRangeInfo] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=criteria.AgeRangeInfo, - ) - gender: criteria.GenderInfo = proto.Field( - proto.MESSAGE, - number=3, - message=criteria.GenderInfo, - ) - parental_status: criteria.ParentalStatusInfo = proto.Field( - proto.MESSAGE, - number=8, - message=criteria.ParentalStatusInfo, - ) - user_interests: MutableSequence[ - audience_insights_attribute.AudienceInsightsAttributeMetadata - ] = proto.RepeatedField( - proto.MESSAGE, - number=10, - message=audience_insights_attribute.AudienceInsightsAttributeMetadata, - ) - coverage: float = proto.Field( - proto.DOUBLE, - number=5, - ) - index: float = proto.Field( - proto.DOUBLE, - number=6, - ) - potential_youtube_reach: int = proto.Field( - proto.INT64, - number=7, - ) - - -class ListAudienceInsightsAttributesRequest(proto.Message): - r"""Request message for - [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v19.services.AudienceInsightsService.ListAudienceInsightsAttributes]. - - Attributes: - customer_id (str): - Required. The ID of the customer. - dimensions (MutableSequence[google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): - Required. The types of attributes to be returned. Supported - dimensions are CATEGORY, KNOWLEDGE_GRAPH, - GEO_TARGET_COUNTRY, SUB_COUNTRY_LOCATION, - YOUTUBE_DYNAMIC_LINEUP, AFFINITY_USER_INTEREST, - IN_MARKET_USER_INTEREST, PARENTAL_STATUS, INCOME_RANGE, - AGE_RANGE, and GENDER. - query_text (str): - Required. A free text query. If the requested dimensions - include Attributes CATEGORY or KNOWLEDGE_GRAPH, then the - attributes returned for those dimensions will match or be - related to this string. For other dimensions, this field is - ignored and all available attributes are returned. - customer_insights_group (str): - The name of the customer being planned for. - This is a user-defined value. - location_country_filters (MutableSequence[google.ads.googleads.v19.common.types.LocationInfo]): - If SUB_COUNTRY_LOCATION attributes are one of the requested - dimensions and this field is present, then the - SUB_COUNTRY_LOCATION attributes returned will be located in - these countries. If this field is absent, then location - attributes are not filtered by country. Setting this field - when SUB_COUNTRY_LOCATION attributes are not requested will - return an error. - youtube_reach_location (google.ads.googleads.v19.common.types.LocationInfo): - If present, potential YouTube reach estimates within the - specified market will be returned for attributes for which - they are available. Reach is only available for the - AGE_RANGE, GENDER, AFFINITY_USER_INTEREST and - IN_MARKET_USER_INTEREST dimensions, and may not be available - for every attribute of those dimensions in every market. - """ - - customer_id: str = proto.Field( - proto.STRING, - number=1, - ) - dimensions: MutableSequence[ - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ] = proto.RepeatedField( - proto.ENUM, - number=2, - enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, - ) - query_text: str = proto.Field( - proto.STRING, - number=3, - ) - customer_insights_group: str = proto.Field( - proto.STRING, - number=4, - ) - location_country_filters: MutableSequence[criteria.LocationInfo] = ( - proto.RepeatedField( - proto.MESSAGE, - number=5, - message=criteria.LocationInfo, - ) - ) - youtube_reach_location: criteria.LocationInfo = proto.Field( - proto.MESSAGE, - number=6, - message=criteria.LocationInfo, - ) - - -class ListAudienceInsightsAttributesResponse(proto.Message): - r"""Response message for - [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v19.services.AudienceInsightsService.ListAudienceInsightsAttributes]. - - Attributes: - attributes (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsAttributeMetadata]): - The attributes matching the search query. - """ - - attributes: MutableSequence[ - audience_insights_attribute.AudienceInsightsAttributeMetadata - ] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=audience_insights_attribute.AudienceInsightsAttributeMetadata, - ) - - -class ListInsightsEligibleDatesRequest(proto.Message): - r"""Request message for - [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v19.services.AudienceInsightsService.ListInsightsEligibleDates]. - - """ - - -class ListInsightsEligibleDatesResponse(proto.Message): - r"""Response message for - [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v19.services.AudienceInsightsService.ListInsightsEligibleDates]. - - Attributes: - data_months (MutableSequence[str]): - The months for which AudienceInsights data is - currently available, each represented as a - string in the form "YYYY-MM". - last_thirty_days (google.ads.googleads.v19.common.types.DateRange): - The actual dates covered by the "last 30 days" date range - that will be used implicitly for - [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceCompositionInsights] - requests that have no data_month set. - """ - - data_months: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=1, - ) - last_thirty_days: dates.DateRange = proto.Field( - proto.MESSAGE, - number=2, - message=dates.DateRange, - ) - - -class GenerateAudienceOverlapInsightsRequest(proto.Message): - r"""Request message for - [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. - - Attributes: - customer_id (str): - Required. The ID of the customer. - country_location (google.ads.googleads.v19.common.types.LocationInfo): - Required. The country in which to calculate - the sizes and overlaps of audiences. - primary_attribute (google.ads.googleads.v19.common.types.AudienceInsightsAttribute): - Required. The audience attribute that should - be intersected with all other eligible - audiences. This must be an Affinity or - In-Market UserInterest, an AgeRange or a Gender. - dimensions (MutableSequence[google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): - Required. The types of attributes of which to calculate the - overlap with the primary_attribute. The values must be a - subset of AFFINITY_USER_INTEREST, IN_MARKET_USER_INTEREST, - AGE_RANGE and GENDER. - customer_insights_group (str): - The name of the customer being planned for. - This is a user-defined value. - """ - - customer_id: str = proto.Field( - proto.STRING, - number=1, - ) - country_location: criteria.LocationInfo = proto.Field( - proto.MESSAGE, - number=2, - message=criteria.LocationInfo, - ) - primary_attribute: audience_insights_attribute.AudienceInsightsAttribute = ( - proto.Field( - proto.MESSAGE, - number=6, - message=audience_insights_attribute.AudienceInsightsAttribute, - ) - ) - dimensions: MutableSequence[ - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ] = proto.RepeatedField( - proto.ENUM, - number=4, - enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, - ) - customer_insights_group: str = proto.Field( - proto.STRING, - number=5, - ) - - -class GenerateAudienceOverlapInsightsResponse(proto.Message): - r"""Response message for - [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v19.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. - - Attributes: - primary_attribute_metadata (google.ads.googleads.v19.common.types.AudienceInsightsAttributeMetadata): - Metadata for the primary attribute, including - potential YouTube reach. - dimension_results (MutableSequence[google.ads.googleads.v19.services.types.DimensionOverlapResult]): - Lists of attributes and their overlap with - the primary attribute, one list per requested - dimension. - """ - - primary_attribute_metadata: ( - audience_insights_attribute.AudienceInsightsAttributeMetadata - ) = proto.Field( - proto.MESSAGE, - number=3, - message=audience_insights_attribute.AudienceInsightsAttributeMetadata, - ) - dimension_results: MutableSequence["DimensionOverlapResult"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=2, - message="DimensionOverlapResult", - ) - ) - - -class DimensionOverlapResult(proto.Message): - r"""A list of audience attributes of a single dimension, including their - overlap with a primary attribute, returned as part of a - [GenerateAudienceOverlapInsightsResponse][google.ads.googleads.v19.services.GenerateAudienceOverlapInsightsResponse]. - - Attributes: - dimension (google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension): - The dimension of all the attributes in this - section. - items (MutableSequence[google.ads.googleads.v19.services.types.AudienceOverlapItem]): - The attributes and their overlap with the - primary attribute. - """ - - dimension: ( - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ) = proto.Field( - proto.ENUM, - number=1, - enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, - ) - items: MutableSequence["AudienceOverlapItem"] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message="AudienceOverlapItem", - ) - - -class AudienceOverlapItem(proto.Message): - r"""An audience attribute, with metadata including the overlap - between this attribute's potential YouTube reach and that of a - primary attribute. - - Attributes: - attribute_metadata (google.ads.googleads.v19.common.types.AudienceInsightsAttributeMetadata): - The attribute and its metadata, including - potential YouTube reach. - potential_youtube_reach_intersection (int): - The estimated size of the intersection of - this audience attribute with the primary - attribute, that is, the number of reachable - YouTube users who match BOTH the primary - attribute and this one. - """ - - attribute_metadata: ( - audience_insights_attribute.AudienceInsightsAttributeMetadata - ) = proto.Field( - proto.MESSAGE, - number=3, - message=audience_insights_attribute.AudienceInsightsAttributeMetadata, - ) - potential_youtube_reach_intersection: int = proto.Field( - proto.INT64, - number=2, - ) - - -class GenerateTargetingSuggestionMetricsRequest(proto.Message): - r"""Request message for - [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v19.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. - - Attributes: - customer_id (str): - Required. The ID of the customer. - audiences (MutableSequence[google.ads.googleads.v19.services.types.BasicInsightsAudience]): - Required. Audiences to request metrics for. - customer_insights_group (str): - Optional. The name of the customer being - planned for. This is a user-defined value. - """ - - customer_id: str = proto.Field( - proto.STRING, - number=1, - ) - audiences: MutableSequence["BasicInsightsAudience"] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message="BasicInsightsAudience", - ) - customer_insights_group: str = proto.Field( - proto.STRING, - number=3, - ) - - -class GenerateTargetingSuggestionMetricsResponse(proto.Message): - r"""Response message for - [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v19.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. - - Attributes: - suggestions (MutableSequence[google.ads.googleads.v19.services.types.TargetingSuggestionMetrics]): - Suggested targetable audiences. There will be one suggestion - for each - [GenerateTargetingSuggestionMetricsRequest.audiences] - requested, matching the order requested. - """ - - suggestions: MutableSequence["TargetingSuggestionMetrics"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message="TargetingSuggestionMetrics", - ) - ) - - -class BasicInsightsAudience(proto.Message): - r"""A description of an audience used for requesting insights. - - Attributes: - country_location (MutableSequence[google.ads.googleads.v19.common.types.LocationInfo]): - Required. The countries for this audience. - sub_country_locations (MutableSequence[google.ads.googleads.v19.common.types.LocationInfo]): - Sub-country geographic location attributes. - If present, each of these must be contained in - one of the countries in this audience. - gender (google.ads.googleads.v19.common.types.GenderInfo): - Gender for the audience. If absent, the - audience does not restrict by gender. - age_ranges (MutableSequence[google.ads.googleads.v19.common.types.AgeRangeInfo]): - Age ranges for the audience. If absent, the - audience represents all people over 18 that - match the other attributes. - user_interests (MutableSequence[google.ads.googleads.v19.common.types.UserInterestInfo]): - User interests defining this audience. - Affinity and In-Market audiences are supported. - topics (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsTopic]): - Topics, represented by Knowledge Graph - entities and/or Product & Service categories, - that this audience is interested in. - """ - - country_location: MutableSequence[criteria.LocationInfo] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message=criteria.LocationInfo, - ) - ) - sub_country_locations: MutableSequence[criteria.LocationInfo] = ( - proto.RepeatedField( - proto.MESSAGE, - number=2, - message=criteria.LocationInfo, - ) - ) - gender: criteria.GenderInfo = proto.Field( - proto.MESSAGE, - number=3, - message=criteria.GenderInfo, - ) - age_ranges: MutableSequence[criteria.AgeRangeInfo] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message=criteria.AgeRangeInfo, - ) - user_interests: MutableSequence[criteria.UserInterestInfo] = ( - proto.RepeatedField( - proto.MESSAGE, - number=5, - message=criteria.UserInterestInfo, - ) - ) - topics: MutableSequence[ - audience_insights_attribute.AudienceInsightsTopic - ] = proto.RepeatedField( - proto.MESSAGE, - number=7, - message=audience_insights_attribute.AudienceInsightsTopic, - ) - - -class InsightsAudienceDefinition(proto.Message): - r"""A structured definition of the audience of interest for which - insights are being requested in AudienceInsightsService. - - Attributes: - audience (google.ads.googleads.v19.services.types.InsightsAudience): - Required. The audience of interest for which - insights are being requested. - baseline_audience (google.ads.googleads.v19.services.types.InsightsAudience): - Optional. The baseline audience. The default, - if unspecified, is all people in the same - country as the audience of interest. - data_month (str): - Optional. The one-month range of historical - data to use for insights, in the format - "yyyy-mm". If unset, insights will be returned - for the last thirty days of data. - """ - - audience: "InsightsAudience" = proto.Field( - proto.MESSAGE, - number=1, - message="InsightsAudience", - ) - baseline_audience: "InsightsAudience" = proto.Field( - proto.MESSAGE, - number=2, - message="InsightsAudience", - ) - data_month: str = proto.Field( - proto.STRING, - number=3, - ) - - -class InsightsAudienceDescription(proto.Message): - r"""A text description of the audience of interest for which - insights are being requested in AudienceInsightsService. - - Attributes: - country_locations (MutableSequence[google.ads.googleads.v19.common.types.LocationInfo]): - Required. The countries for the audience. - audience_description (str): - Required. An English language text - description of an audience to get suggestions - for. Maximum length is 2000 characters. For - example, "Women in their 30s who love to - travel". - marketing_objective (google.ads.googleads.v19.enums.types.AudienceInsightsMarketingObjectiveEnum.AudienceInsightsMarketingObjective): - Optional. An optional marketing objective - which will influence the type of suggestions - produced. AWARENESS will provide affinity - audience segments, while CONSIDERATION will - provide in-market audience segments. Leaving it - unset will provide both. - """ - - country_locations: MutableSequence[criteria.LocationInfo] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message=criteria.LocationInfo, - ) - ) - audience_description: str = proto.Field( - proto.STRING, - number=2, - ) - marketing_objective: ( - audience_insights_marketing_objective.AudienceInsightsMarketingObjectiveEnum.AudienceInsightsMarketingObjective - ) = proto.Field( - proto.ENUM, - number=3, - enum=audience_insights_marketing_objective.AudienceInsightsMarketingObjectiveEnum.AudienceInsightsMarketingObjective, - ) - - -class InsightsAudience(proto.Message): - r"""A set of users, defined by various characteristics, for which - insights can be requested in AudienceInsightsService. - - Attributes: - country_locations (MutableSequence[google.ads.googleads.v19.common.types.LocationInfo]): - Required. The countries for the audience. - sub_country_locations (MutableSequence[google.ads.googleads.v19.common.types.LocationInfo]): - Sub-country geographic location attributes. If present, each - of these must be contained in one of the countries in this - audience. If absent, the audience is geographically to the - country_locations and no further. - gender (google.ads.googleads.v19.common.types.GenderInfo): - Gender for the audience. If absent, the - audience does not restrict by gender. - age_ranges (MutableSequence[google.ads.googleads.v19.common.types.AgeRangeInfo]): - Age ranges for the audience. If absent, the - audience represents all people over 18 that - match the other attributes. - parental_status (google.ads.googleads.v19.common.types.ParentalStatusInfo): - Parental status for the audience. If absent, - the audience does not restrict by parental - status. - income_ranges (MutableSequence[google.ads.googleads.v19.common.types.IncomeRangeInfo]): - Household income percentile ranges for the - audience. If absent, the audience does not - restrict by household income range. - dynamic_lineups (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsDynamicLineup]): - Dynamic lineups representing the YouTube - content viewed by the audience. - topic_audience_combinations (MutableSequence[google.ads.googleads.v19.services.types.InsightsAudienceAttributeGroup]): - A combination of entity, category and user - interest attributes defining the audience. The - combination has a logical AND-of-ORs structure: - Attributes within each - InsightsAudienceAttributeGroup are combined with - OR, and the combinations themselves are combined - together with AND. For example, the expression - (Entity OR Affinity) AND (In-Market OR Category) - can be formed using two - InsightsAudienceAttributeGroups with two - Attributes each. - """ - - country_locations: MutableSequence[criteria.LocationInfo] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message=criteria.LocationInfo, - ) - ) - sub_country_locations: MutableSequence[criteria.LocationInfo] = ( - proto.RepeatedField( - proto.MESSAGE, - number=2, - message=criteria.LocationInfo, - ) - ) - gender: criteria.GenderInfo = proto.Field( - proto.MESSAGE, - number=3, - message=criteria.GenderInfo, - ) - age_ranges: MutableSequence[criteria.AgeRangeInfo] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message=criteria.AgeRangeInfo, - ) - parental_status: criteria.ParentalStatusInfo = proto.Field( - proto.MESSAGE, - number=5, - message=criteria.ParentalStatusInfo, - ) - income_ranges: MutableSequence[criteria.IncomeRangeInfo] = ( - proto.RepeatedField( - proto.MESSAGE, - number=6, - message=criteria.IncomeRangeInfo, - ) - ) - dynamic_lineups: MutableSequence[ - audience_insights_attribute.AudienceInsightsDynamicLineup - ] = proto.RepeatedField( - proto.MESSAGE, - number=9, - message=audience_insights_attribute.AudienceInsightsDynamicLineup, - ) - topic_audience_combinations: MutableSequence[ - "InsightsAudienceAttributeGroup" - ] = proto.RepeatedField( - proto.MESSAGE, - number=8, - message="InsightsAudienceAttributeGroup", - ) - - -class InsightsAudienceAttributeGroup(proto.Message): - r"""A list of AudienceInsightsAttributes. - - Attributes: - attributes (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsAttribute]): - Required. A collection of audience attributes - to be combined with logical OR. Attributes need - not all be the same dimension. Only Knowledge - Graph entities, Product & Service Categories, - and Affinity and In-Market audiences are - supported in this context. - """ - - attributes: MutableSequence[ - audience_insights_attribute.AudienceInsightsAttribute - ] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=audience_insights_attribute.AudienceInsightsAttribute, - ) - - -class AudienceCompositionSection(proto.Message): - r"""A collection of related attributes of the same type in an - audience composition insights report. - - Attributes: - dimension (google.ads.googleads.v19.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension): - The type of the attributes in this section. - top_attributes (MutableSequence[google.ads.googleads.v19.services.types.AudienceCompositionAttribute]): - The most relevant segments for this audience. If dimension - is GENDER, AGE_RANGE or PARENTAL_STATUS, then this list of - attributes is exhaustive. - clustered_attributes (MutableSequence[google.ads.googleads.v19.services.types.AudienceCompositionAttributeCluster]): - Additional attributes for this audience, grouped into - clusters. Only populated if dimension is YOUTUBE_CHANNEL. - """ - - dimension: ( - audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension - ) = proto.Field( - proto.ENUM, - number=1, - enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, - ) - top_attributes: MutableSequence["AudienceCompositionAttribute"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=3, - message="AudienceCompositionAttribute", - ) - ) - clustered_attributes: MutableSequence[ - "AudienceCompositionAttributeCluster" - ] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message="AudienceCompositionAttributeCluster", - ) - - -class AudienceCompositionAttributeCluster(proto.Message): - r"""A collection of related attributes, with metadata and - metrics, in an audience composition insights report. - - Attributes: - cluster_display_name (str): - The name of this cluster of attributes - cluster_metrics (google.ads.googleads.v19.services.types.AudienceCompositionMetrics): - If the dimension associated with this cluster is - YOUTUBE_CHANNEL, then cluster_metrics are metrics associated - with the cluster as a whole. For other dimensions, this - field is unset. - attributes (MutableSequence[google.ads.googleads.v19.services.types.AudienceCompositionAttribute]): - The individual attributes that make up this - cluster, with metadata and metrics. - """ - - cluster_display_name: str = proto.Field( - proto.STRING, - number=1, - ) - cluster_metrics: "AudienceCompositionMetrics" = proto.Field( - proto.MESSAGE, - number=3, - message="AudienceCompositionMetrics", - ) - attributes: MutableSequence["AudienceCompositionAttribute"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=4, - message="AudienceCompositionAttribute", - ) - ) - - -class AudienceCompositionMetrics(proto.Message): - r"""The share and index metrics associated with an attribute in - an audience composition insights report. - - Attributes: - baseline_audience_share (float): - The fraction (from 0 to 1 inclusive) of the - baseline audience that match the attribute. - audience_share (float): - The fraction (from 0 to 1 inclusive) of the - specific audience that match the attribute. - index (float): - The ratio of audience_share to baseline_audience_share, or - zero if this ratio is undefined or is not meaningful. - score (float): - A relevance score from 0 to 1 inclusive. - """ - - baseline_audience_share: float = proto.Field( - proto.DOUBLE, - number=1, - ) - audience_share: float = proto.Field( - proto.DOUBLE, - number=2, - ) - index: float = proto.Field( - proto.DOUBLE, - number=3, - ) - score: float = proto.Field( - proto.DOUBLE, - number=4, - ) - - -class AudienceCompositionAttribute(proto.Message): - r"""An audience attribute with metadata and metrics. - - Attributes: - attribute_metadata (google.ads.googleads.v19.common.types.AudienceInsightsAttributeMetadata): - The attribute with its metadata. - metrics (google.ads.googleads.v19.services.types.AudienceCompositionMetrics): - Share and index metrics for the attribute. - """ - - attribute_metadata: ( - audience_insights_attribute.AudienceInsightsAttributeMetadata - ) = proto.Field( - proto.MESSAGE, - number=3, - message=audience_insights_attribute.AudienceInsightsAttributeMetadata, - ) - metrics: "AudienceCompositionMetrics" = proto.Field( - proto.MESSAGE, - number=2, - message="AudienceCompositionMetrics", - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/content_creator_insights_service.py b/google/ads/googleads/v19/services/types/content_creator_insights_service.py deleted file mode 100644 index 64fd6b976..000000000 --- a/google/ads/googleads/v19/services/types/content_creator_insights_service.py +++ /dev/null @@ -1,522 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -from typing import MutableSequence - -import proto # type: ignore - -from google.ads.googleads.v19.common.types import audience_insights_attribute -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.enums.types import insights_trend - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", - manifest={ - "GenerateCreatorInsightsRequest", - "GenerateCreatorInsightsResponse", - "GenerateTrendingInsightsRequest", - "GenerateTrendingInsightsResponse", - "YouTubeCreatorInsights", - "YouTubeMetrics", - "YouTubeChannelInsights", - "SearchAudience", - "SearchTopics", - "TrendInsight", - "TrendInsightMetrics", - }, -) - - -class GenerateCreatorInsightsRequest(proto.Message): - r"""Request message for - [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v19.services.ContentCreatorInsightsService.GenerateCreatorInsights]. - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - customer_id (str): - Required. The ID of the customer. - customer_insights_group (str): - Required. The name of the customer being - planned for. This is a user-defined value. - country_locations (MutableSequence[google.ads.googleads.v19.common.types.LocationInfo]): - Required. The countries to search that apply - to the criteria. - search_attributes (google.ads.googleads.v19.services.types.GenerateCreatorInsightsRequest.SearchAttributes): - The attributes used to identify top creators. Data fetched - is based on the list of countries specified in - [country_locations]. - - This field is a member of `oneof`_ ``criteria``. - search_brand (google.ads.googleads.v19.services.types.GenerateCreatorInsightsRequest.SearchBrand): - A brand used to search for top creators. Data fetched is - based on the list of countries specified in - [country_locations]. - - This field is a member of `oneof`_ ``criteria``. - search_channels (google.ads.googleads.v19.services.types.GenerateCreatorInsightsRequest.YouTubeChannels): - YouTube Channel IDs for Creator Insights. Data fetched for - channels is based on the list of countries specified in - [country_locations]. - - This field is a member of `oneof`_ ``criteria``. - """ - - class SearchAttributes(proto.Message): - r"""The audience attributes (such as Age, Gender, Affinity, and - In-Market) and creator attributes (such as creator's content - topics) used to search for top creators. - - Attributes: - audience_attributes (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsAttribute]): - Optional. Audience attributes that describe an audience of - viewers. This is used to search for creators whose own - viewers match the input audience. Attributes age_range, - gender, user_interest, entity, category, parental_status, - and income_range are supported. Attribute location is not - supported. - creator_attributes (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsAttribute]): - Optional. Creator attributes that describe a collection of - types of content. This is used to search for creators whose - content matches the input creator attributes. Attribute - entity tagged with - [InsightsKnowledgeGraphEntityCapabilities.CREATOR_ATTRIBUTE][] - is supported. Other attributes including location are not - supported. - """ - - audience_attributes: MutableSequence[ - audience_insights_attribute.AudienceInsightsAttribute - ] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=audience_insights_attribute.AudienceInsightsAttribute, - ) - creator_attributes: MutableSequence[ - audience_insights_attribute.AudienceInsightsAttribute - ] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=audience_insights_attribute.AudienceInsightsAttribute, - ) - - class SearchBrand(proto.Message): - r"""The brand used to search for top creators. - - Attributes: - brand_entities (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsAttribute]): - Optional. One or more Knowledge Graph - Entities that represent the brand for which to - find insights. - include_related_topics (bool): - Optional. When true, we will expand the search to beyond - just the entities specified in [brand_entities] to other - related knowledge graph entities similar to the brand. The - default value is ``false``. - """ - - brand_entities: MutableSequence[ - audience_insights_attribute.AudienceInsightsAttribute - ] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=audience_insights_attribute.AudienceInsightsAttribute, - ) - include_related_topics: bool = proto.Field( - proto.BOOL, - number=2, - ) - - class YouTubeChannels(proto.Message): - r"""A collection of YouTube Channels. - - Attributes: - youtube_channels (MutableSequence[google.ads.googleads.v19.common.types.YouTubeChannelInfo]): - Optional. The YouTube Channel IDs to fetch - creator insights for. - """ - - youtube_channels: MutableSequence[criteria.YouTubeChannelInfo] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message=criteria.YouTubeChannelInfo, - ) - ) - - customer_id: str = proto.Field( - proto.STRING, - number=1, - ) - customer_insights_group: str = proto.Field( - proto.STRING, - number=2, - ) - country_locations: MutableSequence[criteria.LocationInfo] = ( - proto.RepeatedField( - proto.MESSAGE, - number=6, - message=criteria.LocationInfo, - ) - ) - search_attributes: SearchAttributes = proto.Field( - proto.MESSAGE, - number=3, - oneof="criteria", - message=SearchAttributes, - ) - search_brand: SearchBrand = proto.Field( - proto.MESSAGE, - number=5, - oneof="criteria", - message=SearchBrand, - ) - search_channels: YouTubeChannels = proto.Field( - proto.MESSAGE, - number=4, - oneof="criteria", - message=YouTubeChannels, - ) - - -class GenerateCreatorInsightsResponse(proto.Message): - r"""Response message for - [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v19.services.ContentCreatorInsightsService.GenerateCreatorInsights]. - - Attributes: - creator_insights (MutableSequence[google.ads.googleads.v19.services.types.YouTubeCreatorInsights]): - A collection of YouTube Creators, each - containing a collection of YouTube Channels - maintained by the YouTube Creator. - """ - - creator_insights: MutableSequence["YouTubeCreatorInsights"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message="YouTubeCreatorInsights", - ) - ) - - -class GenerateTrendingInsightsRequest(proto.Message): - r"""Request message for - [ContentCreatorInsightsService.GenerateTrendingInsights] - - This message has `oneof`_ fields (mutually exclusive fields). - For each oneof, at most one member field can be set at the same time. - Setting any member of the oneof automatically clears all other - members. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - customer_id (str): - Required. The ID of the customer. - customer_insights_group (str): - Required. The name of the customer being - planned for. This is a user-defined value. - country_location (google.ads.googleads.v19.common.types.LocationInfo): - Required. The country to find trends in. - search_audience (google.ads.googleads.v19.services.types.SearchAudience): - An audience to search for trending content - in. - - This field is a member of `oneof`_ ``criteria``. - search_topics (google.ads.googleads.v19.services.types.SearchTopics): - Content topics to return trend information - for. - - This field is a member of `oneof`_ ``criteria``. - """ - - customer_id: str = proto.Field( - proto.STRING, - number=1, - ) - customer_insights_group: str = proto.Field( - proto.STRING, - number=2, - ) - country_location: criteria.LocationInfo = proto.Field( - proto.MESSAGE, - number=3, - message=criteria.LocationInfo, - ) - search_audience: "SearchAudience" = proto.Field( - proto.MESSAGE, - number=4, - oneof="criteria", - message="SearchAudience", - ) - search_topics: "SearchTopics" = proto.Field( - proto.MESSAGE, - number=5, - oneof="criteria", - message="SearchTopics", - ) - - -class GenerateTrendingInsightsResponse(proto.Message): - r"""Response message for - [ContentCreatorInsightsService.GenerateTrendingInsights] - - Attributes: - trend_insights (MutableSequence[google.ads.googleads.v19.services.types.TrendInsight]): - The list of trending insights for the given - criteria. - """ - - trend_insights: MutableSequence["TrendInsight"] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="TrendInsight", - ) - - -class YouTubeCreatorInsights(proto.Message): - r"""A YouTube creator and the insights for this creator. - - Attributes: - creator_name (str): - The name of the creator. - creator_channels (MutableSequence[google.ads.googleads.v19.services.types.YouTubeChannelInsights]): - The list of YouTube Channels - """ - - creator_name: str = proto.Field( - proto.STRING, - number=1, - ) - creator_channels: MutableSequence["YouTubeChannelInsights"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=2, - message="YouTubeChannelInsights", - ) - ) - - -class YouTubeMetrics(proto.Message): - r"""YouTube Channel metrics. - - Attributes: - subscriber_count (int): - The number of subscribers. - views_count (int): - The total number of views. - video_count (int): - The total number of videos. - is_active_shorts_creator (bool): - When true, this channel has published a - shorts video in the last 90 days. - """ - - subscriber_count: int = proto.Field( - proto.INT64, - number=1, - ) - views_count: int = proto.Field( - proto.INT64, - number=2, - ) - video_count: int = proto.Field( - proto.INT64, - number=3, - ) - is_active_shorts_creator: bool = proto.Field( - proto.BOOL, - number=4, - ) - - -class YouTubeChannelInsights(proto.Message): - r"""YouTube Channel insights, and its metadata (such as channel - name and channel ID), returned for a creator insights response. - - Attributes: - display_name (str): - The name of the YouTube Channel. - youtube_channel (google.ads.googleads.v19.common.types.YouTubeChannelInfo): - The YouTube Channel ID. - channel_url (str): - URL for the channel in the form of - https://www.youtube.com/channel/{channel_id}. - channel_description (str): - Description of the channel. - channel_metrics (google.ads.googleads.v19.services.types.YouTubeMetrics): - The metrics for a YouTube Channel. - channel_audience_attributes (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsAttributeMetadata]): - The types of audiences and demographics - linked to the channel's main audience. Audiences - and demographics have a breakdown of subscriber - share across dimensions of the same value, such - as Age Range, Gender, and User Interest. - channel_attributes (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsAttributeMetadata]): - The attributes associated with the content - made by a channel. - top_videos (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsAttributeMetadata]): - The top 10 videos for the channel. - channel_type (str): - Metadata string associated with the type of - channel. - """ - - display_name: str = proto.Field( - proto.STRING, - number=1, - ) - youtube_channel: criteria.YouTubeChannelInfo = proto.Field( - proto.MESSAGE, - number=2, - message=criteria.YouTubeChannelInfo, - ) - channel_url: str = proto.Field( - proto.STRING, - number=9, - ) - channel_description: str = proto.Field( - proto.STRING, - number=10, - ) - channel_metrics: "YouTubeMetrics" = proto.Field( - proto.MESSAGE, - number=3, - message="YouTubeMetrics", - ) - channel_audience_attributes: MutableSequence[ - audience_insights_attribute.AudienceInsightsAttributeMetadata - ] = proto.RepeatedField( - proto.MESSAGE, - number=7, - message=audience_insights_attribute.AudienceInsightsAttributeMetadata, - ) - channel_attributes: MutableSequence[ - audience_insights_attribute.AudienceInsightsAttributeMetadata - ] = proto.RepeatedField( - proto.MESSAGE, - number=5, - message=audience_insights_attribute.AudienceInsightsAttributeMetadata, - ) - top_videos: MutableSequence[ - audience_insights_attribute.AudienceInsightsAttributeMetadata - ] = proto.RepeatedField( - proto.MESSAGE, - number=8, - message=audience_insights_attribute.AudienceInsightsAttributeMetadata, - ) - channel_type: str = proto.Field( - proto.STRING, - number=6, - ) - - -class SearchAudience(proto.Message): - r"""A collection of audience attributes that describe an audience - of viewers. This is used to search for topics trending for the - defined audience. - - Attributes: - audience_attributes (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsAttribute]): - Required. Audience attributes that describe - an audience of viewers. This is used to search - for topics trending for the defined audience. - """ - - audience_attributes: MutableSequence[ - audience_insights_attribute.AudienceInsightsAttribute - ] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=audience_insights_attribute.AudienceInsightsAttribute, - ) - - -class SearchTopics(proto.Message): - r"""A collection of content topics to return trend information - for. - - Attributes: - entities (MutableSequence[google.ads.googleads.v19.common.types.AudienceInsightsEntity]): - Required. A list of knowledge graph entities to retrieve - trend information for. Supported entities are tagged with - [InsightsKnowledgeGraphEntityCapabilities.CONTENT_TRENDING_INSIGHTS][]. - """ - - entities: MutableSequence[ - audience_insights_attribute.AudienceInsightsEntity - ] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=audience_insights_attribute.AudienceInsightsEntity, - ) - - -class TrendInsight(proto.Message): - r"""A trend insight for a given attribute. - - Attributes: - trend_attribute (google.ads.googleads.v19.common.types.AudienceInsightsAttributeMetadata): - The attribute this trend is for. - trend_metrics (google.ads.googleads.v19.services.types.TrendInsightMetrics): - Metrics associated with this trend. - trend (google.ads.googleads.v19.enums.types.InsightsTrendEnum.InsightsTrend): - The direction of trend (such as RISING or - DECLINING). - """ - - trend_attribute: ( - audience_insights_attribute.AudienceInsightsAttributeMetadata - ) = proto.Field( - proto.MESSAGE, - number=1, - message=audience_insights_attribute.AudienceInsightsAttributeMetadata, - ) - trend_metrics: "TrendInsightMetrics" = proto.Field( - proto.MESSAGE, - number=2, - message="TrendInsightMetrics", - ) - trend: insights_trend.InsightsTrendEnum.InsightsTrend = proto.Field( - proto.ENUM, - number=3, - enum=insights_trend.InsightsTrendEnum.InsightsTrend, - ) - - -class TrendInsightMetrics(proto.Message): - r"""Metrics associated with a trend insight. - - Attributes: - views_count (int): - The number of views for this trend. - """ - - views_count: int = proto.Field( - proto.INT64, - number=1, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/invoice_service.py b/google/ads/googleads/v19/services/types/invoice_service.py deleted file mode 100644 index 99b87bcc4..000000000 --- a/google/ads/googleads/v19/services/types/invoice_service.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -from typing import MutableSequence - -import proto # type: ignore - -from google.ads.googleads.v19.enums.types import month_of_year -from google.ads.googleads.v19.resources.types import invoice - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", - manifest={ - "ListInvoicesRequest", - "ListInvoicesResponse", - }, -) - - -class ListInvoicesRequest(proto.Message): - r"""Request message for fetching the invoices of a given billing - setup that were issued during a given month. - - Attributes: - customer_id (str): - Required. The ID of the customer to fetch - invoices for. - billing_setup (str): - Required. The billing setup resource name of the requested - invoices. - - ``customers/{customer_id}/billingSetups/{billing_setup_id}`` - issue_year (str): - Required. The issue year to retrieve - invoices, in yyyy format. Only invoices issued - in 2019 or later can be retrieved. - issue_month (google.ads.googleads.v19.enums.types.MonthOfYearEnum.MonthOfYear): - Required. The issue month to retrieve - invoices. - """ - - customer_id: str = proto.Field( - proto.STRING, - number=1, - ) - billing_setup: str = proto.Field( - proto.STRING, - number=2, - ) - issue_year: str = proto.Field( - proto.STRING, - number=3, - ) - issue_month: month_of_year.MonthOfYearEnum.MonthOfYear = proto.Field( - proto.ENUM, - number=4, - enum=month_of_year.MonthOfYearEnum.MonthOfYear, - ) - - -class ListInvoicesResponse(proto.Message): - r"""Response message for - [InvoiceService.ListInvoices][google.ads.googleads.v19.services.InvoiceService.ListInvoices]. - - Attributes: - invoices (MutableSequence[google.ads.googleads.v19.resources.types.Invoice]): - The list of invoices that match the billing - setup and time period. - """ - - invoices: MutableSequence[invoice.Invoice] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message=invoice.Invoice, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/reach_plan_service.py b/google/ads/googleads/v19/services/types/reach_plan_service.py deleted file mode 100644 index 3692ffcdc..000000000 --- a/google/ads/googleads/v19/services/types/reach_plan_service.py +++ /dev/null @@ -1,1445 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -from typing import MutableSequence - -import proto # type: ignore - -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.common.types import dates -from google.ads.googleads.v19.enums.types import frequency_cap_time_unit -from google.ads.googleads.v19.enums.types import reach_plan_age_range -from google.ads.googleads.v19.enums.types import ( - reach_plan_conversion_rate_model, -) -from google.ads.googleads.v19.enums.types import reach_plan_network -from google.ads.googleads.v19.enums.types import reach_plan_surface -from google.ads.googleads.v19.enums.types import target_frequency_time_unit - - -__protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", - manifest={ - "GenerateConversionRatesRequest", - "GenerateConversionRatesResponse", - "ConversionRateSuggestion", - "ListPlannableLocationsRequest", - "ListPlannableLocationsResponse", - "PlannableLocation", - "ListPlannableProductsRequest", - "ListPlannableProductsResponse", - "ProductMetadata", - "PlannableTargeting", - "GenerateReachForecastRequest", - "EffectiveFrequencyLimit", - "FrequencyCap", - "Targeting", - "CampaignDuration", - "PlannedProduct", - "GenerateReachForecastResponse", - "ReachCurve", - "ReachForecast", - "Forecast", - "PlannedProductReachForecast", - "PlannedProductForecast", - "OnTargetAudienceMetrics", - "EffectiveFrequencyBreakdown", - "ForecastMetricOptions", - "AudienceTargeting", - "AdvancedProductTargeting", - "YouTubeSelectSettings", - "YouTubeSelectLineUp", - "SurfaceTargetingCombinations", - "SurfaceTargeting", - "TargetFrequencySettings", - }, -) - - -class GenerateConversionRatesRequest(proto.Message): - r"""Request message for - [ReachPlanService.GenerateConversionRates][google.ads.googleads.v19.services.ReachPlanService.GenerateConversionRates]. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - customer_id (str): - Required. The ID of the customer. A - conversion rate based on the historical data of - this customer may be suggested. - customer_reach_group (str): - The name of the customer being planned for. - This is a user-defined value. - - This field is a member of `oneof`_ ``_customer_reach_group``. - """ - - customer_id: str = proto.Field( - proto.STRING, - number=1, - ) - customer_reach_group: str = proto.Field( - proto.STRING, - number=2, - optional=True, - ) - - -class GenerateConversionRatesResponse(proto.Message): - r"""Response message for - [ReachPlanService.GenerateConversionRates][google.ads.googleads.v19.services.ReachPlanService.GenerateConversionRates], - containing conversion rate suggestions for supported plannable - products. - - Attributes: - conversion_rate_suggestions (MutableSequence[google.ads.googleads.v19.services.types.ConversionRateSuggestion]): - A list containing conversion rate - suggestions. Each repeated element will have an - associated product code. Multiple suggestions - may share the same product code. - """ - - conversion_rate_suggestions: MutableSequence["ConversionRateSuggestion"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message="ConversionRateSuggestion", - ) - ) - - -class ConversionRateSuggestion(proto.Message): - r"""A conversion rate suggestion. - - Attributes: - conversion_rate_model (google.ads.googleads.v19.enums.types.ReachPlanConversionRateModelEnum.ReachPlanConversionRateModel): - Model type used to calculate the suggested - conversion rate. - plannable_product_code (str): - The code associated with the plannable product (for example: - DEMAND_GEN). To list all plannable product codes, use - [ReachPlanService.ListPlannableProducts][google.ads.googleads.v19.services.ReachPlanService.ListPlannableProducts]. - conversion_rate (float): - The suggested conversion rate. The value is - between 0 and 1 (exclusive). - """ - - conversion_rate_model: ( - reach_plan_conversion_rate_model.ReachPlanConversionRateModelEnum.ReachPlanConversionRateModel - ) = proto.Field( - proto.ENUM, - number=1, - enum=reach_plan_conversion_rate_model.ReachPlanConversionRateModelEnum.ReachPlanConversionRateModel, - ) - plannable_product_code: str = proto.Field( - proto.STRING, - number=2, - ) - conversion_rate: float = proto.Field( - proto.DOUBLE, - number=3, - ) - - -class ListPlannableLocationsRequest(proto.Message): - r"""Request message for - [ReachPlanService.ListPlannableLocations][google.ads.googleads.v19.services.ReachPlanService.ListPlannableLocations]. - - """ - - -class ListPlannableLocationsResponse(proto.Message): - r"""The list of plannable locations. - - Attributes: - plannable_locations (MutableSequence[google.ads.googleads.v19.services.types.PlannableLocation]): - The list of locations available for planning. - See - https://developers.google.com/google-ads/api/reference/data/geotargets - for sample locations. - """ - - plannable_locations: MutableSequence["PlannableLocation"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message="PlannableLocation", - ) - ) - - -class PlannableLocation(proto.Message): - r"""A plannable location: country, metro region, province, etc. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - id (str): - The location identifier. - - This field is a member of `oneof`_ ``_id``. - name (str): - The unique location name in English. - - This field is a member of `oneof`_ ``_name``. - parent_country_id (int): - The parent country (not present if location is a country). - If present, will always be a GeoTargetConstant ID. - Additional information such as country name is provided by - [ReachPlanService.ListPlannableLocations][google.ads.googleads.v19.services.ReachPlanService.ListPlannableLocations] - or GoogleAdsService.Search/SearchStream. - - This field is a member of `oneof`_ ``_parent_country_id``. - country_code (str): - The ISO-3166-1 alpha-2 country code that is - associated with the location. - - This field is a member of `oneof`_ ``_country_code``. - location_type (str): - The location's type. Location types correspond to - target_type returned by searching location type in - GoogleAdsService.Search/SearchStream. - - This field is a member of `oneof`_ ``_location_type``. - """ - - id: str = proto.Field( - proto.STRING, - number=4, - optional=True, - ) - name: str = proto.Field( - proto.STRING, - number=5, - optional=True, - ) - parent_country_id: int = proto.Field( - proto.INT64, - number=6, - optional=True, - ) - country_code: str = proto.Field( - proto.STRING, - number=7, - optional=True, - ) - location_type: str = proto.Field( - proto.STRING, - number=8, - optional=True, - ) - - -class ListPlannableProductsRequest(proto.Message): - r"""Request to list available products in a given location. - - Attributes: - plannable_location_id (str): - Required. The ID of the selected location for planning. To - list the available plannable location IDs use - [ReachPlanService.ListPlannableLocations][google.ads.googleads.v19.services.ReachPlanService.ListPlannableLocations]. - """ - - plannable_location_id: str = proto.Field( - proto.STRING, - number=2, - ) - - -class ListPlannableProductsResponse(proto.Message): - r"""A response with all available products. - - Attributes: - product_metadata (MutableSequence[google.ads.googleads.v19.services.types.ProductMetadata]): - The list of products available for planning - and related targeting metadata. - """ - - product_metadata: MutableSequence["ProductMetadata"] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="ProductMetadata", - ) - - -class ProductMetadata(proto.Message): - r"""The metadata associated with an available plannable product. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - plannable_product_code (str): - The code associated with the ad product (for example: - BUMPER, TRUEVIEW_IN_STREAM). To list the available plannable - product codes use - [ReachPlanService.ListPlannableProducts][google.ads.googleads.v19.services.ReachPlanService.ListPlannableProducts]. - - This field is a member of `oneof`_ ``_plannable_product_code``. - plannable_product_name (str): - The name associated with the ad product. - plannable_targeting (google.ads.googleads.v19.services.types.PlannableTargeting): - The allowed plannable targeting for this - product. - """ - - plannable_product_code: str = proto.Field( - proto.STRING, - number=4, - optional=True, - ) - plannable_product_name: str = proto.Field( - proto.STRING, - number=3, - ) - plannable_targeting: "PlannableTargeting" = proto.Field( - proto.MESSAGE, - number=2, - message="PlannableTargeting", - ) - - -class PlannableTargeting(proto.Message): - r"""The targeting for which traffic metrics will be reported. - - Attributes: - age_ranges (MutableSequence[google.ads.googleads.v19.enums.types.ReachPlanAgeRangeEnum.ReachPlanAgeRange]): - Allowed plannable age ranges for the product - for which metrics will be reported. Actual - targeting is computed by mapping this age range - onto standard Google common.AgeRangeInfo values. - genders (MutableSequence[google.ads.googleads.v19.common.types.GenderInfo]): - Targetable genders for the ad product. - devices (MutableSequence[google.ads.googleads.v19.common.types.DeviceInfo]): - Targetable devices for the ad product. TABLET device - targeting is automatically applied to reported metrics when - MOBILE targeting is selected for CPM_MASTHEAD, - GOOGLE_PREFERRED_BUMPER, and GOOGLE_PREFERRED_SHORT - products. - networks (MutableSequence[google.ads.googleads.v19.enums.types.ReachPlanNetworkEnum.ReachPlanNetwork]): - Targetable networks for the ad product. - youtube_select_lineups (MutableSequence[google.ads.googleads.v19.services.types.YouTubeSelectLineUp]): - Targetable YouTube Select Lineups for the ad - product. - surface_targeting (google.ads.googleads.v19.services.types.SurfaceTargetingCombinations): - Targetable surface combinations for the ad - product. - """ - - age_ranges: MutableSequence[ - reach_plan_age_range.ReachPlanAgeRangeEnum.ReachPlanAgeRange - ] = proto.RepeatedField( - proto.ENUM, - number=1, - enum=reach_plan_age_range.ReachPlanAgeRangeEnum.ReachPlanAgeRange, - ) - genders: MutableSequence[criteria.GenderInfo] = proto.RepeatedField( - proto.MESSAGE, - number=2, - message=criteria.GenderInfo, - ) - devices: MutableSequence[criteria.DeviceInfo] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message=criteria.DeviceInfo, - ) - networks: MutableSequence[ - reach_plan_network.ReachPlanNetworkEnum.ReachPlanNetwork - ] = proto.RepeatedField( - proto.ENUM, - number=4, - enum=reach_plan_network.ReachPlanNetworkEnum.ReachPlanNetwork, - ) - youtube_select_lineups: MutableSequence["YouTubeSelectLineUp"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=5, - message="YouTubeSelectLineUp", - ) - ) - surface_targeting: "SurfaceTargetingCombinations" = proto.Field( - proto.MESSAGE, - number=6, - message="SurfaceTargetingCombinations", - ) - - -class GenerateReachForecastRequest(proto.Message): - r"""Request message for - [ReachPlanService.GenerateReachForecast][google.ads.googleads.v19.services.ReachPlanService.GenerateReachForecast]. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - customer_id (str): - Required. The ID of the customer. - currency_code (str): - The currency code. - Three-character ISO 4217 currency code. - - This field is a member of `oneof`_ ``_currency_code``. - campaign_duration (google.ads.googleads.v19.services.types.CampaignDuration): - Required. Campaign duration. - cookie_frequency_cap (int): - Chosen cookie frequency cap to be applied to each planned - product. This is equivalent to the frequency cap exposed in - Google Ads when creating a campaign, it represents the - maximum number of times an ad can be shown to the same user. - If not specified, no cap is applied. - - This field is deprecated in v4 and will eventually be - removed. Use cookie_frequency_cap_setting instead. - - This field is a member of `oneof`_ ``_cookie_frequency_cap``. - cookie_frequency_cap_setting (google.ads.googleads.v19.services.types.FrequencyCap): - Chosen cookie frequency cap to be applied to each planned - product. This is equivalent to the frequency cap exposed in - Google Ads when creating a campaign, it represents the - maximum number of times an ad can be shown to the same user - during a specified time interval. If not specified, a - default of 0 (no cap) is applied. - - This field replaces the deprecated cookie_frequency_cap - field. - min_effective_frequency (int): - Chosen minimum effective frequency (the number of times a - person was exposed to the ad) for the reported reach metrics - [1-10]. This won't affect the targeting, but just the - reporting. If not specified, a default of 1 is applied. - - This field cannot be combined with the - effective_frequency_limit field. - - This field is a member of `oneof`_ ``_min_effective_frequency``. - effective_frequency_limit (google.ads.googleads.v19.services.types.EffectiveFrequencyLimit): - The highest minimum effective frequency (the number of times - a person was exposed to the ad) value [1-10] to include in - Forecast.effective_frequency_breakdowns. If not specified, - Forecast.effective_frequency_breakdowns will not be - provided. - - The effective frequency value provided here will also be - used as the minimum effective frequency for the reported - reach metrics. - - This field cannot be combined with the - min_effective_frequency field. - - This field is a member of `oneof`_ ``_effective_frequency_limit``. - targeting (google.ads.googleads.v19.services.types.Targeting): - The targeting to be applied to all products - selected in the product mix. - This is planned targeting: execution details - might vary based on the advertising product, - consult an implementation specialist. - - See specific metrics for details on how - targeting affects them. - planned_products (MutableSequence[google.ads.googleads.v19.services.types.PlannedProduct]): - Required. The products to be forecast. - The max number of allowed planned products is - 15. - forecast_metric_options (google.ads.googleads.v19.services.types.ForecastMetricOptions): - Controls the forecast metrics returned in the - response. - customer_reach_group (str): - The name of the customer being planned for. - This is a user-defined value. - - This field is a member of `oneof`_ ``_customer_reach_group``. - """ - - customer_id: str = proto.Field( - proto.STRING, - number=1, - ) - currency_code: str = proto.Field( - proto.STRING, - number=9, - optional=True, - ) - campaign_duration: "CampaignDuration" = proto.Field( - proto.MESSAGE, - number=3, - message="CampaignDuration", - ) - cookie_frequency_cap: int = proto.Field( - proto.INT32, - number=10, - optional=True, - ) - cookie_frequency_cap_setting: "FrequencyCap" = proto.Field( - proto.MESSAGE, - number=8, - message="FrequencyCap", - ) - min_effective_frequency: int = proto.Field( - proto.INT32, - number=11, - optional=True, - ) - effective_frequency_limit: "EffectiveFrequencyLimit" = proto.Field( - proto.MESSAGE, - number=12, - optional=True, - message="EffectiveFrequencyLimit", - ) - targeting: "Targeting" = proto.Field( - proto.MESSAGE, - number=6, - message="Targeting", - ) - planned_products: MutableSequence["PlannedProduct"] = proto.RepeatedField( - proto.MESSAGE, - number=7, - message="PlannedProduct", - ) - forecast_metric_options: "ForecastMetricOptions" = proto.Field( - proto.MESSAGE, - number=13, - message="ForecastMetricOptions", - ) - customer_reach_group: str = proto.Field( - proto.STRING, - number=14, - optional=True, - ) - - -class EffectiveFrequencyLimit(proto.Message): - r"""Effective frequency limit. - - Attributes: - effective_frequency_breakdown_limit (int): - The highest effective frequency value to include in - Forecast.effective_frequency_breakdowns. This field supports - frequencies 1-10, inclusive. - """ - - effective_frequency_breakdown_limit: int = proto.Field( - proto.INT32, - number=1, - ) - - -class FrequencyCap(proto.Message): - r"""A rule specifying the maximum number of times an ad can be - shown to a user over a particular time period. - - Attributes: - impressions (int): - Required. The number of impressions, - inclusive. - time_unit (google.ads.googleads.v19.enums.types.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit): - Required. The type of time unit. - """ - - impressions: int = proto.Field( - proto.INT32, - number=3, - ) - time_unit: ( - frequency_cap_time_unit.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit - ) = proto.Field( - proto.ENUM, - number=2, - enum=frequency_cap_time_unit.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit, - ) - - -class Targeting(proto.Message): - r"""The targeting for which traffic metrics will be reported. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - plannable_location_id (str): - The ID of the selected location. Plannable location IDs can - be obtained from - [ReachPlanService.ListPlannableLocations][google.ads.googleads.v19.services.ReachPlanService.ListPlannableLocations]. - - Requests must set either this field or - ``plannable_location_ids``. - - This field is deprecated as of V12 and will be removed in a - future release. Use ``plannable_location_ids`` instead. - - This field is a member of `oneof`_ ``_plannable_location_id``. - plannable_location_ids (MutableSequence[str]): - The list of plannable location IDs to target with this - forecast. - - If more than one ID is provided, all IDs must have the same - ``parent_country_id``. Planning for more than - ``parent_county`` is not supported. Plannable location IDs - and their ``parent_country_id`` can be obtained from - [ReachPlanService.ListPlannableLocations][google.ads.googleads.v19.services.ReachPlanService.ListPlannableLocations]. - - Requests must set either this field or - ``plannable_location_id``. - age_range (google.ads.googleads.v19.enums.types.ReachPlanAgeRangeEnum.ReachPlanAgeRange): - Targeted age range. - An unset value is equivalent to targeting all - ages. - genders (MutableSequence[google.ads.googleads.v19.common.types.GenderInfo]): - Targeted genders. - An unset value is equivalent to targeting MALE - and FEMALE. - devices (MutableSequence[google.ads.googleads.v19.common.types.DeviceInfo]): - Targeted devices. If not specified, targets all applicable - devices. Applicable devices vary by product and region and - can be obtained from - [ReachPlanService.ListPlannableProducts][google.ads.googleads.v19.services.ReachPlanService.ListPlannableProducts]. - network (google.ads.googleads.v19.enums.types.ReachPlanNetworkEnum.ReachPlanNetwork): - Targetable network for the ad product. If not specified, - targets all applicable networks. Applicable networks vary by - product and region and can be obtained from - [ReachPlanService.ListPlannableProducts][google.ads.googleads.v19.services.ReachPlanService.ListPlannableProducts]. - audience_targeting (google.ads.googleads.v19.services.types.AudienceTargeting): - Targeted audiences. - If not specified, does not target any specific - audience. - """ - - plannable_location_id: str = proto.Field( - proto.STRING, - number=6, - optional=True, - ) - plannable_location_ids: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=8, - ) - age_range: reach_plan_age_range.ReachPlanAgeRangeEnum.ReachPlanAgeRange = ( - proto.Field( - proto.ENUM, - number=2, - enum=reach_plan_age_range.ReachPlanAgeRangeEnum.ReachPlanAgeRange, - ) - ) - genders: MutableSequence[criteria.GenderInfo] = proto.RepeatedField( - proto.MESSAGE, - number=3, - message=criteria.GenderInfo, - ) - devices: MutableSequence[criteria.DeviceInfo] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message=criteria.DeviceInfo, - ) - network: reach_plan_network.ReachPlanNetworkEnum.ReachPlanNetwork = ( - proto.Field( - proto.ENUM, - number=5, - enum=reach_plan_network.ReachPlanNetworkEnum.ReachPlanNetwork, - ) - ) - audience_targeting: "AudienceTargeting" = proto.Field( - proto.MESSAGE, - number=7, - message="AudienceTargeting", - ) - - -class CampaignDuration(proto.Message): - r"""The duration of a planned campaign. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - duration_in_days (int): - The duration value in days. - - This field cannot be combined with the date_range field. - - This field is a member of `oneof`_ ``_duration_in_days``. - date_range (google.ads.googleads.v19.common.types.DateRange): - Date range of the campaign. Dates are in the yyyy-mm-dd - format and inclusive. The end date must be < 1 year in the - future and the date range must be <= 92 days long. - - This field cannot be combined with the duration_in_days - field. - """ - - duration_in_days: int = proto.Field( - proto.INT32, - number=2, - optional=True, - ) - date_range: dates.DateRange = proto.Field( - proto.MESSAGE, - number=3, - message=dates.DateRange, - ) - - -class PlannedProduct(proto.Message): - r"""A product being planned for reach. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - plannable_product_code (str): - Required. Selected product for planning. The code associated - with the ad product (for example: Trueview, Bumper). To list - the available plannable product codes use - [ReachPlanService.ListPlannableProducts][google.ads.googleads.v19.services.ReachPlanService.ListPlannableProducts]. - - This field is a member of `oneof`_ ``_plannable_product_code``. - budget_micros (int): - Required. Maximum budget allocation in micros for the - selected product. The value is specified in the selected - planning currency_code. For example: 1 000 000$ = 1 000 000 - 000 000 micros. - - This field is a member of `oneof`_ ``_budget_micros``. - conversion_rate (float): - Conversion rate as a decimal between 0 and 1, exclusive. For - example: if 2% of ad interactions are expected to lead to - conversions, conversion_rate should be 0.02. This field is - required for DEMAND_GEN plannable products. It is not - supported for other plannable products. - - This field is a member of `oneof`_ ``_conversion_rate``. - advanced_product_targeting (google.ads.googleads.v19.services.types.AdvancedProductTargeting): - Targeting settings for the selected product. To list the - available targeting for each product use - [ReachPlanService.ListPlannableProducts][google.ads.googleads.v19.services.ReachPlanService.ListPlannableProducts]. - """ - - plannable_product_code: str = proto.Field( - proto.STRING, - number=3, - optional=True, - ) - budget_micros: int = proto.Field( - proto.INT64, - number=4, - optional=True, - ) - conversion_rate: float = proto.Field( - proto.DOUBLE, - number=6, - optional=True, - ) - advanced_product_targeting: "AdvancedProductTargeting" = proto.Field( - proto.MESSAGE, - number=5, - message="AdvancedProductTargeting", - ) - - -class GenerateReachForecastResponse(proto.Message): - r"""Response message containing the generated reach curve. - - Attributes: - on_target_audience_metrics (google.ads.googleads.v19.services.types.OnTargetAudienceMetrics): - Reference on target audiences for this curve. - reach_curve (google.ads.googleads.v19.services.types.ReachCurve): - The generated reach curve for the planned - product mix. - """ - - on_target_audience_metrics: "OnTargetAudienceMetrics" = proto.Field( - proto.MESSAGE, - number=1, - message="OnTargetAudienceMetrics", - ) - reach_curve: "ReachCurve" = proto.Field( - proto.MESSAGE, - number=2, - message="ReachCurve", - ) - - -class ReachCurve(proto.Message): - r"""The reach curve for the planned products. - - Attributes: - reach_forecasts (MutableSequence[google.ads.googleads.v19.services.types.ReachForecast]): - All points on the reach curve. - """ - - reach_forecasts: MutableSequence["ReachForecast"] = proto.RepeatedField( - proto.MESSAGE, - number=1, - message="ReachForecast", - ) - - -class ReachForecast(proto.Message): - r"""A point on reach curve. - - Attributes: - cost_micros (int): - The cost in micros. - forecast (google.ads.googleads.v19.services.types.Forecast): - Forecasted traffic metrics for this point. - planned_product_reach_forecasts (MutableSequence[google.ads.googleads.v19.services.types.PlannedProductReachForecast]): - The forecasted allocation and traffic metrics - for each planned product at this point on the - reach curve. - """ - - cost_micros: int = proto.Field( - proto.INT64, - number=5, - ) - forecast: "Forecast" = proto.Field( - proto.MESSAGE, - number=2, - message="Forecast", - ) - planned_product_reach_forecasts: MutableSequence[ - "PlannedProductReachForecast" - ] = proto.RepeatedField( - proto.MESSAGE, - number=4, - message="PlannedProductReachForecast", - ) - - -class Forecast(proto.Message): - r"""Forecasted traffic metrics for the planned products and - targeting. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - on_target_reach (int): - Number of unique people reached at least - GenerateReachForecastRequest.min_effective_frequency or - GenerateReachForecastRequest.effective_frequency_limit times - that exactly matches the Targeting. - - Note that a minimum number of unique people must be reached - in order for data to be reported. If the minimum number is - not met, the on_target_reach value will be rounded to 0. - - This field is a member of `oneof`_ ``_on_target_reach``. - total_reach (int): - Total number of unique people reached at least - GenerateReachForecastRequest.min_effective_frequency or - GenerateReachForecastRequest.effective_frequency_limit - times. This includes people that may fall outside the - specified Targeting. - - Note that a minimum number of unique people must be reached - in order for data to be reported. If the minimum number is - not met, the total_reach value will be rounded to 0. - - This field is a member of `oneof`_ ``_total_reach``. - on_target_impressions (int): - Number of ad impressions that exactly matches - the Targeting. - - This field is a member of `oneof`_ ``_on_target_impressions``. - total_impressions (int): - Total number of ad impressions. This includes - impressions that may fall outside the specified - Targeting, due to insufficient information on - signed-in users. - - This field is a member of `oneof`_ ``_total_impressions``. - viewable_impressions (int): - Number of times the ad's impressions were - considered viewable. See - https://support.google.com/google-ads/answer/7029393 - for more information about what makes an ad - viewable and how viewability is measured. - - This field is a member of `oneof`_ ``_viewable_impressions``. - effective_frequency_breakdowns (MutableSequence[google.ads.googleads.v19.services.types.EffectiveFrequencyBreakdown]): - A list of effective frequency forecasts. The list is ordered - starting with 1+ and ending with the value set in - GenerateReachForecastRequest.effective_frequency_limit. If - no effective_frequency_limit was set, this list will be - empty. - on_target_coview_reach (int): - Number of unique people reached that exactly - matches the Targeting including co-viewers. - - This field is a member of `oneof`_ ``_on_target_coview_reach``. - total_coview_reach (int): - Number of unique people reached including - co-viewers. This includes people that may fall - outside the specified Targeting. - - This field is a member of `oneof`_ ``_total_coview_reach``. - on_target_coview_impressions (int): - Number of ad impressions that exactly matches - the Targeting including co-viewers. - - This field is a member of `oneof`_ ``_on_target_coview_impressions``. - total_coview_impressions (int): - Total number of ad impressions including - co-viewers. This includes impressions that may - fall outside the specified Targeting, due to - insufficient information on signed-in users. - - This field is a member of `oneof`_ ``_total_coview_impressions``. - views (int): - Number of ad views forecasted for the - specified product and targeting. A view is - counted when a viewer views a larger portion or - the entirety of an ad beyond an impression. - - See - https://support.google.com/google-ads/answer/2375431 - for more information on views. - - This field is a member of `oneof`_ ``_views``. - conversions (float): - The number of conversions. This metric is only available for - DEMAND_GEN plannable products. - - See https://support.google.com/google-ads/answer/2375431 for - more information on conversions. - - This field is a member of `oneof`_ ``_conversions``. - """ - - on_target_reach: int = proto.Field( - proto.INT64, - number=5, - optional=True, - ) - total_reach: int = proto.Field( - proto.INT64, - number=6, - optional=True, - ) - on_target_impressions: int = proto.Field( - proto.INT64, - number=7, - optional=True, - ) - total_impressions: int = proto.Field( - proto.INT64, - number=8, - optional=True, - ) - viewable_impressions: int = proto.Field( - proto.INT64, - number=9, - optional=True, - ) - effective_frequency_breakdowns: MutableSequence[ - "EffectiveFrequencyBreakdown" - ] = proto.RepeatedField( - proto.MESSAGE, - number=10, - message="EffectiveFrequencyBreakdown", - ) - on_target_coview_reach: int = proto.Field( - proto.INT64, - number=11, - optional=True, - ) - total_coview_reach: int = proto.Field( - proto.INT64, - number=12, - optional=True, - ) - on_target_coview_impressions: int = proto.Field( - proto.INT64, - number=13, - optional=True, - ) - total_coview_impressions: int = proto.Field( - proto.INT64, - number=14, - optional=True, - ) - views: int = proto.Field( - proto.INT64, - number=15, - optional=True, - ) - conversions: float = proto.Field( - proto.DOUBLE, - number=16, - optional=True, - ) - - -class PlannedProductReachForecast(proto.Message): - r"""The forecasted allocation and traffic metrics for a specific - product at a point on the reach curve. - - Attributes: - plannable_product_code (str): - Selected product for planning. The product - codes returned are within the set of the ones - returned by ListPlannableProducts when using the - same location ID. - cost_micros (int): - The cost in micros. This may differ from the - product's input allocation if one or more - planned products cannot fulfill the budget - because of limited inventory. - planned_product_forecast (google.ads.googleads.v19.services.types.PlannedProductForecast): - Forecasted traffic metrics for this product. - """ - - plannable_product_code: str = proto.Field( - proto.STRING, - number=1, - ) - cost_micros: int = proto.Field( - proto.INT64, - number=2, - ) - planned_product_forecast: "PlannedProductForecast" = proto.Field( - proto.MESSAGE, - number=3, - message="PlannedProductForecast", - ) - - -class PlannedProductForecast(proto.Message): - r"""Forecasted traffic metrics for a planned product. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - on_target_reach (int): - Number of unique people reached that exactly matches the - Targeting. - - Note that a minimum number of unique people must be reached - in order for data to be reported. If the minimum number is - not met, the on_target_reach value will be rounded to 0. - total_reach (int): - Number of unique people reached. This includes people that - may fall outside the specified Targeting. - - Note that a minimum number of unique people must be reached - in order for data to be reported. If the minimum number is - not met, the total_reach value will be rounded to 0. - on_target_impressions (int): - Number of ad impressions that exactly matches - the Targeting. - total_impressions (int): - Total number of ad impressions. This includes - impressions that may fall outside the specified - Targeting, due to insufficient information on - signed-in users. - viewable_impressions (int): - Number of times the ad's impressions were - considered viewable. See - https://support.google.com/google-ads/answer/7029393 - for more information about what makes an ad - viewable and how viewability is measured. - - This field is a member of `oneof`_ ``_viewable_impressions``. - on_target_coview_reach (int): - Number of unique people reached that exactly - matches the Targeting including co-viewers. - - This field is a member of `oneof`_ ``_on_target_coview_reach``. - total_coview_reach (int): - Number of unique people reached including - co-viewers. This includes people that may fall - outside the specified Targeting. - - This field is a member of `oneof`_ ``_total_coview_reach``. - on_target_coview_impressions (int): - Number of ad impressions that exactly matches - the Targeting including co-viewers. - - This field is a member of `oneof`_ ``_on_target_coview_impressions``. - total_coview_impressions (int): - Total number of ad impressions including - co-viewers. This includes impressions that may - fall outside the specified Targeting, due to - insufficient information on signed-in users. - - This field is a member of `oneof`_ ``_total_coview_impressions``. - average_frequency (float): - The number of times per selected time unit a - user will see an ad, averaged over the number of - time units in the forecast length. This field - will only be populated for a Target Frequency - campaign. - - See - https://support.google.com/google-ads/answer/12400225 - for more information about Target Frequency - campaigns. - - This field is a member of `oneof`_ ``_average_frequency``. - views (int): - Number of ad views forecasted for the - specified product and targeting. A view is - counted when a viewer views a larger portion or - the entirety of an ad beyond an impression. - - See - https://support.google.com/google-ads/answer/2375431 - for more information on views. - - This field is a member of `oneof`_ ``_views``. - conversions (float): - The number of conversions. This metric is only available for - DEMAND_GEN plannable products. - - See https://support.google.com/google-ads/answer/2375431 for - more information on conversions. - - This field is a member of `oneof`_ ``_conversions``. - """ - - on_target_reach: int = proto.Field( - proto.INT64, - number=1, - ) - total_reach: int = proto.Field( - proto.INT64, - number=2, - ) - on_target_impressions: int = proto.Field( - proto.INT64, - number=3, - ) - total_impressions: int = proto.Field( - proto.INT64, - number=4, - ) - viewable_impressions: int = proto.Field( - proto.INT64, - number=5, - optional=True, - ) - on_target_coview_reach: int = proto.Field( - proto.INT64, - number=6, - optional=True, - ) - total_coview_reach: int = proto.Field( - proto.INT64, - number=7, - optional=True, - ) - on_target_coview_impressions: int = proto.Field( - proto.INT64, - number=8, - optional=True, - ) - total_coview_impressions: int = proto.Field( - proto.INT64, - number=9, - optional=True, - ) - average_frequency: float = proto.Field( - proto.DOUBLE, - number=10, - optional=True, - ) - views: int = proto.Field( - proto.INT64, - number=11, - optional=True, - ) - conversions: float = proto.Field( - proto.DOUBLE, - number=12, - optional=True, - ) - - -class OnTargetAudienceMetrics(proto.Message): - r"""Audience metrics for the planned products. These metrics consider - the following targeting dimensions: - - - Location - - PlannableAgeRange - - Gender - - AudienceTargeting (only for youtube_audience_size) - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - youtube_audience_size (int): - Reference audience size matching the - considered targeting for YouTube. - - This field is a member of `oneof`_ ``_youtube_audience_size``. - census_audience_size (int): - Reference audience size matching the - considered targeting for Census. - - This field is a member of `oneof`_ ``_census_audience_size``. - """ - - youtube_audience_size: int = proto.Field( - proto.INT64, - number=3, - optional=True, - ) - census_audience_size: int = proto.Field( - proto.INT64, - number=4, - optional=True, - ) - - -class EffectiveFrequencyBreakdown(proto.Message): - r"""A breakdown of the number of unique people reached at a given - effective frequency. - - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - effective_frequency (int): - The effective frequency [1-10]. - on_target_reach (int): - The number of unique people reached at least - effective_frequency times that exactly matches the - Targeting. - - Note that a minimum number of unique people must be reached - in order for data to be reported. If the minimum number is - not met, the on_target_reach value will be rounded to 0. - total_reach (int): - Total number of unique people reached at least - effective_frequency times. This includes people that may - fall outside the specified Targeting. - - Note that a minimum number of unique people must be reached - in order for data to be reported. If the minimum number is - not met, the total_reach value will be rounded to 0. - effective_coview_reach (int): - The number of users (including co-viewing users) reached for - the associated effective_frequency value. - - This field is a member of `oneof`_ ``_effective_coview_reach``. - on_target_effective_coview_reach (int): - The number of users (including co-viewing users) reached for - the associated effective_frequency value within the - specified plan demographic. - - This field is a member of `oneof`_ ``_on_target_effective_coview_reach``. - """ - - effective_frequency: int = proto.Field( - proto.INT32, - number=1, - ) - on_target_reach: int = proto.Field( - proto.INT64, - number=2, - ) - total_reach: int = proto.Field( - proto.INT64, - number=3, - ) - effective_coview_reach: int = proto.Field( - proto.INT64, - number=4, - optional=True, - ) - on_target_effective_coview_reach: int = proto.Field( - proto.INT64, - number=5, - optional=True, - ) - - -class ForecastMetricOptions(proto.Message): - r"""Controls forecast metrics to return. - - Attributes: - include_coview (bool): - Indicates whether to include co-view metrics - in the response forecast. - """ - - include_coview: bool = proto.Field( - proto.BOOL, - number=1, - ) - - -class AudienceTargeting(proto.Message): - r"""Audience targeting for reach forecast. - - Attributes: - user_interest (MutableSequence[google.ads.googleads.v19.common.types.UserInterestInfo]): - List of audiences based on user interests to - be targeted. - """ - - user_interest: MutableSequence[criteria.UserInterestInfo] = ( - proto.RepeatedField( - proto.MESSAGE, - number=1, - message=criteria.UserInterestInfo, - ) - ) - - -class AdvancedProductTargeting(proto.Message): - r"""Advanced targeting settings for products. - - .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields - - Attributes: - surface_targeting_settings (google.ads.googleads.v19.services.types.SurfaceTargeting): - Surface targeting settings for this product. - target_frequency_settings (google.ads.googleads.v19.services.types.TargetFrequencySettings): - Settings for a Target frequency campaign. Must be set when - selecting the TARGET_FREQUENCY product. - - See https://support.google.com/google-ads/answer/12400225 - for more information about Target Frequency campaigns. - youtube_select_settings (google.ads.googleads.v19.services.types.YouTubeSelectSettings): - Settings for YouTube Select targeting. - - This field is a member of `oneof`_ ``advanced_targeting``. - """ - - surface_targeting_settings: "SurfaceTargeting" = proto.Field( - proto.MESSAGE, - number=2, - message="SurfaceTargeting", - ) - target_frequency_settings: "TargetFrequencySettings" = proto.Field( - proto.MESSAGE, - number=3, - message="TargetFrequencySettings", - ) - youtube_select_settings: "YouTubeSelectSettings" = proto.Field( - proto.MESSAGE, - number=1, - oneof="advanced_targeting", - message="YouTubeSelectSettings", - ) - - -class YouTubeSelectSettings(proto.Message): - r"""Request settings for YouTube Select Lineups - - Attributes: - lineup_id (int): - Lineup for YouTube Select Targeting. - """ - - lineup_id: int = proto.Field( - proto.INT64, - number=1, - ) - - -class YouTubeSelectLineUp(proto.Message): - r"""A Plannable YouTube Select Lineup for product targeting. - - Attributes: - lineup_id (int): - The ID of the YouTube Select Lineup. - lineup_name (str): - The unique name of the YouTube Select Lineup. - """ - - lineup_id: int = proto.Field( - proto.INT64, - number=1, - ) - lineup_name: str = proto.Field( - proto.STRING, - number=2, - ) - - -class SurfaceTargetingCombinations(proto.Message): - r"""The surface targeting combinations available for an ad - product. - - Attributes: - default_targeting (google.ads.googleads.v19.services.types.SurfaceTargeting): - Default surface targeting applied to the ad - product. - available_targeting_combinations (MutableSequence[google.ads.googleads.v19.services.types.SurfaceTargeting]): - Available surface target combinations for the - ad product. - """ - - default_targeting: "SurfaceTargeting" = proto.Field( - proto.MESSAGE, - number=1, - message="SurfaceTargeting", - ) - available_targeting_combinations: MutableSequence["SurfaceTargeting"] = ( - proto.RepeatedField( - proto.MESSAGE, - number=2, - message="SurfaceTargeting", - ) - ) - - -class SurfaceTargeting(proto.Message): - r"""Container for surfaces for a product. Surfaces refer to the - available types of ad inventories such as In-Feed, In-Stream, - and Shorts. - - Attributes: - surfaces (MutableSequence[google.ads.googleads.v19.enums.types.ReachPlanSurfaceEnum.ReachPlanSurface]): - List of surfaces available to target. - """ - - surfaces: MutableSequence[ - reach_plan_surface.ReachPlanSurfaceEnum.ReachPlanSurface - ] = proto.RepeatedField( - proto.ENUM, - number=1, - enum=reach_plan_surface.ReachPlanSurfaceEnum.ReachPlanSurface, - ) - - -class TargetFrequencySettings(proto.Message): - r"""Target Frequency settings for a supported product. - - Attributes: - time_unit (google.ads.googleads.v19.enums.types.TargetFrequencyTimeUnitEnum.TargetFrequencyTimeUnit): - Required. The time unit used to describe the time frame for - target_frequency. - target_frequency (int): - Required. The target frequency goal per - selected time unit. - """ - - time_unit: ( - target_frequency_time_unit.TargetFrequencyTimeUnitEnum.TargetFrequencyTimeUnit - ) = proto.Field( - proto.ENUM, - number=1, - enum=target_frequency_time_unit.TargetFrequencyTimeUnitEnum.TargetFrequencyTimeUnit, - ) - target_frequency: int = proto.Field( - proto.INT32, - number=2, - ) - - -__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/__init__.py b/google/ads/googleads/v23/__init__.py new file mode 100644 index 000000000..0a324f8ad --- /dev/null +++ b/google/ads/googleads/v23/__init__.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from google.ads.googleads.v23 import gapic_version as package_version + +import google.api_core as api_core +import sys + +__version__ = package_version.__version__ + +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata + +from . import common +from . import enums +from . import errors +from . import resources +from . import services + + +if hasattr(api_core, "check_python_version") and hasattr( + api_core, "check_dependency_versions" +): # pragma: NO COVER + api_core.check_python_version("google.ads.googleads.v23") # type: ignore + api_core.check_dependency_versions("google.ads.googleads.v23") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.ads.googleads.v23" + if sys.version_info < (3, 9): + warnings.warn( + "You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning, + ) + if sys.version_info[:2] == (3, 9): + warnings.warn( + f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning, + ) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version( + _dependency_package + ) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn( + f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning, + ) + except Exception: + warnings.warn( + "Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/" + ) + +__all__ = ( + "common", + "enums", + "errors", + "resources", + "services", +) diff --git a/google/ads/googleads/v23/common/__init__.py b/google/ads/googleads/v23/common/__init__.py new file mode 100644 index 000000000..3da3bcf8c --- /dev/null +++ b/google/ads/googleads/v23/common/__init__.py @@ -0,0 +1,831 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from google.ads.googleads.v23 import gapic_version as package_version + +import google.api_core as api_core +import sys + +__version__ = package_version.__version__ + +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata + + +from .types.ad_asset import AdAppDeepLinkAsset +from .types.ad_asset import AdCallToActionAsset +from .types.ad_asset import AdDemandGenCarouselCardAsset +from .types.ad_asset import AdImageAsset +from .types.ad_asset import AdMediaBundleAsset +from .types.ad_asset import AdTextAsset +from .types.ad_asset import AdVideoAsset +from .types.ad_asset import AdVideoAssetInfo +from .types.ad_asset import AdVideoAssetInventoryPreferences +from .types.ad_asset import AdVideoAssetLinkFeatureControl +from .types.ad_type_infos import AppAdInfo +from .types.ad_type_infos import AppEngagementAdInfo +from .types.ad_type_infos import AppPreRegistrationAdInfo +from .types.ad_type_infos import DemandGenCarouselAdInfo +from .types.ad_type_infos import DemandGenMultiAssetAdInfo +from .types.ad_type_infos import DemandGenProductAdInfo +from .types.ad_type_infos import DemandGenVideoResponsiveAdInfo +from .types.ad_type_infos import DisplayUploadAdInfo +from .types.ad_type_infos import ExpandedDynamicSearchAdInfo +from .types.ad_type_infos import ExpandedTextAdInfo +from .types.ad_type_infos import HotelAdInfo +from .types.ad_type_infos import ImageAdInfo +from .types.ad_type_infos import InFeedVideoAdInfo +from .types.ad_type_infos import LegacyAppInstallAdInfo +from .types.ad_type_infos import LegacyResponsiveDisplayAdInfo +from .types.ad_type_infos import LocalAdInfo +from .types.ad_type_infos import ResponsiveDisplayAdControlSpec +from .types.ad_type_infos import ResponsiveDisplayAdInfo +from .types.ad_type_infos import ResponsiveSearchAdInfo +from .types.ad_type_infos import ShoppingComparisonListingAdInfo +from .types.ad_type_infos import ShoppingProductAdInfo +from .types.ad_type_infos import ShoppingSmartAdInfo +from .types.ad_type_infos import SmartCampaignAdInfo +from .types.ad_type_infos import TextAdInfo +from .types.ad_type_infos import TravelAdInfo +from .types.ad_type_infos import VideoAdInfo +from .types.ad_type_infos import VideoBumperInStreamAdInfo +from .types.ad_type_infos import VideoNonSkippableInStreamAdInfo +from .types.ad_type_infos import VideoOutstreamAdInfo +from .types.ad_type_infos import VideoResponsiveAdInfo +from .types.ad_type_infos import VideoTrueViewInStreamAdInfo +from .types.ad_type_infos import YouTubeAudioAdInfo +from .types.additional_application_info import AdditionalApplicationInfo +from .types.asset_policy import AdAssetPolicySummary +from .types.asset_policy import AssetDisapproved +from .types.asset_policy import AssetLinkPrimaryStatusDetails +from .types.asset_set_types import BusinessProfileBusinessNameFilter +from .types.asset_set_types import BusinessProfileLocationGroup +from .types.asset_set_types import BusinessProfileLocationSet +from .types.asset_set_types import ChainFilter +from .types.asset_set_types import ChainLocationGroup +from .types.asset_set_types import ChainSet +from .types.asset_set_types import DynamicBusinessProfileLocationGroupFilter +from .types.asset_set_types import LocationSet +from .types.asset_set_types import MapsLocationInfo +from .types.asset_set_types import MapsLocationSet +from .types.asset_types import AppDeepLinkAsset +from .types.asset_types import BookOnGoogleAsset +from .types.asset_types import BusinessMessageAsset +from .types.asset_types import BusinessMessageCallToActionInfo +from .types.asset_types import BusinessProfileLocation +from .types.asset_types import CallAsset +from .types.asset_types import CalloutAsset +from .types.asset_types import CallToActionAsset +from .types.asset_types import DemandGenCarouselCardAsset +from .types.asset_types import DynamicCustomAsset +from .types.asset_types import DynamicEducationAsset +from .types.asset_types import DynamicFlightsAsset +from .types.asset_types import DynamicHotelsAndRentalsAsset +from .types.asset_types import DynamicJobsAsset +from .types.asset_types import DynamicLocalAsset +from .types.asset_types import DynamicRealEstateAsset +from .types.asset_types import DynamicTravelAsset +from .types.asset_types import FacebookMessengerBusinessMessageInfo +from .types.asset_types import HotelCalloutAsset +from .types.asset_types import HotelPropertyAsset +from .types.asset_types import ImageAsset +from .types.asset_types import ImageDimension +from .types.asset_types import LeadFormAsset +from .types.asset_types import LeadFormCustomQuestionField +from .types.asset_types import LeadFormDeliveryMethod +from .types.asset_types import LeadFormField +from .types.asset_types import LeadFormSingleChoiceAnswers +from .types.asset_types import LocationAsset +from .types.asset_types import MediaBundleAsset +from .types.asset_types import MobileAppAsset +from .types.asset_types import PageFeedAsset +from .types.asset_types import PriceAsset +from .types.asset_types import PriceOffering +from .types.asset_types import PromotionAsset +from .types.asset_types import PromotionBarcodeInfo +from .types.asset_types import PromotionQrCodeInfo +from .types.asset_types import SitelinkAsset +from .types.asset_types import StructuredSnippetAsset +from .types.asset_types import TextAsset +from .types.asset_types import WebhookDelivery +from .types.asset_types import WhatsappBusinessMessageInfo +from .types.asset_types import YoutubeVideoAsset +from .types.asset_types import YouTubeVideoListAsset +from .types.asset_types import ZaloBusinessMessageInfo +from .types.asset_usage import AssetUsage +from .types.audience_insights_attribute import AudienceInsightsAttribute +from .types.audience_insights_attribute import AudienceInsightsAttributeMetadata +from .types.audience_insights_attribute import ( + AudienceInsightsAttributeMetadataGroup, +) +from .types.audience_insights_attribute import AudienceInsightsCategory +from .types.audience_insights_attribute import AudienceInsightsEntity +from .types.audience_insights_attribute import AudienceInsightsLineup +from .types.audience_insights_attribute import KnowledgeGraphAttributeMetadata +from .types.audience_insights_attribute import LineupAttributeMetadata +from .types.audience_insights_attribute import LocationAttributeMetadata +from .types.audience_insights_attribute import UserInterestAttributeMetadata +from .types.audience_insights_attribute import UserListAttributeMetadata +from .types.audience_insights_attribute import YouTubeChannelAttributeMetadata +from .types.audience_insights_attribute import YouTubeVideoAttributeMetadata +from .types.audiences import AgeDimension +from .types.audiences import AgeSegment +from .types.audiences import AudienceDimension +from .types.audiences import AudienceExclusionDimension +from .types.audiences import AudienceSegment +from .types.audiences import AudienceSegmentDimension +from .types.audiences import CustomAudienceSegment +from .types.audiences import DetailedDemographicSegment +from .types.audiences import ExclusionSegment +from .types.audiences import GenderDimension +from .types.audiences import HouseholdIncomeDimension +from .types.audiences import LifeEventSegment +from .types.audiences import ParentalStatusDimension +from .types.audiences import UserInterestSegment +from .types.audiences import UserListSegment +from .types.bidding import Commission +from .types.bidding import EnhancedCpc +from .types.bidding import FixedCpm +from .types.bidding import FixedCpmTargetFrequencyGoalInfo +from .types.bidding import ManualCpa +from .types.bidding import ManualCpc +from .types.bidding import ManualCpm +from .types.bidding import ManualCpv +from .types.bidding import MaximizeConversions +from .types.bidding import MaximizeConversionValue +from .types.bidding import PercentCpc +from .types.bidding import TargetCpa +from .types.bidding import TargetCpc +from .types.bidding import TargetCpm +from .types.bidding import TargetCpmTargetFrequencyGoal +from .types.bidding import TargetCpv +from .types.bidding import TargetImpressionShare +from .types.bidding import TargetRoas +from .types.bidding import TargetSpend +from .types.campaign_goal_settings import CampaignGoalSettings +from .types.click_location import ClickLocation +from .types.consent import Consent +from .types.criteria import ActivityCityInfo +from .types.criteria import ActivityCountryInfo +from .types.criteria import ActivityIdInfo +from .types.criteria import ActivityRatingInfo +from .types.criteria import ActivityStateInfo +from .types.criteria import AddressInfo +from .types.criteria import AdScheduleInfo +from .types.criteria import AgeRangeInfo +from .types.criteria import AppPaymentModelInfo +from .types.criteria import AudienceInfo +from .types.criteria import BrandInfo +from .types.criteria import BrandListInfo +from .types.criteria import CarrierInfo +from .types.criteria import CombinedAudienceInfo +from .types.criteria import ContentLabelInfo +from .types.criteria import CustomAffinityInfo +from .types.criteria import CustomAudienceInfo +from .types.criteria import CustomIntentInfo +from .types.criteria import DeviceInfo +from .types.criteria import ExtendedDemographicInfo +from .types.criteria import GenderInfo +from .types.criteria import GeoPointInfo +from .types.criteria import HotelAdvanceBookingWindowInfo +from .types.criteria import HotelCheckInDateRangeInfo +from .types.criteria import HotelCheckInDayInfo +from .types.criteria import HotelCityInfo +from .types.criteria import HotelClassInfo +from .types.criteria import HotelCountryRegionInfo +from .types.criteria import HotelDateSelectionTypeInfo +from .types.criteria import HotelIdInfo +from .types.criteria import HotelLengthOfStayInfo +from .types.criteria import HotelStateInfo +from .types.criteria import IncomeRangeInfo +from .types.criteria import InteractionTypeInfo +from .types.criteria import IpBlockInfo +from .types.criteria import KeywordInfo +from .types.criteria import KeywordThemeInfo +from .types.criteria import LanguageInfo +from .types.criteria import LifeEventInfo +from .types.criteria import ListingDimensionInfo +from .types.criteria import ListingDimensionPath +from .types.criteria import ListingGroupInfo +from .types.criteria import ListingScopeInfo +from .types.criteria import LocalServiceIdInfo +from .types.criteria import LocationGroupInfo +from .types.criteria import LocationInfo +from .types.criteria import MobileAppCategoryInfo +from .types.criteria import MobileApplicationInfo +from .types.criteria import MobileDeviceInfo +from .types.criteria import NegativeKeywordListInfo +from .types.criteria import OperatingSystemVersionInfo +from .types.criteria import ParentalStatusInfo +from .types.criteria import PlacementInfo +from .types.criteria import PlacementListInfo +from .types.criteria import ProductBrandInfo +from .types.criteria import ProductCategoryInfo +from .types.criteria import ProductChannelExclusivityInfo +from .types.criteria import ProductChannelInfo +from .types.criteria import ProductConditionInfo +from .types.criteria import ProductCustomAttributeInfo +from .types.criteria import ProductGroupingInfo +from .types.criteria import ProductItemIdInfo +from .types.criteria import ProductLabelsInfo +from .types.criteria import ProductLegacyConditionInfo +from .types.criteria import ProductTypeFullInfo +from .types.criteria import ProductTypeInfo +from .types.criteria import ProximityInfo +from .types.criteria import SearchThemeInfo +from .types.criteria import TopicInfo +from .types.criteria import UnknownListingDimensionInfo +from .types.criteria import UserInterestInfo +from .types.criteria import UserListInfo +from .types.criteria import VerticalAdsItemGroupRuleInfo +from .types.criteria import VerticalAdsItemGroupRuleListInfo +from .types.criteria import VideoLineupInfo +from .types.criteria import WebpageConditionInfo +from .types.criteria import WebpageInfo +from .types.criteria import WebpageListInfo +from .types.criteria import WebpageSampleInfo +from .types.criteria import YouTubeChannelInfo +from .types.criteria import YouTubeVideoInfo +from .types.criterion_category_availability import CriterionCategoryAvailability +from .types.criterion_category_availability import ( + CriterionCategoryChannelAvailability, +) +from .types.criterion_category_availability import ( + CriterionCategoryLocaleAvailability, +) +from .types.custom_parameter import CustomParameter +from .types.customizer_value import CustomizerValue +from .types.dates import DateRange +from .types.dates import YearMonth +from .types.dates import YearMonthRange +from .types.extensions import CallFeedItem +from .types.extensions import CalloutFeedItem +from .types.extensions import SitelinkFeedItem +from .types.feed_common import Money +from .types.final_app_url import FinalAppUrl +from .types.frequency_cap import FrequencyCapEntry +from .types.frequency_cap import FrequencyCapKey +from .types.goal_common import CustomerLifecycleOptimizationValueSettings +from .types.goal_setting import GoalSetting +from .types.keyword_plan_common import ConceptGroup +from .types.keyword_plan_common import HistoricalMetricsOptions +from .types.keyword_plan_common import KeywordAnnotations +from .types.keyword_plan_common import KeywordConcept +from .types.keyword_plan_common import KeywordPlanAggregateMetricResults +from .types.keyword_plan_common import KeywordPlanAggregateMetrics +from .types.keyword_plan_common import KeywordPlanDeviceSearches +from .types.keyword_plan_common import KeywordPlanHistoricalMetrics +from .types.keyword_plan_common import MonthlySearchVolume +from .types.lifecycle_goals import LifecycleGoalValueSettings +from .types.local_services import LocalServicesDocumentReadOnly +from .types.metric_goal import MetricGoal +from .types.metrics import Metrics +from .types.metrics import SearchVolumeRange +from .types.offline_user_data import CustomerMatchUserListMetadata +from .types.offline_user_data import EventAttribute +from .types.offline_user_data import EventItemAttribute +from .types.offline_user_data import ItemAttribute +from .types.offline_user_data import OfflineUserAddressInfo +from .types.offline_user_data import ShoppingLoyalty +from .types.offline_user_data import StoreAttribute +from .types.offline_user_data import StoreSalesMetadata +from .types.offline_user_data import StoreSalesThirdPartyMetadata +from .types.offline_user_data import TransactionAttribute +from .types.offline_user_data import UserAttribute +from .types.offline_user_data import UserData +from .types.offline_user_data import UserIdentifier +from .types.policy import PolicyTopicConstraint +from .types.policy import PolicyTopicEntry +from .types.policy import PolicyTopicEvidence +from .types.policy import PolicyValidationParameter +from .types.policy import PolicyViolationKey +from .types.policy_summary import PolicySummary +from .types.real_time_bidding_setting import RealTimeBiddingSetting +from .types.segments import AssetInteractionTarget +from .types.segments import BudgetCampaignAssociationStatus +from .types.segments import Keyword +from .types.segments import Segments +from .types.segments import SkAdNetworkSourceApp +from .types.simulation import BudgetSimulationPoint +from .types.simulation import BudgetSimulationPointList +from .types.simulation import CpcBidSimulationPoint +from .types.simulation import CpcBidSimulationPointList +from .types.simulation import CpvBidSimulationPoint +from .types.simulation import CpvBidSimulationPointList +from .types.simulation import PercentCpcBidSimulationPoint +from .types.simulation import PercentCpcBidSimulationPointList +from .types.simulation import TargetCpaSimulationPoint +from .types.simulation import TargetCpaSimulationPointList +from .types.simulation import TargetImpressionShareSimulationPoint +from .types.simulation import TargetImpressionShareSimulationPointList +from .types.simulation import TargetRoasSimulationPoint +from .types.simulation import TargetRoasSimulationPointList +from .types.tag_snippet import TagSnippet +from .types.targeting_setting import TargetingSetting +from .types.targeting_setting import TargetRestriction +from .types.targeting_setting import TargetRestrictionOperation +from .types.text_label import TextLabel +from .types.third_party_integration_partners import ( + CampaignThirdPartyBrandLiftIntegrationPartner, +) +from .types.third_party_integration_partners import ( + CampaignThirdPartyBrandSafetyIntegrationPartner, +) +from .types.third_party_integration_partners import ( + CampaignThirdPartyIntegrationPartners, +) +from .types.third_party_integration_partners import ( + CampaignThirdPartyReachIntegrationPartner, +) +from .types.third_party_integration_partners import ( + CampaignThirdPartyViewabilityIntegrationPartner, +) +from .types.third_party_integration_partners import ( + CustomerThirdPartyBrandLiftIntegrationPartner, +) +from .types.third_party_integration_partners import ( + CustomerThirdPartyBrandSafetyIntegrationPartner, +) +from .types.third_party_integration_partners import ( + CustomerThirdPartyIntegrationPartners, +) +from .types.third_party_integration_partners import ( + CustomerThirdPartyReachIntegrationPartner, +) +from .types.third_party_integration_partners import ( + CustomerThirdPartyViewabilityIntegrationPartner, +) +from .types.third_party_integration_partners import ( + ThirdPartyIntegrationPartnerData, +) +from .types.url_collection import UrlCollection +from .types.user_lists import BasicUserListInfo +from .types.user_lists import CrmBasedUserListInfo +from .types.user_lists import FlexibleRuleOperandInfo +from .types.user_lists import FlexibleRuleUserListInfo +from .types.user_lists import LogicalUserListInfo +from .types.user_lists import LogicalUserListOperandInfo +from .types.user_lists import LookalikeUserListInfo +from .types.user_lists import RuleBasedUserListInfo +from .types.user_lists import SimilarUserListInfo +from .types.user_lists import UserListActionInfo +from .types.user_lists import UserListDateRuleItemInfo +from .types.user_lists import UserListLogicalRuleInfo +from .types.user_lists import UserListNumberRuleItemInfo +from .types.user_lists import UserListRuleInfo +from .types.user_lists import UserListRuleItemGroupInfo +from .types.user_lists import UserListRuleItemInfo +from .types.user_lists import UserListStringRuleItemInfo +from .types.value import Value + +if hasattr(api_core, "check_python_version") and hasattr( + api_core, "check_dependency_versions" +): # pragma: NO COVER + api_core.check_python_version("google.ads.googleads.v23") # type: ignore + api_core.check_dependency_versions("google.ads.googleads.v23") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.ads.googleads.v23" + if sys.version_info < (3, 9): + warnings.warn( + "You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning, + ) + if sys.version_info[:2] == (3, 9): + warnings.warn( + f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning, + ) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version( + _dependency_package + ) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn( + f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning, + ) + except Exception: + warnings.warn( + "Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/" + ) + +__all__ = ( + "ActivityCityInfo", + "ActivityCountryInfo", + "ActivityIdInfo", + "ActivityRatingInfo", + "ActivityStateInfo", + "AdAppDeepLinkAsset", + "AdAssetPolicySummary", + "AdCallToActionAsset", + "AdDemandGenCarouselCardAsset", + "AdImageAsset", + "AdMediaBundleAsset", + "AdScheduleInfo", + "AdTextAsset", + "AdVideoAsset", + "AdVideoAssetInfo", + "AdVideoAssetInventoryPreferences", + "AdVideoAssetLinkFeatureControl", + "AdditionalApplicationInfo", + "AddressInfo", + "AgeDimension", + "AgeRangeInfo", + "AgeSegment", + "AppAdInfo", + "AppDeepLinkAsset", + "AppEngagementAdInfo", + "AppPaymentModelInfo", + "AppPreRegistrationAdInfo", + "AssetDisapproved", + "AssetInteractionTarget", + "AssetLinkPrimaryStatusDetails", + "AssetUsage", + "AudienceDimension", + "AudienceExclusionDimension", + "AudienceInfo", + "AudienceInsightsAttribute", + "AudienceInsightsAttributeMetadata", + "AudienceInsightsAttributeMetadataGroup", + "AudienceInsightsCategory", + "AudienceInsightsEntity", + "AudienceInsightsLineup", + "AudienceSegment", + "AudienceSegmentDimension", + "BasicUserListInfo", + "BookOnGoogleAsset", + "BrandInfo", + "BrandListInfo", + "BudgetCampaignAssociationStatus", + "BudgetSimulationPoint", + "BudgetSimulationPointList", + "BusinessMessageAsset", + "BusinessMessageCallToActionInfo", + "BusinessProfileBusinessNameFilter", + "BusinessProfileLocation", + "BusinessProfileLocationGroup", + "BusinessProfileLocationSet", + "CallAsset", + "CallFeedItem", + "CallToActionAsset", + "CalloutAsset", + "CalloutFeedItem", + "CampaignGoalSettings", + "CampaignThirdPartyBrandLiftIntegrationPartner", + "CampaignThirdPartyBrandSafetyIntegrationPartner", + "CampaignThirdPartyIntegrationPartners", + "CampaignThirdPartyReachIntegrationPartner", + "CampaignThirdPartyViewabilityIntegrationPartner", + "CarrierInfo", + "ChainFilter", + "ChainLocationGroup", + "ChainSet", + "ClickLocation", + "CombinedAudienceInfo", + "Commission", + "ConceptGroup", + "Consent", + "ContentLabelInfo", + "CpcBidSimulationPoint", + "CpcBidSimulationPointList", + "CpvBidSimulationPoint", + "CpvBidSimulationPointList", + "CriterionCategoryAvailability", + "CriterionCategoryChannelAvailability", + "CriterionCategoryLocaleAvailability", + "CrmBasedUserListInfo", + "CustomAffinityInfo", + "CustomAudienceInfo", + "CustomAudienceSegment", + "CustomIntentInfo", + "CustomParameter", + "CustomerLifecycleOptimizationValueSettings", + "CustomerMatchUserListMetadata", + "CustomerThirdPartyBrandLiftIntegrationPartner", + "CustomerThirdPartyBrandSafetyIntegrationPartner", + "CustomerThirdPartyIntegrationPartners", + "CustomerThirdPartyReachIntegrationPartner", + "CustomerThirdPartyViewabilityIntegrationPartner", + "CustomizerValue", + "DateRange", + "DemandGenCarouselAdInfo", + "DemandGenCarouselCardAsset", + "DemandGenMultiAssetAdInfo", + "DemandGenProductAdInfo", + "DemandGenVideoResponsiveAdInfo", + "DetailedDemographicSegment", + "DeviceInfo", + "DisplayUploadAdInfo", + "DynamicBusinessProfileLocationGroupFilter", + "DynamicCustomAsset", + "DynamicEducationAsset", + "DynamicFlightsAsset", + "DynamicHotelsAndRentalsAsset", + "DynamicJobsAsset", + "DynamicLocalAsset", + "DynamicRealEstateAsset", + "DynamicTravelAsset", + "EnhancedCpc", + "EventAttribute", + "EventItemAttribute", + "ExclusionSegment", + "ExpandedDynamicSearchAdInfo", + "ExpandedTextAdInfo", + "ExtendedDemographicInfo", + "FacebookMessengerBusinessMessageInfo", + "FinalAppUrl", + "FixedCpm", + "FixedCpmTargetFrequencyGoalInfo", + "FlexibleRuleOperandInfo", + "FlexibleRuleUserListInfo", + "FrequencyCapEntry", + "FrequencyCapKey", + "GenderDimension", + "GenderInfo", + "GeoPointInfo", + "GoalSetting", + "HistoricalMetricsOptions", + "HotelAdInfo", + "HotelAdvanceBookingWindowInfo", + "HotelCalloutAsset", + "HotelCheckInDateRangeInfo", + "HotelCheckInDayInfo", + "HotelCityInfo", + "HotelClassInfo", + "HotelCountryRegionInfo", + "HotelDateSelectionTypeInfo", + "HotelIdInfo", + "HotelLengthOfStayInfo", + "HotelPropertyAsset", + "HotelStateInfo", + "HouseholdIncomeDimension", + "ImageAdInfo", + "ImageAsset", + "ImageDimension", + "InFeedVideoAdInfo", + "IncomeRangeInfo", + "InteractionTypeInfo", + "IpBlockInfo", + "ItemAttribute", + "Keyword", + "KeywordAnnotations", + "KeywordConcept", + "KeywordInfo", + "KeywordPlanAggregateMetricResults", + "KeywordPlanAggregateMetrics", + "KeywordPlanDeviceSearches", + "KeywordPlanHistoricalMetrics", + "KeywordThemeInfo", + "KnowledgeGraphAttributeMetadata", + "LanguageInfo", + "LeadFormAsset", + "LeadFormCustomQuestionField", + "LeadFormDeliveryMethod", + "LeadFormField", + "LeadFormSingleChoiceAnswers", + "LegacyAppInstallAdInfo", + "LegacyResponsiveDisplayAdInfo", + "LifeEventInfo", + "LifeEventSegment", + "LifecycleGoalValueSettings", + "LineupAttributeMetadata", + "ListingDimensionInfo", + "ListingDimensionPath", + "ListingGroupInfo", + "ListingScopeInfo", + "LocalAdInfo", + "LocalServiceIdInfo", + "LocalServicesDocumentReadOnly", + "LocationAsset", + "LocationAttributeMetadata", + "LocationGroupInfo", + "LocationInfo", + "LocationSet", + "LogicalUserListInfo", + "LogicalUserListOperandInfo", + "LookalikeUserListInfo", + "ManualCpa", + "ManualCpc", + "ManualCpm", + "ManualCpv", + "MapsLocationInfo", + "MapsLocationSet", + "MaximizeConversionValue", + "MaximizeConversions", + "MediaBundleAsset", + "MetricGoal", + "Metrics", + "MobileAppAsset", + "MobileAppCategoryInfo", + "MobileApplicationInfo", + "MobileDeviceInfo", + "Money", + "MonthlySearchVolume", + "NegativeKeywordListInfo", + "OfflineUserAddressInfo", + "OperatingSystemVersionInfo", + "PageFeedAsset", + "ParentalStatusDimension", + "ParentalStatusInfo", + "PercentCpc", + "PercentCpcBidSimulationPoint", + "PercentCpcBidSimulationPointList", + "PlacementInfo", + "PlacementListInfo", + "PolicySummary", + "PolicyTopicConstraint", + "PolicyTopicEntry", + "PolicyTopicEvidence", + "PolicyValidationParameter", + "PolicyViolationKey", + "PriceAsset", + "PriceOffering", + "ProductBrandInfo", + "ProductCategoryInfo", + "ProductChannelExclusivityInfo", + "ProductChannelInfo", + "ProductConditionInfo", + "ProductCustomAttributeInfo", + "ProductGroupingInfo", + "ProductItemIdInfo", + "ProductLabelsInfo", + "ProductLegacyConditionInfo", + "ProductTypeFullInfo", + "ProductTypeInfo", + "PromotionAsset", + "PromotionBarcodeInfo", + "PromotionQrCodeInfo", + "ProximityInfo", + "RealTimeBiddingSetting", + "ResponsiveDisplayAdControlSpec", + "ResponsiveDisplayAdInfo", + "ResponsiveSearchAdInfo", + "RuleBasedUserListInfo", + "SearchThemeInfo", + "SearchVolumeRange", + "Segments", + "ShoppingComparisonListingAdInfo", + "ShoppingLoyalty", + "ShoppingProductAdInfo", + "ShoppingSmartAdInfo", + "SimilarUserListInfo", + "SitelinkAsset", + "SitelinkFeedItem", + "SkAdNetworkSourceApp", + "SmartCampaignAdInfo", + "StoreAttribute", + "StoreSalesMetadata", + "StoreSalesThirdPartyMetadata", + "StructuredSnippetAsset", + "TagSnippet", + "TargetCpa", + "TargetCpaSimulationPoint", + "TargetCpaSimulationPointList", + "TargetCpc", + "TargetCpm", + "TargetCpmTargetFrequencyGoal", + "TargetCpv", + "TargetImpressionShare", + "TargetImpressionShareSimulationPoint", + "TargetImpressionShareSimulationPointList", + "TargetRestriction", + "TargetRestrictionOperation", + "TargetRoas", + "TargetRoasSimulationPoint", + "TargetRoasSimulationPointList", + "TargetSpend", + "TargetingSetting", + "TextAdInfo", + "TextAsset", + "TextLabel", + "ThirdPartyIntegrationPartnerData", + "TopicInfo", + "TransactionAttribute", + "TravelAdInfo", + "UnknownListingDimensionInfo", + "UrlCollection", + "UserAttribute", + "UserData", + "UserIdentifier", + "UserInterestAttributeMetadata", + "UserInterestInfo", + "UserInterestSegment", + "UserListActionInfo", + "UserListAttributeMetadata", + "UserListDateRuleItemInfo", + "UserListInfo", + "UserListLogicalRuleInfo", + "UserListNumberRuleItemInfo", + "UserListRuleInfo", + "UserListRuleItemGroupInfo", + "UserListRuleItemInfo", + "UserListSegment", + "UserListStringRuleItemInfo", + "Value", + "VerticalAdsItemGroupRuleInfo", + "VerticalAdsItemGroupRuleListInfo", + "VideoAdInfo", + "VideoBumperInStreamAdInfo", + "VideoLineupInfo", + "VideoNonSkippableInStreamAdInfo", + "VideoOutstreamAdInfo", + "VideoResponsiveAdInfo", + "VideoTrueViewInStreamAdInfo", + "WebhookDelivery", + "WebpageConditionInfo", + "WebpageInfo", + "WebpageListInfo", + "WebpageSampleInfo", + "WhatsappBusinessMessageInfo", + "YearMonth", + "YearMonthRange", + "YouTubeAudioAdInfo", + "YouTubeChannelAttributeMetadata", + "YouTubeChannelInfo", + "YouTubeVideoAttributeMetadata", + "YouTubeVideoInfo", + "YouTubeVideoListAsset", + "YoutubeVideoAsset", + "ZaloBusinessMessageInfo", +) diff --git a/google/ads/googleads/v19/common/services/__init__.py b/google/ads/googleads/v23/common/services/__init__.py similarity index 100% rename from google/ads/googleads/v19/common/services/__init__.py rename to google/ads/googleads/v23/common/services/__init__.py diff --git a/google/ads/googleads/v23/common/types/__init__.py b/google/ads/googleads/v23/common/types/__init__.py new file mode 100644 index 000000000..206150e93 --- /dev/null +++ b/google/ads/googleads/v23/common/types/__init__.py @@ -0,0 +1,776 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .ad_asset import ( + AdAppDeepLinkAsset, + AdCallToActionAsset, + AdDemandGenCarouselCardAsset, + AdImageAsset, + AdMediaBundleAsset, + AdTextAsset, + AdVideoAsset, + AdVideoAssetInfo, + AdVideoAssetInventoryPreferences, + AdVideoAssetLinkFeatureControl, +) +from .ad_type_infos import ( + AppAdInfo, + AppEngagementAdInfo, + AppPreRegistrationAdInfo, + DemandGenCarouselAdInfo, + DemandGenMultiAssetAdInfo, + DemandGenProductAdInfo, + DemandGenVideoResponsiveAdInfo, + DisplayUploadAdInfo, + ExpandedDynamicSearchAdInfo, + ExpandedTextAdInfo, + HotelAdInfo, + ImageAdInfo, + InFeedVideoAdInfo, + LegacyAppInstallAdInfo, + LegacyResponsiveDisplayAdInfo, + LocalAdInfo, + ResponsiveDisplayAdControlSpec, + ResponsiveDisplayAdInfo, + ResponsiveSearchAdInfo, + ShoppingComparisonListingAdInfo, + ShoppingProductAdInfo, + ShoppingSmartAdInfo, + SmartCampaignAdInfo, + TextAdInfo, + TravelAdInfo, + VideoAdInfo, + VideoBumperInStreamAdInfo, + VideoNonSkippableInStreamAdInfo, + VideoOutstreamAdInfo, + VideoResponsiveAdInfo, + VideoTrueViewInStreamAdInfo, + YouTubeAudioAdInfo, +) +from .additional_application_info import ( + AdditionalApplicationInfo, +) +from .asset_policy import ( + AdAssetPolicySummary, + AssetDisapproved, + AssetLinkPrimaryStatusDetails, +) +from .asset_set_types import ( + BusinessProfileBusinessNameFilter, + BusinessProfileLocationGroup, + BusinessProfileLocationSet, + ChainFilter, + ChainLocationGroup, + ChainSet, + DynamicBusinessProfileLocationGroupFilter, + LocationSet, + MapsLocationInfo, + MapsLocationSet, +) +from .asset_types import ( + AppDeepLinkAsset, + BookOnGoogleAsset, + BusinessMessageAsset, + BusinessMessageCallToActionInfo, + BusinessProfileLocation, + CallAsset, + CalloutAsset, + CallToActionAsset, + DemandGenCarouselCardAsset, + DynamicCustomAsset, + DynamicEducationAsset, + DynamicFlightsAsset, + DynamicHotelsAndRentalsAsset, + DynamicJobsAsset, + DynamicLocalAsset, + DynamicRealEstateAsset, + DynamicTravelAsset, + FacebookMessengerBusinessMessageInfo, + HotelCalloutAsset, + HotelPropertyAsset, + ImageAsset, + ImageDimension, + LeadFormAsset, + LeadFormCustomQuestionField, + LeadFormDeliveryMethod, + LeadFormField, + LeadFormSingleChoiceAnswers, + LocationAsset, + MediaBundleAsset, + MobileAppAsset, + PageFeedAsset, + PriceAsset, + PriceOffering, + PromotionAsset, + PromotionBarcodeInfo, + PromotionQrCodeInfo, + SitelinkAsset, + StructuredSnippetAsset, + TextAsset, + WebhookDelivery, + WhatsappBusinessMessageInfo, + YoutubeVideoAsset, + YouTubeVideoListAsset, + ZaloBusinessMessageInfo, +) +from .asset_usage import ( + AssetUsage, +) +from .audience_insights_attribute import ( + AudienceInsightsAttribute, + AudienceInsightsAttributeMetadata, + AudienceInsightsAttributeMetadataGroup, + AudienceInsightsCategory, + AudienceInsightsEntity, + AudienceInsightsLineup, + KnowledgeGraphAttributeMetadata, + LineupAttributeMetadata, + LocationAttributeMetadata, + UserInterestAttributeMetadata, + UserListAttributeMetadata, + YouTubeChannelAttributeMetadata, + YouTubeVideoAttributeMetadata, +) +from .audiences import ( + AgeDimension, + AgeSegment, + AudienceDimension, + AudienceExclusionDimension, + AudienceSegment, + AudienceSegmentDimension, + CustomAudienceSegment, + DetailedDemographicSegment, + ExclusionSegment, + GenderDimension, + HouseholdIncomeDimension, + LifeEventSegment, + ParentalStatusDimension, + UserInterestSegment, + UserListSegment, +) +from .bidding import ( + Commission, + EnhancedCpc, + FixedCpm, + FixedCpmTargetFrequencyGoalInfo, + ManualCpa, + ManualCpc, + ManualCpm, + ManualCpv, + MaximizeConversions, + MaximizeConversionValue, + PercentCpc, + TargetCpa, + TargetCpc, + TargetCpm, + TargetCpmTargetFrequencyGoal, + TargetCpv, + TargetImpressionShare, + TargetRoas, + TargetSpend, +) +from .campaign_goal_settings import ( + CampaignGoalSettings, +) +from .click_location import ( + ClickLocation, +) +from .consent import ( + Consent, +) +from .criteria import ( + ActivityCityInfo, + ActivityCountryInfo, + ActivityIdInfo, + ActivityRatingInfo, + ActivityStateInfo, + AddressInfo, + AdScheduleInfo, + AgeRangeInfo, + AppPaymentModelInfo, + AudienceInfo, + BrandInfo, + BrandListInfo, + CarrierInfo, + CombinedAudienceInfo, + ContentLabelInfo, + CustomAffinityInfo, + CustomAudienceInfo, + CustomIntentInfo, + DeviceInfo, + ExtendedDemographicInfo, + GenderInfo, + GeoPointInfo, + HotelAdvanceBookingWindowInfo, + HotelCheckInDateRangeInfo, + HotelCheckInDayInfo, + HotelCityInfo, + HotelClassInfo, + HotelCountryRegionInfo, + HotelDateSelectionTypeInfo, + HotelIdInfo, + HotelLengthOfStayInfo, + HotelStateInfo, + IncomeRangeInfo, + InteractionTypeInfo, + IpBlockInfo, + KeywordInfo, + KeywordThemeInfo, + LanguageInfo, + LifeEventInfo, + ListingDimensionInfo, + ListingDimensionPath, + ListingGroupInfo, + ListingScopeInfo, + LocalServiceIdInfo, + LocationGroupInfo, + LocationInfo, + MobileAppCategoryInfo, + MobileApplicationInfo, + MobileDeviceInfo, + NegativeKeywordListInfo, + OperatingSystemVersionInfo, + ParentalStatusInfo, + PlacementInfo, + PlacementListInfo, + ProductBrandInfo, + ProductCategoryInfo, + ProductChannelExclusivityInfo, + ProductChannelInfo, + ProductConditionInfo, + ProductCustomAttributeInfo, + ProductGroupingInfo, + ProductItemIdInfo, + ProductLabelsInfo, + ProductLegacyConditionInfo, + ProductTypeFullInfo, + ProductTypeInfo, + ProximityInfo, + SearchThemeInfo, + TopicInfo, + UnknownListingDimensionInfo, + UserInterestInfo, + UserListInfo, + VerticalAdsItemGroupRuleInfo, + VerticalAdsItemGroupRuleListInfo, + VideoLineupInfo, + WebpageConditionInfo, + WebpageInfo, + WebpageListInfo, + WebpageSampleInfo, + YouTubeChannelInfo, + YouTubeVideoInfo, +) +from .criterion_category_availability import ( + CriterionCategoryAvailability, + CriterionCategoryChannelAvailability, + CriterionCategoryLocaleAvailability, +) +from .custom_parameter import ( + CustomParameter, +) +from .customizer_value import ( + CustomizerValue, +) +from .dates import ( + DateRange, + YearMonth, + YearMonthRange, +) +from .extensions import ( + CallFeedItem, + CalloutFeedItem, + SitelinkFeedItem, +) +from .feed_common import ( + Money, +) +from .final_app_url import ( + FinalAppUrl, +) +from .frequency_cap import ( + FrequencyCapEntry, + FrequencyCapKey, +) +from .goal_common import ( + CustomerLifecycleOptimizationValueSettings, +) +from .goal_setting import ( + GoalSetting, +) +from .keyword_plan_common import ( + ConceptGroup, + HistoricalMetricsOptions, + KeywordAnnotations, + KeywordConcept, + KeywordPlanAggregateMetricResults, + KeywordPlanAggregateMetrics, + KeywordPlanDeviceSearches, + KeywordPlanHistoricalMetrics, + MonthlySearchVolume, +) +from .lifecycle_goals import ( + LifecycleGoalValueSettings, +) +from .local_services import ( + LocalServicesDocumentReadOnly, +) +from .metric_goal import ( + MetricGoal, +) +from .metrics import ( + Metrics, + SearchVolumeRange, +) +from .offline_user_data import ( + CustomerMatchUserListMetadata, + EventAttribute, + EventItemAttribute, + ItemAttribute, + OfflineUserAddressInfo, + ShoppingLoyalty, + StoreAttribute, + StoreSalesMetadata, + StoreSalesThirdPartyMetadata, + TransactionAttribute, + UserAttribute, + UserData, + UserIdentifier, +) +from .policy import ( + PolicyTopicConstraint, + PolicyTopicEntry, + PolicyTopicEvidence, + PolicyValidationParameter, + PolicyViolationKey, +) +from .policy_summary import ( + PolicySummary, +) +from .real_time_bidding_setting import ( + RealTimeBiddingSetting, +) +from .segments import ( + AssetInteractionTarget, + BudgetCampaignAssociationStatus, + Keyword, + Segments, + SkAdNetworkSourceApp, +) +from .simulation import ( + BudgetSimulationPoint, + BudgetSimulationPointList, + CpcBidSimulationPoint, + CpcBidSimulationPointList, + CpvBidSimulationPoint, + CpvBidSimulationPointList, + PercentCpcBidSimulationPoint, + PercentCpcBidSimulationPointList, + TargetCpaSimulationPoint, + TargetCpaSimulationPointList, + TargetImpressionShareSimulationPoint, + TargetImpressionShareSimulationPointList, + TargetRoasSimulationPoint, + TargetRoasSimulationPointList, +) +from .tag_snippet import ( + TagSnippet, +) +from .targeting_setting import ( + TargetingSetting, + TargetRestriction, + TargetRestrictionOperation, +) +from .text_label import ( + TextLabel, +) +from .third_party_integration_partners import ( + CampaignThirdPartyBrandLiftIntegrationPartner, + CampaignThirdPartyBrandSafetyIntegrationPartner, + CampaignThirdPartyIntegrationPartners, + CampaignThirdPartyReachIntegrationPartner, + CampaignThirdPartyViewabilityIntegrationPartner, + CustomerThirdPartyBrandLiftIntegrationPartner, + CustomerThirdPartyBrandSafetyIntegrationPartner, + CustomerThirdPartyIntegrationPartners, + CustomerThirdPartyReachIntegrationPartner, + CustomerThirdPartyViewabilityIntegrationPartner, + ThirdPartyIntegrationPartnerData, +) +from .url_collection import ( + UrlCollection, +) +from .user_lists import ( + BasicUserListInfo, + CrmBasedUserListInfo, + FlexibleRuleOperandInfo, + FlexibleRuleUserListInfo, + LogicalUserListInfo, + LogicalUserListOperandInfo, + LookalikeUserListInfo, + RuleBasedUserListInfo, + SimilarUserListInfo, + UserListActionInfo, + UserListDateRuleItemInfo, + UserListLogicalRuleInfo, + UserListNumberRuleItemInfo, + UserListRuleInfo, + UserListRuleItemGroupInfo, + UserListRuleItemInfo, + UserListStringRuleItemInfo, +) +from .value import ( + Value, +) + +__all__ = ( + "AdAppDeepLinkAsset", + "AdCallToActionAsset", + "AdDemandGenCarouselCardAsset", + "AdImageAsset", + "AdMediaBundleAsset", + "AdTextAsset", + "AdVideoAsset", + "AdVideoAssetInfo", + "AdVideoAssetInventoryPreferences", + "AdVideoAssetLinkFeatureControl", + "AppAdInfo", + "AppEngagementAdInfo", + "AppPreRegistrationAdInfo", + "DemandGenCarouselAdInfo", + "DemandGenMultiAssetAdInfo", + "DemandGenProductAdInfo", + "DemandGenVideoResponsiveAdInfo", + "DisplayUploadAdInfo", + "ExpandedDynamicSearchAdInfo", + "ExpandedTextAdInfo", + "HotelAdInfo", + "ImageAdInfo", + "InFeedVideoAdInfo", + "LegacyAppInstallAdInfo", + "LegacyResponsiveDisplayAdInfo", + "LocalAdInfo", + "ResponsiveDisplayAdControlSpec", + "ResponsiveDisplayAdInfo", + "ResponsiveSearchAdInfo", + "ShoppingComparisonListingAdInfo", + "ShoppingProductAdInfo", + "ShoppingSmartAdInfo", + "SmartCampaignAdInfo", + "TextAdInfo", + "TravelAdInfo", + "VideoAdInfo", + "VideoBumperInStreamAdInfo", + "VideoNonSkippableInStreamAdInfo", + "VideoOutstreamAdInfo", + "VideoResponsiveAdInfo", + "VideoTrueViewInStreamAdInfo", + "YouTubeAudioAdInfo", + "AdditionalApplicationInfo", + "AdAssetPolicySummary", + "AssetDisapproved", + "AssetLinkPrimaryStatusDetails", + "BusinessProfileBusinessNameFilter", + "BusinessProfileLocationGroup", + "BusinessProfileLocationSet", + "ChainFilter", + "ChainLocationGroup", + "ChainSet", + "DynamicBusinessProfileLocationGroupFilter", + "LocationSet", + "MapsLocationInfo", + "MapsLocationSet", + "AppDeepLinkAsset", + "BookOnGoogleAsset", + "BusinessMessageAsset", + "BusinessMessageCallToActionInfo", + "BusinessProfileLocation", + "CallAsset", + "CalloutAsset", + "CallToActionAsset", + "DemandGenCarouselCardAsset", + "DynamicCustomAsset", + "DynamicEducationAsset", + "DynamicFlightsAsset", + "DynamicHotelsAndRentalsAsset", + "DynamicJobsAsset", + "DynamicLocalAsset", + "DynamicRealEstateAsset", + "DynamicTravelAsset", + "FacebookMessengerBusinessMessageInfo", + "HotelCalloutAsset", + "HotelPropertyAsset", + "ImageAsset", + "ImageDimension", + "LeadFormAsset", + "LeadFormCustomQuestionField", + "LeadFormDeliveryMethod", + "LeadFormField", + "LeadFormSingleChoiceAnswers", + "LocationAsset", + "MediaBundleAsset", + "MobileAppAsset", + "PageFeedAsset", + "PriceAsset", + "PriceOffering", + "PromotionAsset", + "PromotionBarcodeInfo", + "PromotionQrCodeInfo", + "SitelinkAsset", + "StructuredSnippetAsset", + "TextAsset", + "WebhookDelivery", + "WhatsappBusinessMessageInfo", + "YoutubeVideoAsset", + "YouTubeVideoListAsset", + "ZaloBusinessMessageInfo", + "AssetUsage", + "AudienceInsightsAttribute", + "AudienceInsightsAttributeMetadata", + "AudienceInsightsAttributeMetadataGroup", + "AudienceInsightsCategory", + "AudienceInsightsEntity", + "AudienceInsightsLineup", + "KnowledgeGraphAttributeMetadata", + "LineupAttributeMetadata", + "LocationAttributeMetadata", + "UserInterestAttributeMetadata", + "UserListAttributeMetadata", + "YouTubeChannelAttributeMetadata", + "YouTubeVideoAttributeMetadata", + "AgeDimension", + "AgeSegment", + "AudienceDimension", + "AudienceExclusionDimension", + "AudienceSegment", + "AudienceSegmentDimension", + "CustomAudienceSegment", + "DetailedDemographicSegment", + "ExclusionSegment", + "GenderDimension", + "HouseholdIncomeDimension", + "LifeEventSegment", + "ParentalStatusDimension", + "UserInterestSegment", + "UserListSegment", + "Commission", + "EnhancedCpc", + "FixedCpm", + "FixedCpmTargetFrequencyGoalInfo", + "ManualCpa", + "ManualCpc", + "ManualCpm", + "ManualCpv", + "MaximizeConversions", + "MaximizeConversionValue", + "PercentCpc", + "TargetCpa", + "TargetCpc", + "TargetCpm", + "TargetCpmTargetFrequencyGoal", + "TargetCpv", + "TargetImpressionShare", + "TargetRoas", + "TargetSpend", + "CampaignGoalSettings", + "ClickLocation", + "Consent", + "ActivityCityInfo", + "ActivityCountryInfo", + "ActivityIdInfo", + "ActivityRatingInfo", + "ActivityStateInfo", + "AddressInfo", + "AdScheduleInfo", + "AgeRangeInfo", + "AppPaymentModelInfo", + "AudienceInfo", + "BrandInfo", + "BrandListInfo", + "CarrierInfo", + "CombinedAudienceInfo", + "ContentLabelInfo", + "CustomAffinityInfo", + "CustomAudienceInfo", + "CustomIntentInfo", + "DeviceInfo", + "ExtendedDemographicInfo", + "GenderInfo", + "GeoPointInfo", + "HotelAdvanceBookingWindowInfo", + "HotelCheckInDateRangeInfo", + "HotelCheckInDayInfo", + "HotelCityInfo", + "HotelClassInfo", + "HotelCountryRegionInfo", + "HotelDateSelectionTypeInfo", + "HotelIdInfo", + "HotelLengthOfStayInfo", + "HotelStateInfo", + "IncomeRangeInfo", + "InteractionTypeInfo", + "IpBlockInfo", + "KeywordInfo", + "KeywordThemeInfo", + "LanguageInfo", + "LifeEventInfo", + "ListingDimensionInfo", + "ListingDimensionPath", + "ListingGroupInfo", + "ListingScopeInfo", + "LocalServiceIdInfo", + "LocationGroupInfo", + "LocationInfo", + "MobileAppCategoryInfo", + "MobileApplicationInfo", + "MobileDeviceInfo", + "NegativeKeywordListInfo", + "OperatingSystemVersionInfo", + "ParentalStatusInfo", + "PlacementInfo", + "PlacementListInfo", + "ProductBrandInfo", + "ProductCategoryInfo", + "ProductChannelExclusivityInfo", + "ProductChannelInfo", + "ProductConditionInfo", + "ProductCustomAttributeInfo", + "ProductGroupingInfo", + "ProductItemIdInfo", + "ProductLabelsInfo", + "ProductLegacyConditionInfo", + "ProductTypeFullInfo", + "ProductTypeInfo", + "ProximityInfo", + "SearchThemeInfo", + "TopicInfo", + "UnknownListingDimensionInfo", + "UserInterestInfo", + "UserListInfo", + "VerticalAdsItemGroupRuleInfo", + "VerticalAdsItemGroupRuleListInfo", + "VideoLineupInfo", + "WebpageConditionInfo", + "WebpageInfo", + "WebpageListInfo", + "WebpageSampleInfo", + "YouTubeChannelInfo", + "YouTubeVideoInfo", + "CriterionCategoryAvailability", + "CriterionCategoryChannelAvailability", + "CriterionCategoryLocaleAvailability", + "CustomParameter", + "CustomizerValue", + "DateRange", + "YearMonth", + "YearMonthRange", + "CallFeedItem", + "CalloutFeedItem", + "SitelinkFeedItem", + "Money", + "FinalAppUrl", + "FrequencyCapEntry", + "FrequencyCapKey", + "CustomerLifecycleOptimizationValueSettings", + "GoalSetting", + "ConceptGroup", + "HistoricalMetricsOptions", + "KeywordAnnotations", + "KeywordConcept", + "KeywordPlanAggregateMetricResults", + "KeywordPlanAggregateMetrics", + "KeywordPlanDeviceSearches", + "KeywordPlanHistoricalMetrics", + "MonthlySearchVolume", + "LifecycleGoalValueSettings", + "LocalServicesDocumentReadOnly", + "MetricGoal", + "Metrics", + "SearchVolumeRange", + "CustomerMatchUserListMetadata", + "EventAttribute", + "EventItemAttribute", + "ItemAttribute", + "OfflineUserAddressInfo", + "ShoppingLoyalty", + "StoreAttribute", + "StoreSalesMetadata", + "StoreSalesThirdPartyMetadata", + "TransactionAttribute", + "UserAttribute", + "UserData", + "UserIdentifier", + "PolicyTopicConstraint", + "PolicyTopicEntry", + "PolicyTopicEvidence", + "PolicyValidationParameter", + "PolicyViolationKey", + "PolicySummary", + "RealTimeBiddingSetting", + "AssetInteractionTarget", + "BudgetCampaignAssociationStatus", + "Keyword", + "Segments", + "SkAdNetworkSourceApp", + "BudgetSimulationPoint", + "BudgetSimulationPointList", + "CpcBidSimulationPoint", + "CpcBidSimulationPointList", + "CpvBidSimulationPoint", + "CpvBidSimulationPointList", + "PercentCpcBidSimulationPoint", + "PercentCpcBidSimulationPointList", + "TargetCpaSimulationPoint", + "TargetCpaSimulationPointList", + "TargetImpressionShareSimulationPoint", + "TargetImpressionShareSimulationPointList", + "TargetRoasSimulationPoint", + "TargetRoasSimulationPointList", + "TagSnippet", + "TargetingSetting", + "TargetRestriction", + "TargetRestrictionOperation", + "TextLabel", + "CampaignThirdPartyBrandLiftIntegrationPartner", + "CampaignThirdPartyBrandSafetyIntegrationPartner", + "CampaignThirdPartyIntegrationPartners", + "CampaignThirdPartyReachIntegrationPartner", + "CampaignThirdPartyViewabilityIntegrationPartner", + "CustomerThirdPartyBrandLiftIntegrationPartner", + "CustomerThirdPartyBrandSafetyIntegrationPartner", + "CustomerThirdPartyIntegrationPartners", + "CustomerThirdPartyReachIntegrationPartner", + "CustomerThirdPartyViewabilityIntegrationPartner", + "ThirdPartyIntegrationPartnerData", + "UrlCollection", + "BasicUserListInfo", + "CrmBasedUserListInfo", + "FlexibleRuleOperandInfo", + "FlexibleRuleUserListInfo", + "LogicalUserListInfo", + "LogicalUserListOperandInfo", + "LookalikeUserListInfo", + "RuleBasedUserListInfo", + "SimilarUserListInfo", + "UserListActionInfo", + "UserListDateRuleItemInfo", + "UserListLogicalRuleInfo", + "UserListNumberRuleItemInfo", + "UserListRuleInfo", + "UserListRuleItemGroupInfo", + "UserListRuleItemInfo", + "UserListStringRuleItemInfo", + "Value", +) diff --git a/google/ads/googleads/v19/common/types/ad_asset.py b/google/ads/googleads/v23/common/types/ad_asset.py similarity index 82% rename from google/ads/googleads/v19/common/types/ad_asset.py rename to google/ads/googleads/v23/common/types/ad_asset.py index ada6b8c35..ac4d8fcda 100644 --- a/google/ads/googleads/v19/common/types/ad_asset.py +++ b/google/ads/googleads/v23/common/types/ad_asset.py @@ -18,22 +18,23 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import asset_policy -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import asset_policy +from google.ads.googleads.v23.enums.types import ( asset_performance_label as gage_asset_performance_label, ) -from google.ads.googleads.v19.enums.types import served_asset_field_type +from google.ads.googleads.v23.enums.types import served_asset_field_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "AdTextAsset", "AdImageAsset", "AdVideoAsset", "AdVideoAssetInfo", "AdVideoAssetInventoryPreferences", + "AdVideoAssetLinkFeatureControl", "AdMediaBundleAsset", "AdDemandGenCarouselCardAsset", "AdCallToActionAsset", @@ -52,16 +53,16 @@ class AdTextAsset(proto.Message): Asset text. This field is a member of `oneof`_ ``_text``. - pinned_field (google.ads.googleads.v19.enums.types.ServedAssetFieldTypeEnum.ServedAssetFieldType): + pinned_field (google.ads.googleads.v23.enums.types.ServedAssetFieldTypeEnum.ServedAssetFieldType): The pinned field of the asset. This restricts the asset to only serve within this field. Multiple assets can be pinned to the same field. An asset that is unpinned or pinned to a different field will not serve in a field where some other asset has been pinned. - asset_performance_label (google.ads.googleads.v19.enums.types.AssetPerformanceLabelEnum.AssetPerformanceLabel): + asset_performance_label (google.ads.googleads.v23.enums.types.AssetPerformanceLabelEnum.AssetPerformanceLabel): The performance label of this text asset. - policy_summary_info (google.ads.googleads.v19.common.types.AdAssetPolicySummary): + policy_summary_info (google.ads.googleads.v23.common.types.AdAssetPolicySummary): The policy summary of this text asset. """ @@ -120,7 +121,7 @@ class AdVideoAsset(proto.Message): The Asset resource name of this video. This field is a member of `oneof`_ ``_asset``. - ad_video_asset_info (google.ads.googleads.v19.common.types.AdVideoAssetInfo): + ad_video_asset_info (google.ads.googleads.v23.common.types.AdVideoAssetInfo): Contains info fields for this AdVideoAsset. This field is a member of `oneof`_ ``_ad_video_asset_info``. @@ -145,7 +146,7 @@ class AdVideoAssetInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - ad_video_asset_inventory_preferences (google.ads.googleads.v19.common.types.AdVideoAssetInventoryPreferences): + ad_video_asset_inventory_preferences (google.ads.googleads.v23.common.types.AdVideoAssetInventoryPreferences): List of inventory preferences for this AdVideoAsset. This field can only be set for DiscoveryVideoResponsiveAd. The video assets @@ -160,6 +161,13 @@ class AdVideoAssetInfo(proto.Message): for a given ad slot can be found. This field is a member of `oneof`_ ``_ad_video_asset_inventory_preferences``. + ad_video_asset_feature_control (google.ads.googleads.v23.common.types.AdVideoAssetLinkFeatureControl): + Defines feature controls for this + AdVideoAsset during serving time. For example, + whether YouTube comments should be enabled for + Partnership Ads served on YouTube Shorts. + + This field is a member of `oneof`_ ``_ad_video_asset_feature_control``. """ ad_video_asset_inventory_preferences: "AdVideoAssetInventoryPreferences" = ( @@ -170,6 +178,14 @@ class AdVideoAssetInfo(proto.Message): message="AdVideoAssetInventoryPreferences", ) ) + ad_video_asset_feature_control: "AdVideoAssetLinkFeatureControl" = ( + proto.Field( + proto.MESSAGE, + number=2, + optional=True, + message="AdVideoAssetLinkFeatureControl", + ) + ) class AdVideoAssetInventoryPreferences(proto.Message): @@ -215,6 +231,27 @@ class AdVideoAssetInventoryPreferences(proto.Message): ) +class AdVideoAssetLinkFeatureControl(proto.Message): + r"""YouTube Video Asset feature controls. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + allow_youtube_comments (bool): + Defines if YouTube comments should be enabled + for the creative using this YouTube video asset + served on YouTube Shorts. + + This field is a member of `oneof`_ ``_allow_youtube_comments``. + """ + + allow_youtube_comments: bool = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + + class AdMediaBundleAsset(proto.Message): r"""A media bundle asset used inside an ad. diff --git a/google/ads/googleads/v19/common/types/ad_type_infos.py b/google/ads/googleads/v23/common/types/ad_type_infos.py similarity index 86% rename from google/ads/googleads/v19/common/types/ad_type_infos.py rename to google/ads/googleads/v23/common/types/ad_type_infos.py index cc61dfb52..611c6df9a 100644 --- a/google/ads/googleads/v19/common/types/ad_type_infos.py +++ b/google/ads/googleads/v23/common/types/ad_type_infos.py @@ -19,20 +19,19 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import ad_asset -from google.ads.googleads.v19.enums.types import call_conversion_reporting_state -from google.ads.googleads.v19.enums.types import display_ad_format_setting -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import ad_asset +from google.ads.googleads.v23.enums.types import display_ad_format_setting +from google.ads.googleads.v23.enums.types import ( display_upload_product_type as gage_display_upload_product_type, ) -from google.ads.googleads.v19.enums.types import legacy_app_install_ad_app_store -from google.ads.googleads.v19.enums.types import mime_type as gage_mime_type -from google.ads.googleads.v19.enums.types import video_thumbnail +from google.ads.googleads.v23.enums.types import legacy_app_install_ad_app_store +from google.ads.googleads.v23.enums.types import mime_type as gage_mime_type +from google.ads.googleads.v23.enums.types import video_thumbnail __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "TextAdInfo", "ExpandedTextAdInfo", @@ -62,7 +61,6 @@ "DisplayUploadAdInfo", "ResponsiveDisplayAdControlSpec", "SmartCampaignAdInfo", - "CallAdInfo", "DemandGenMultiAssetAdInfo", "DemandGenCarouselAdInfo", "DemandGenVideoResponsiveAdInfo", @@ -282,7 +280,7 @@ class ImageAdInfo(proto.Message): URL of the preview size image. This field is a member of `oneof`_ ``_preview_image_url``. - mime_type (google.ads.googleads.v19.enums.types.MimeTypeEnum.MimeType): + mime_type (google.ads.googleads.v23.enums.types.MimeTypeEnum.MimeType): The mime type of the image. name (str): The name of the image. If the image was @@ -291,7 +289,7 @@ class ImageAdInfo(proto.Message): bytes, this is empty. This field is a member of `oneof`_ ``_name``. - image_asset (google.ads.googleads.v19.common.types.AdImageAsset): + image_asset (google.ads.googleads.v23.common.types.AdImageAsset): The image assets used for the ad. This field is a member of `oneof`_ ``image``. @@ -368,7 +366,7 @@ class VideoBumperInStreamAdInfo(proto.Message): short in-stream non-skippable video ad). Attributes: - companion_banner (google.ads.googleads.v19.common.types.AdImageAsset): + companion_banner (google.ads.googleads.v23.common.types.AdImageAsset): The image assets of the companion banner used with the ad. action_button_label (str): @@ -400,7 +398,7 @@ class VideoNonSkippableInStreamAdInfo(proto.Message): second in-stream non-skippable video ad). Attributes: - companion_banner (google.ads.googleads.v19.common.types.AdImageAsset): + companion_banner (google.ads.googleads.v23.common.types.AdImageAsset): The image assets of the companion banner used with the ad. action_button_label (str): @@ -442,7 +440,7 @@ class VideoTrueViewInStreamAdInfo(proto.Message): Additional text displayed with the CTA (call-to-action) button to give context and encourage clicking on the button. - companion_banner (google.ads.googleads.v19.common.types.AdImageAsset): + companion_banner (google.ads.googleads.v23.common.types.AdImageAsset): The image assets of the companion banner used with the ad. """ @@ -493,7 +491,7 @@ class InFeedVideoAdInfo(proto.Message): First text line for the ad. description2 (str): Second text line for the ad. - thumbnail (google.ads.googleads.v19.enums.types.VideoThumbnailEnum.VideoThumbnail): + thumbnail (google.ads.googleads.v23.enums.types.VideoThumbnailEnum.VideoThumbnail): Video thumbnail image to use. """ @@ -531,29 +529,29 @@ class VideoAdInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - video (google.ads.googleads.v19.common.types.AdVideoAsset): + video (google.ads.googleads.v23.common.types.AdVideoAsset): The YouTube video assets used for the ad. - in_stream (google.ads.googleads.v19.common.types.VideoTrueViewInStreamAdInfo): + in_stream (google.ads.googleads.v23.common.types.VideoTrueViewInStreamAdInfo): Video TrueView in-stream ad format. This field is a member of `oneof`_ ``format``. - bumper (google.ads.googleads.v19.common.types.VideoBumperInStreamAdInfo): + bumper (google.ads.googleads.v23.common.types.VideoBumperInStreamAdInfo): Video bumper in-stream ad format. This field is a member of `oneof`_ ``format``. - out_stream (google.ads.googleads.v19.common.types.VideoOutstreamAdInfo): + out_stream (google.ads.googleads.v23.common.types.VideoOutstreamAdInfo): Video out-stream ad format. This field is a member of `oneof`_ ``format``. - non_skippable (google.ads.googleads.v19.common.types.VideoNonSkippableInStreamAdInfo): + non_skippable (google.ads.googleads.v23.common.types.VideoNonSkippableInStreamAdInfo): Video non-skippable in-stream ad format. This field is a member of `oneof`_ ``format``. - in_feed (google.ads.googleads.v19.common.types.InFeedVideoAdInfo): + in_feed (google.ads.googleads.v23.common.types.InFeedVideoAdInfo): In-feed video ad format. This field is a member of `oneof`_ ``format``. - audio (google.ads.googleads.v19.common.types.YouTubeAudioAdInfo): + audio (google.ads.googleads.v23.common.types.YouTubeAudioAdInfo): YouTube Audio ad format. This field is a member of `oneof`_ ``format``. @@ -606,27 +604,34 @@ class VideoResponsiveAdInfo(proto.Message): r"""A video responsive ad. Attributes: - headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets used for the short headline. Currently, only a single value for the short headline is supported. - long_headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + long_headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets used for the long headline. Currently, only a single value for the long headline is supported. - descriptions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + descriptions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets used for the description. Currently, only a single value for the description is supported. - call_to_actions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + call_to_actions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets used for the button, for example, the "Call To Action" button. Currently, only a single value for the button is supported. - videos (MutableSequence[google.ads.googleads.v19.common.types.AdVideoAsset]): + videos (MutableSequence[google.ads.googleads.v23.common.types.AdVideoAsset]): List of YouTube video assets used for the ad. Currently, only a single value for the YouTube video asset is supported. - companion_banners (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + business_name (google.ads.googleads.v23.common.types.AdTextAsset): + Optional advertiser/brand name. Maximum + display width is 25 characters. + logo_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): + Optional logo image to be used in the ad. The + minimum size is 128x128 and the aspect ratio + must be 1:1(+-1%). + companion_banners (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): List of image assets used for the companion banner. Currently, only a single value for the companion banner asset is supported. @@ -665,6 +670,16 @@ class VideoResponsiveAdInfo(proto.Message): number=5, message=ad_asset.AdVideoAsset, ) + business_name: ad_asset.AdTextAsset = proto.Field( + proto.MESSAGE, + number=9, + message=ad_asset.AdTextAsset, + ) + logo_images: MutableSequence[ad_asset.AdImageAsset] = proto.RepeatedField( + proto.MESSAGE, + number=10, + message=ad_asset.AdImageAsset, + ) companion_banners: MutableSequence[ad_asset.AdImageAsset] = ( proto.RepeatedField( proto.MESSAGE, @@ -701,11 +716,11 @@ class ResponsiveSearchAdInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets for headlines. When the ad serves the headlines will be selected from this list. - descriptions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + descriptions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets for descriptions. When the ad serves the descriptions will be selected from this list. @@ -811,7 +826,7 @@ class LegacyResponsiveDisplayAdInfo(proto.Message): marketing image used in the ad. This field is a member of `oneof`_ ``_square_marketing_image``. - format_setting (google.ads.googleads.v19.enums.types.DisplayAdFormatSettingEnum.DisplayAdFormatSetting): + format_setting (google.ads.googleads.v23.enums.types.DisplayAdFormatSettingEnum.DisplayAdFormatSetting): Specifies which format the ad will be served in. Default is ALL_FORMATS. price_prefix (str): @@ -910,26 +925,26 @@ class AppAdInfo(proto.Message): r"""An app ad. Attributes: - mandatory_ad_text (google.ads.googleads.v19.common.types.AdTextAsset): + mandatory_ad_text (google.ads.googleads.v23.common.types.AdTextAsset): Mandatory ad text. - headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets for headlines. When the ad serves the headlines will be selected from this list. - descriptions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + descriptions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets for descriptions. When the ad serves the descriptions will be selected from this list. - images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): List of image assets that may be displayed with the ad. - youtube_videos (MutableSequence[google.ads.googleads.v19.common.types.AdVideoAsset]): + youtube_videos (MutableSequence[google.ads.googleads.v23.common.types.AdVideoAsset]): List of YouTube video assets that may be displayed with the ad. - html5_media_bundles (MutableSequence[google.ads.googleads.v19.common.types.AdMediaBundleAsset]): + html5_media_bundles (MutableSequence[google.ads.googleads.v23.common.types.AdMediaBundleAsset]): List of media bundle assets that may be used with the ad. - app_deep_link (google.ads.googleads.v19.common.types.AdAppDeepLinkAsset): + app_deep_link (google.ads.googleads.v23.common.types.AdAppDeepLinkAsset): An app deep link asset that may be used with the ad. """ @@ -983,18 +998,18 @@ class AppEngagementAdInfo(proto.Message): easier and faster. Attributes: - headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets for headlines. When the ad serves the headlines will be selected from this list. - descriptions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + descriptions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets for descriptions. When the ad serves the descriptions will be selected from this list. - images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): List of image assets that may be displayed with the ad. - videos (MutableSequence[google.ads.googleads.v19.common.types.AdVideoAsset]): + videos (MutableSequence[google.ads.googleads.v23.common.types.AdVideoAsset]): List of video assets that may be displayed with the ad. """ @@ -1030,18 +1045,18 @@ class AppPreRegistrationAdInfo(proto.Message): before a launch. Attributes: - headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets for headlines. When the ad serves the headlines will be selected from this list. - descriptions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + descriptions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets for descriptions. When the ad serves the descriptions will be selected from this list. - images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): List of image asset IDs whose images may be displayed with the ad. - youtube_videos (MutableSequence[google.ads.googleads.v19.common.types.AdVideoAsset]): + youtube_videos (MutableSequence[google.ads.googleads.v23.common.types.AdVideoAsset]): List of YouTube video asset IDs whose videos may be displayed with the ad. """ @@ -1082,7 +1097,7 @@ class LegacyAppInstallAdInfo(proto.Message): The ID of the mobile app. This field is a member of `oneof`_ ``_app_id``. - app_store (google.ads.googleads.v19.enums.types.LegacyAppInstallAdAppStoreEnum.LegacyAppInstallAdAppStore): + app_store (google.ads.googleads.v23.enums.types.LegacyAppInstallAdAppStoreEnum.LegacyAppInstallAdAppStore): The app store the mobile app is available in. headline (str): The headline of the ad. @@ -1133,40 +1148,40 @@ class ResponsiveDisplayAdInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - marketing_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + marketing_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): Marketing images to be used in the ad. Valid image types are GIF, JPEG, and PNG. The minimum size is 600x314 and the aspect ratio must be 1.91:1 (+-1%). At least one ``marketing_image`` is required. Combined with ``square_marketing_images``, the maximum is 15. - square_marketing_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + square_marketing_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): Square marketing images to be used in the ad. Valid image types are GIF, JPEG, and PNG. The minimum size is 300x300 and the aspect ratio must be 1:1 (+-1%). At least one square ``marketing_image`` is required. Combined with ``marketing_images``, the maximum is 15. - logo_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + logo_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): Logo images to be used in the ad. Valid image types are GIF, JPEG, and PNG. The minimum size is 512x128 and the aspect ratio must be 4:1 (+-1%). Combined with ``square_logo_images``, the maximum is 5. - square_logo_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + square_logo_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): Square logo images to be used in the ad. Valid image types are GIF, JPEG, and PNG. The minimum size is 128x128 and the aspect ratio must be 1:1 (+-1%). Combined with ``logo_images``, the maximum is 5. - headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): Short format headlines for the ad. The maximum length is 30 characters. At least 1 and max 5 headlines can be specified. - long_headline (google.ads.googleads.v19.common.types.AdTextAsset): + long_headline (google.ads.googleads.v23.common.types.AdTextAsset): A required long format headline. The maximum length is 90 characters. - descriptions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + descriptions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): Descriptive texts for the ad. The maximum length is 90 characters. At least 1 and max 5 headlines can be specified. - youtube_videos (MutableSequence[google.ads.googleads.v19.common.types.AdVideoAsset]): + youtube_videos (MutableSequence[google.ads.googleads.v23.common.types.AdVideoAsset]): Optional YouTube videos for the ad. A maximum of 5 videos can be specified. business_name (str): @@ -1210,10 +1225,10 @@ class ResponsiveDisplayAdInfo(proto.Message): shipping'. This field is a member of `oneof`_ ``_promo_text``. - format_setting (google.ads.googleads.v19.enums.types.DisplayAdFormatSettingEnum.DisplayAdFormatSetting): + format_setting (google.ads.googleads.v23.enums.types.DisplayAdFormatSettingEnum.DisplayAdFormatSetting): Specifies which format the ad will be served in. Default is ALL_FORMATS. - control_spec (google.ads.googleads.v19.common.types.ResponsiveDisplayAdControlSpec): + control_spec (google.ads.googleads.v23.common.types.ResponsiveDisplayAdControlSpec): Specification for various creative controls. """ @@ -1320,33 +1335,33 @@ class LocalAdInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets for headlines. When the ad serves the headlines will be selected from this list. At least 1 and at most 5 headlines must be specified. - descriptions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + descriptions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets for descriptions. When the ad serves the descriptions will be selected from this list. At least 1 and at most 5 descriptions must be specified. - call_to_actions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + call_to_actions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets for call-to-actions. When the ad serves the call-to-actions will be selected from this list. At least 1 and at most 5 call-to-actions must be specified. - marketing_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + marketing_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): List of marketing image assets that may be displayed with the ad. The images must be 314x600 pixels or 320x320 pixels. At least 1 and at most 20 image assets must be specified. - logo_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + logo_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): List of logo image assets that may be displayed with the ad. The images must be 128x128 pixels and not larger than 120KB. At least 1 and at most 5 image assets must be specified. - videos (MutableSequence[google.ads.googleads.v19.common.types.AdVideoAsset]): + videos (MutableSequence[google.ads.googleads.v23.common.types.AdVideoAsset]): List of YouTube video assets that may be displayed with the ad. At least 1 and at most 20 video assets must be specified. @@ -1418,10 +1433,10 @@ class DisplayUploadAdInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - display_upload_product_type (google.ads.googleads.v19.enums.types.DisplayUploadProductTypeEnum.DisplayUploadProductType): + display_upload_product_type (google.ads.googleads.v23.enums.types.DisplayUploadProductTypeEnum.DisplayUploadProductType): The product type of this ad. See comments on the enum for details. - media_bundle (google.ads.googleads.v19.common.types.AdMediaBundleAsset): + media_bundle (google.ads.googleads.v23.common.types.AdMediaBundleAsset): A media bundle asset to be used in the ad. For information about the media bundle for HTML5_UPLOAD_AD, see https://support.google.com/google-ads/answer/1722096 Media @@ -1476,12 +1491,12 @@ class SmartCampaignAdInfo(proto.Message): r"""A Smart campaign ad. Attributes: - headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets, each of which corresponds to a headline when the ad serves. This list consists of a minimum of 3 and up to 15 text assets. - descriptions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + descriptions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets, each of which corresponds to a description when the ad serves. This list consists of a minimum of 2 and up to 4 @@ -1500,160 +1515,50 @@ class SmartCampaignAdInfo(proto.Message): ) -class CallAdInfo(proto.Message): - r"""A call ad. - - Attributes: - country_code (str): - The country code in the ad. - phone_number (str): - The phone number in the ad. - business_name (str): - The business name in the ad. - headline1 (str): - First headline in the ad. - headline2 (str): - Second headline in the ad. - description1 (str): - The first line of the ad's description. - description2 (str): - The second line of the ad's description. - call_tracked (bool): - Whether to enable call tracking for the - creative. Enabling call tracking also enables - call conversions. - disable_call_conversion (bool): - Whether to disable call conversion for the creative. If set - to ``true``, disables call conversions even when - ``call_tracked`` is ``true``. If ``call_tracked`` is - ``false``, this field is ignored. - phone_number_verification_url (str): - The URL to be used for phone number - verification. - conversion_action (str): - The conversion action to attribute a call conversion to. If - not set a default conversion action is used. This field only - has effect if ``call_tracked`` is set to ``true``. Otherwise - this field is ignored. - conversion_reporting_state (google.ads.googleads.v19.enums.types.CallConversionReportingStateEnum.CallConversionReportingState): - The call conversion behavior of this call ad. - It can use its own call conversion setting, - inherit the account level setting, or be - disabled. - path1 (str): - First part of text that can be appended to - the URL in the ad. Optional. - path2 (str): - Second part of text that can be appended to the URL in the - ad. This field can only be set when ``path1`` is also set. - Optional. - """ - - country_code: str = proto.Field( - proto.STRING, - number=1, - ) - phone_number: str = proto.Field( - proto.STRING, - number=2, - ) - business_name: str = proto.Field( - proto.STRING, - number=3, - ) - headline1: str = proto.Field( - proto.STRING, - number=11, - ) - headline2: str = proto.Field( - proto.STRING, - number=12, - ) - description1: str = proto.Field( - proto.STRING, - number=4, - ) - description2: str = proto.Field( - proto.STRING, - number=5, - ) - call_tracked: bool = proto.Field( - proto.BOOL, - number=6, - ) - disable_call_conversion: bool = proto.Field( - proto.BOOL, - number=7, - ) - phone_number_verification_url: str = proto.Field( - proto.STRING, - number=8, - ) - conversion_action: str = proto.Field( - proto.STRING, - number=9, - ) - conversion_reporting_state: ( - call_conversion_reporting_state.CallConversionReportingStateEnum.CallConversionReportingState - ) = proto.Field( - proto.ENUM, - number=10, - enum=call_conversion_reporting_state.CallConversionReportingStateEnum.CallConversionReportingState, - ) - path1: str = proto.Field( - proto.STRING, - number=13, - ) - path2: str = proto.Field( - proto.STRING, - number=14, - ) - - class DemandGenMultiAssetAdInfo(proto.Message): r"""A Demand Gen multi asset ad. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - marketing_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + marketing_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): Marketing image assets to be used in the ad. Valid image types are GIF, JPEG, and PNG. The minimum size is 600x314 and the aspect ratio must be 1.91:1 (+-1%). Required if square_marketing_images is not present. Combined with ``square_marketing_images``, ``portrait_marketing_images``, and ``tall_portrait_marketing_images`` the maximum is 20. - square_marketing_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + square_marketing_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): Square marketing image assets to be used in the ad. Valid image types are GIF, JPEG, and PNG. The minimum size is 300x300 and the aspect ratio must be 1:1 (+-1%). Required if marketing_images is not present. Combined with ``marketing_images``, ``portrait_marketing_images``, and ``tall_portrait_marketing_images`` the maximum is 20. - portrait_marketing_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + portrait_marketing_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): Portrait marketing image assets to be used in the ad. Valid image types are GIF, JPEG, and PNG. The minimum size is 480x600 and the aspect ratio must be 4:5 (+-1%). Combined with ``marketing_images``, ``square_marketing_images``, and ``tall_portrait_marketing_images`` the maximum is 20. - tall_portrait_marketing_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + tall_portrait_marketing_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): Tall portrait marketing image assets to be used in the ad. Valid image types are GIF, JPEG, and PNG. The minimum size is 600x1067 and the aspect ratio must be 9:16 (+-1%). Combined with ``marketing_images``, ``square_marketing_images``, and ``portrait_marketing_images``, the maximum is 20. - logo_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + logo_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): Logo image assets to be used in the ad. Valid image types are GIF, JPEG, and PNG. The minimum size is 128x128 and the aspect ratio must be 1:1 (+-1%). At least 1 and max 5 logo images can be specified. - headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): Headline text asset of the ad. Maximum display width is 30. At least 1 and max 5 headlines can be specified. - descriptions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + descriptions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): The descriptive text of the ad. Maximum display width is 90. At least 1 and max 5 descriptions can be specified. @@ -1666,11 +1571,6 @@ class DemandGenMultiAssetAdInfo(proto.Message): Call to action text. This field is a member of `oneof`_ ``_call_to_action_text``. - lead_form_only (bool): - Boolean option that indicates if this ad must - be served with lead form. - - This field is a member of `oneof`_ ``_lead_form_only``. """ marketing_images: MutableSequence[ad_asset.AdImageAsset] = ( @@ -1726,11 +1626,6 @@ class DemandGenMultiAssetAdInfo(proto.Message): number=8, optional=True, ) - lead_form_only: bool = proto.Field( - proto.BOOL, - number=9, - optional=True, - ) class DemandGenCarouselAdInfo(proto.Message): @@ -1739,17 +1634,17 @@ class DemandGenCarouselAdInfo(proto.Message): Attributes: business_name (str): Required. The Advertiser/brand name. - logo_image (google.ads.googleads.v19.common.types.AdImageAsset): + logo_image (google.ads.googleads.v23.common.types.AdImageAsset): Required. Logo image to be used in the ad. The minimum size is 128x128 and the aspect ratio must be 1:1 (+-1%). - headline (google.ads.googleads.v19.common.types.AdTextAsset): + headline (google.ads.googleads.v23.common.types.AdTextAsset): Required. Headline of the ad. - description (google.ads.googleads.v19.common.types.AdTextAsset): + description (google.ads.googleads.v23.common.types.AdTextAsset): Required. The descriptive text of the ad. call_to_action_text (str): Call to action text. - carousel_cards (MutableSequence[google.ads.googleads.v19.common.types.AdDemandGenCarouselCardAsset]): + carousel_cards (MutableSequence[google.ads.googleads.v23.common.types.AdDemandGenCarouselCardAsset]): Required. Carousel cards that will display with the ad. Min 2 max 10. """ @@ -1790,30 +1685,34 @@ class DemandGenVideoResponsiveAdInfo(proto.Message): r"""A Demand Gen video responsive ad. Attributes: - headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets used for the short headline. - long_headlines (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + long_headlines (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets used for the long headline. - descriptions (MutableSequence[google.ads.googleads.v19.common.types.AdTextAsset]): + descriptions (MutableSequence[google.ads.googleads.v23.common.types.AdTextAsset]): List of text assets used for the description. - videos (MutableSequence[google.ads.googleads.v19.common.types.AdVideoAsset]): + videos (MutableSequence[google.ads.googleads.v23.common.types.AdVideoAsset]): List of YouTube video assets used for the ad. - logo_images (MutableSequence[google.ads.googleads.v19.common.types.AdImageAsset]): + logo_images (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): Logo image to be used in the ad. Valid image types are GIF, JPEG, and PNG. The minimum size is 128x128 and the aspect ratio must be 1:1 (+-1%). + companion_banners (MutableSequence[google.ads.googleads.v23.common.types.AdImageAsset]): + List of image assets used for the companion + banner. Currently, only a single value for the + companion banner asset is supported. breadcrumb1 (str): First part of text that appears in the ad with the displayed URL. breadcrumb2 (str): Second part of text that appears in the ad with the displayed URL. - business_name (google.ads.googleads.v19.common.types.AdTextAsset): + business_name (google.ads.googleads.v23.common.types.AdTextAsset): Required. The advertiser/brand name. - call_to_actions (MutableSequence[google.ads.googleads.v19.common.types.AdCallToActionAsset]): + call_to_actions (MutableSequence[google.ads.googleads.v23.common.types.AdCallToActionAsset]): Assets of type CallToActionAsset used for the "Call To Action" button. """ @@ -1843,6 +1742,13 @@ class DemandGenVideoResponsiveAdInfo(proto.Message): number=5, message=ad_asset.AdImageAsset, ) + companion_banners: MutableSequence[ad_asset.AdImageAsset] = ( + proto.RepeatedField( + proto.MESSAGE, + number=10, + message=ad_asset.AdImageAsset, + ) + ) breadcrumb1: str = proto.Field( proto.STRING, number=6, @@ -1871,17 +1777,17 @@ class DemandGenProductAdInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - headline (google.ads.googleads.v19.common.types.AdTextAsset): + headline (google.ads.googleads.v23.common.types.AdTextAsset): Required. Text asset used for the short headline. This field is a member of `oneof`_ ``_headline``. - description (google.ads.googleads.v19.common.types.AdTextAsset): + description (google.ads.googleads.v23.common.types.AdTextAsset): Required. Text asset used for the description. This field is a member of `oneof`_ ``_description``. - logo_image (google.ads.googleads.v19.common.types.AdImageAsset): + logo_image (google.ads.googleads.v23.common.types.AdImageAsset): Required. Logo image to be used in the ad. Valid image types are GIF, JPEG, and PNG. The minimum size is 128x128 and the aspect ratio @@ -1894,9 +1800,9 @@ class DemandGenProductAdInfo(proto.Message): breadcrumb2 (str): Second part of text that appears in the ad with the displayed URL. - business_name (google.ads.googleads.v19.common.types.AdTextAsset): + business_name (google.ads.googleads.v23.common.types.AdTextAsset): Required. The advertiser/brand name. - call_to_action (google.ads.googleads.v19.common.types.AdCallToActionAsset): + call_to_action (google.ads.googleads.v23.common.types.AdCallToActionAsset): Asset of type CallToActionAsset used for the "Call To Action" button. diff --git a/google/ads/googleads/v23/common/types/additional_application_info.py b/google/ads/googleads/v23/common/types/additional_application_info.py new file mode 100644 index 000000000..ce291737a --- /dev/null +++ b/google/ads/googleads/v23/common/types/additional_application_info.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.ads.googleads.v23.enums.types import ( + application_instance as gage_application_instance, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", + manifest={ + "AdditionalApplicationInfo", + }, +) + + +class AdditionalApplicationInfo(proto.Message): + r"""Additional information about the application/tool issuing the + request. This field is only used by [ContentCreatorInsightsService], + [AudienceInsightsService], and [ReachPlanService] APIs. + + Attributes: + application_id (str): + The unique identifier of the agency proprietary application. + This identifier is generated by Google. Reach out to your + Google representative to request an application_id for each + new application being integrated. + application_instance (google.ads.googleads.v23.enums.types.ApplicationInstanceEnum.ApplicationInstance): + The instance type of the application sending + the request. + """ + + application_id: str = proto.Field( + proto.STRING, + number=1, + ) + application_instance: ( + gage_application_instance.ApplicationInstanceEnum.ApplicationInstance + ) = proto.Field( + proto.ENUM, + number=2, + enum=gage_application_instance.ApplicationInstanceEnum.ApplicationInstance, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/common/types/asset_policy.py b/google/ads/googleads/v23/common/types/asset_policy.py similarity index 85% rename from google/ads/googleads/v19/common/types/asset_policy.py rename to google/ads/googleads/v23/common/types/asset_policy.py index 6c67b1c54..d7fbb5457 100644 --- a/google/ads/googleads/v19/common/types/asset_policy.py +++ b/google/ads/googleads/v23/common/types/asset_policy.py @@ -19,21 +19,21 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import policy -from google.ads.googleads.v19.enums.types import asset_link_primary_status -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import policy +from google.ads.googleads.v23.enums.types import asset_link_primary_status +from google.ads.googleads.v23.enums.types import ( asset_link_primary_status_reason, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( asset_offline_evaluation_error_reasons, ) -from google.ads.googleads.v19.enums.types import policy_approval_status -from google.ads.googleads.v19.enums.types import policy_review_status +from google.ads.googleads.v23.enums.types import policy_approval_status +from google.ads.googleads.v23.enums.types import policy_review_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "AdAssetPolicySummary", "AssetLinkPrimaryStatusDetails", @@ -46,11 +46,11 @@ class AdAssetPolicySummary(proto.Message): r"""Contains policy information for an asset inside an ad. Attributes: - policy_topic_entries (MutableSequence[google.ads.googleads.v19.common.types.PolicyTopicEntry]): + policy_topic_entries (MutableSequence[google.ads.googleads.v23.common.types.PolicyTopicEntry]): The list of policy findings for this asset. - review_status (google.ads.googleads.v19.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): + review_status (google.ads.googleads.v23.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): Where in the review process this asset. - approval_status (google.ads.googleads.v19.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): + approval_status (google.ads.googleads.v23.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): The overall approval status of this asset, which is calculated based on the status of its individual policy topic entries. @@ -93,16 +93,16 @@ class AssetLinkPrimaryStatusDetails(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - reason (google.ads.googleads.v19.enums.types.AssetLinkPrimaryStatusReasonEnum.AssetLinkPrimaryStatusReason): + reason (google.ads.googleads.v23.enums.types.AssetLinkPrimaryStatusReasonEnum.AssetLinkPrimaryStatusReason): Provides the reason of this PrimaryStatus. This field is a member of `oneof`_ ``_reason``. - status (google.ads.googleads.v19.enums.types.AssetLinkPrimaryStatusEnum.AssetLinkPrimaryStatus): + status (google.ads.googleads.v23.enums.types.AssetLinkPrimaryStatusEnum.AssetLinkPrimaryStatus): Provides the PrimaryStatus of this status detail. This field is a member of `oneof`_ ``_status``. - asset_disapproved (google.ads.googleads.v19.common.types.AssetDisapproved): + asset_disapproved (google.ads.googleads.v23.common.types.AssetDisapproved): Provides the details for AssetLinkPrimaryStatusReason.ASSET_DISAPPROVED @@ -137,7 +137,7 @@ class AssetDisapproved(proto.Message): r"""Details related to AssetLinkPrimaryStatusReasonPB.ASSET_DISAPPROVED Attributes: - offline_evaluation_error_reasons (MutableSequence[google.ads.googleads.v19.enums.types.AssetOfflineEvaluationErrorReasonsEnum.AssetOfflineEvaluationErrorReasons]): + offline_evaluation_error_reasons (MutableSequence[google.ads.googleads.v23.enums.types.AssetOfflineEvaluationErrorReasonsEnum.AssetOfflineEvaluationErrorReasons]): Provides the quality evaluation disapproval reason of an asset. """ diff --git a/google/ads/googleads/v19/common/types/asset_set_types.py b/google/ads/googleads/v23/common/types/asset_set_types.py similarity index 92% rename from google/ads/googleads/v19/common/types/asset_set_types.py rename to google/ads/googleads/v23/common/types/asset_set_types.py index 2232d8594..c53ca2e5f 100644 --- a/google/ads/googleads/v19/common/types/asset_set_types.py +++ b/google/ads/googleads/v23/common/types/asset_set_types.py @@ -19,16 +19,16 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import chain_relationship_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import chain_relationship_type +from google.ads.googleads.v23.enums.types import ( location_ownership_type as gage_location_ownership_type, ) -from google.ads.googleads.v19.enums.types import location_string_filter_type +from google.ads.googleads.v23.enums.types import location_string_filter_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "LocationSet", "BusinessProfileLocationSet", @@ -57,21 +57,21 @@ class LocationSet(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - location_ownership_type (google.ads.googleads.v19.enums.types.LocationOwnershipTypeEnum.LocationOwnershipType): + location_ownership_type (google.ads.googleads.v23.enums.types.LocationOwnershipTypeEnum.LocationOwnershipType): Required. Immutable. Location Ownership Type (owned location or affiliate location). - business_profile_location_set (google.ads.googleads.v19.common.types.BusinessProfileLocationSet): + business_profile_location_set (google.ads.googleads.v23.common.types.BusinessProfileLocationSet): Data used to configure a location set populated from Google Business Profile locations. This field is a member of `oneof`_ ``source``. - chain_location_set (google.ads.googleads.v19.common.types.ChainSet): + chain_location_set (google.ads.googleads.v23.common.types.ChainSet): Data used to configure a location on chain set populated with the specified chains. This field is a member of `oneof`_ ``source``. - maps_location_set (google.ads.googleads.v19.common.types.MapsLocationSet): + maps_location_set (google.ads.googleads.v23.common.types.MapsLocationSet): Only set if locations are synced based on selected maps locations @@ -180,10 +180,10 @@ class ChainSet(proto.Message): specified chains. Attributes: - relationship_type (google.ads.googleads.v19.enums.types.ChainRelationshipTypeEnum.ChainRelationshipType): + relationship_type (google.ads.googleads.v23.enums.types.ChainRelationshipTypeEnum.ChainRelationshipType): Required. Immutable. Relationship type the specified chains have with this advertiser. - chains (MutableSequence[google.ads.googleads.v19.common.types.ChainFilter]): + chains (MutableSequence[google.ads.googleads.v23.common.types.ChainFilter]): Required. A list of chain level filters, all filters are OR'ed together. """ @@ -233,7 +233,7 @@ class MapsLocationSet(proto.Message): r"""Wrapper for multiple maps location sync data Attributes: - maps_locations (MutableSequence[google.ads.googleads.v19.common.types.MapsLocationInfo]): + maps_locations (MutableSequence[google.ads.googleads.v23.common.types.MapsLocationInfo]): Required. A list of maps location info that user manually synced in. """ @@ -265,7 +265,7 @@ class BusinessProfileLocationGroup(proto.Message): sync source is Business Profile. Attributes: - dynamic_business_profile_location_group_filter (google.ads.googleads.v19.common.types.DynamicBusinessProfileLocationGroupFilter): + dynamic_business_profile_location_group_filter (google.ads.googleads.v23.common.types.DynamicBusinessProfileLocationGroupFilter): Filter for dynamic Business Profile location sets. """ @@ -292,7 +292,7 @@ class DynamicBusinessProfileLocationGroupFilter(proto.Message): label. Only locations that have any of the listed labels will be in the asset set. Label filters are OR'ed together. - business_name_filter (google.ads.googleads.v19.common.types.BusinessProfileBusinessNameFilter): + business_name_filter (google.ads.googleads.v23.common.types.BusinessProfileBusinessNameFilter): Used to filter Business Profile locations by business name. @@ -324,7 +324,7 @@ class BusinessProfileBusinessNameFilter(proto.Message): Attributes: business_name (str): Business name string to use for filtering. - filter_type (google.ads.googleads.v19.enums.types.LocationStringFilterTypeEnum.LocationStringFilterType): + filter_type (google.ads.googleads.v23.enums.types.LocationStringFilterTypeEnum.LocationStringFilterType): The type of string matching to use when filtering with business_name. """ @@ -348,7 +348,7 @@ class ChainLocationGroup(proto.Message): sync source is chain. Attributes: - dynamic_chain_location_group_filters (MutableSequence[google.ads.googleads.v19.common.types.ChainFilter]): + dynamic_chain_location_group_filters (MutableSequence[google.ads.googleads.v23.common.types.ChainFilter]): Used to filter chain locations by chain ids. Only Locations that belong to the specified chain(s) will be in the asset set. diff --git a/google/ads/googleads/v19/common/types/asset_types.py b/google/ads/googleads/v23/common/types/asset_types.py similarity index 89% rename from google/ads/googleads/v19/common/types/asset_types.py rename to google/ads/googleads/v23/common/types/asset_types.py index 006d34251..032d8fd4a 100644 --- a/google/ads/googleads/v19/common/types/asset_types.py +++ b/google/ads/googleads/v23/common/types/asset_types.py @@ -19,41 +19,43 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.common.types import feed_common -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import ad_asset +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.common.types import feed_common +from google.ads.googleads.v23.enums.types import ( business_message_call_to_action_type, ) -from google.ads.googleads.v19.enums.types import business_message_provider -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import business_message_provider +from google.ads.googleads.v23.enums.types import ( call_conversion_reporting_state as gage_call_conversion_reporting_state, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( call_to_action_type as gage_call_to_action_type, ) -from google.ads.googleads.v19.enums.types import lead_form_call_to_action_type -from google.ads.googleads.v19.enums.types import lead_form_desired_intent -from google.ads.googleads.v19.enums.types import lead_form_field_user_input_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import lead_form_call_to_action_type +from google.ads.googleads.v23.enums.types import lead_form_desired_intent +from google.ads.googleads.v23.enums.types import lead_form_field_user_input_type +from google.ads.googleads.v23.enums.types import ( lead_form_post_submit_call_to_action_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( location_ownership_type as gage_location_ownership_type, ) -from google.ads.googleads.v19.enums.types import mime_type as gage_mime_type -from google.ads.googleads.v19.enums.types import mobile_app_vendor -from google.ads.googleads.v19.enums.types import price_extension_price_qualifier -from google.ads.googleads.v19.enums.types import price_extension_price_unit -from google.ads.googleads.v19.enums.types import price_extension_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import mime_type as gage_mime_type +from google.ads.googleads.v23.enums.types import mobile_app_vendor +from google.ads.googleads.v23.enums.types import price_extension_price_qualifier +from google.ads.googleads.v23.enums.types import price_extension_price_unit +from google.ads.googleads.v23.enums.types import price_extension_type +from google.ads.googleads.v23.enums.types import promotion_barcode_type +from google.ads.googleads.v23.enums.types import ( promotion_extension_discount_modifier, ) -from google.ads.googleads.v19.enums.types import promotion_extension_occasion +from google.ads.googleads.v23.enums.types import promotion_extension_occasion __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "YoutubeVideoAsset", "MediaBundleAsset", @@ -68,6 +70,8 @@ "WebhookDelivery", "BookOnGoogleAsset", "PromotionAsset", + "PromotionBarcodeInfo", + "PromotionQrCodeInfo", "CalloutAsset", "StructuredSnippetAsset", "SitelinkAsset", @@ -92,8 +96,11 @@ "HotelPropertyAsset", "BusinessMessageAsset", "WhatsappBusinessMessageInfo", + "FacebookMessengerBusinessMessageInfo", + "ZaloBusinessMessageInfo", "BusinessMessageCallToActionInfo", "AppDeepLinkAsset", + "YouTubeVideoListAsset", }, ) @@ -163,9 +170,9 @@ class ImageAsset(proto.Message): File size of the image asset in bytes. This field is a member of `oneof`_ ``_file_size``. - mime_type (google.ads.googleads.v19.enums.types.MimeTypeEnum.MimeType): + mime_type (google.ads.googleads.v23.enums.types.MimeTypeEnum.MimeType): MIME type of the image asset. - full_size (google.ads.googleads.v19.common.types.ImageDimension): + full_size (google.ads.googleads.v23.common.types.ImageDimension): Metadata for this image at its original size. """ @@ -259,7 +266,7 @@ class LeadFormAsset(proto.Message): business_name (str): Required. The name of the business being advertised. - call_to_action_type (google.ads.googleads.v19.enums.types.LeadFormCallToActionTypeEnum.LeadFormCallToActionType): + call_to_action_type (google.ads.googleads.v23.enums.types.LeadFormCallToActionTypeEnum.LeadFormCallToActionType): Required. Pre-defined display text that encourages user to expand the form. call_to_action_description (str): @@ -290,19 +297,19 @@ class LeadFormAsset(proto.Message): will follow up with the user. This field is a member of `oneof`_ ``_post_submit_description``. - fields (MutableSequence[google.ads.googleads.v19.common.types.LeadFormField]): + fields (MutableSequence[google.ads.googleads.v23.common.types.LeadFormField]): Ordered list of input fields. This field can be updated by reordering questions, but not by adding or removing questions. - custom_question_fields (MutableSequence[google.ads.googleads.v19.common.types.LeadFormCustomQuestionField]): + custom_question_fields (MutableSequence[google.ads.googleads.v23.common.types.LeadFormCustomQuestionField]): Ordered list of custom question fields. This field is subject to a limit of 5 qualifying questions per form. - delivery_methods (MutableSequence[google.ads.googleads.v19.common.types.LeadFormDeliveryMethod]): + delivery_methods (MutableSequence[google.ads.googleads.v23.common.types.LeadFormDeliveryMethod]): Configured methods for collected lead data to be delivered to advertiser. Only one method typed as WebhookDelivery can be configured. - post_submit_call_to_action_type (google.ads.googleads.v19.enums.types.LeadFormPostSubmitCallToActionTypeEnum.LeadFormPostSubmitCallToActionType): + post_submit_call_to_action_type (google.ads.googleads.v23.enums.types.LeadFormPostSubmitCallToActionTypeEnum.LeadFormPostSubmitCallToActionType): Pre-defined display text that encourages user action after the form is submitted. background_image_asset (str): @@ -310,7 +317,7 @@ class LeadFormAsset(proto.Message): The image dimensions must be exactly 1200x628. This field is a member of `oneof`_ ``_background_image_asset``. - desired_intent (google.ads.googleads.v19.enums.types.LeadFormDesiredIntentEnum.LeadFormDesiredIntent): + desired_intent (google.ads.googleads.v23.enums.types.LeadFormDesiredIntentEnum.LeadFormDesiredIntent): Chosen intent for the lead form, for example, more volume or more qualified. custom_disclosure (str): @@ -414,12 +421,12 @@ class LeadFormField(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - input_type (google.ads.googleads.v19.enums.types.LeadFormFieldUserInputTypeEnum.LeadFormFieldUserInputType): + input_type (google.ads.googleads.v23.enums.types.LeadFormFieldUserInputTypeEnum.LeadFormFieldUserInputType): Describes the input type, which may be a predefined type such as "full name" or a pre-vetted question like "What kind of vehicle do you have?". - single_choice_answers (google.ads.googleads.v19.common.types.LeadFormSingleChoiceAnswers): + single_choice_answers (google.ads.googleads.v23.common.types.LeadFormSingleChoiceAnswers): Answer configuration for a single choice question. Can be set only for pre-vetted question fields. Minimum of 2 answers required @@ -471,7 +478,7 @@ class LeadFormCustomQuestionField(proto.Message): custom_question_text (str): The exact custom question field text (for example, "What kind of vehicle do you have?"). - single_choice_answers (google.ads.googleads.v19.common.types.LeadFormSingleChoiceAnswers): + single_choice_answers (google.ads.googleads.v23.common.types.LeadFormSingleChoiceAnswers): Answer configuration for a single choice question. Minimum of 2 answers and maximum of 12 allowed. @@ -528,7 +535,7 @@ class LeadFormDeliveryMethod(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - webhook (google.ads.googleads.v19.common.types.WebhookDelivery): + webhook (google.ads.googleads.v23.common.types.WebhookDelivery): Webhook method of delivery. This field is a member of `oneof`_ ``delivery_details``. @@ -608,7 +615,7 @@ class PromotionAsset(proto.Message): promotion_target (str): Required. A freeform description of what the promotion is targeting. - discount_modifier (google.ads.googleads.v19.enums.types.PromotionExtensionDiscountModifierEnum.PromotionExtensionDiscountModifier): + discount_modifier (google.ads.googleads.v23.enums.types.PromotionExtensionDiscountModifierEnum.PromotionExtensionDiscountModifier): A modifier for qualification of the discount. redemption_start_date (str): Start date of when the promotion is eligible @@ -616,7 +623,7 @@ class PromotionAsset(proto.Message): redemption_end_date (str): Last date of when the promotion is eligible to be redeemed, in yyyy-MM-dd format. - occasion (google.ads.googleads.v19.enums.types.PromotionExtensionOccasionEnum.PromotionExtensionOccasion): + occasion (google.ads.googleads.v23.enums.types.PromotionExtensionOccasionEnum.PromotionExtensionOccasion): The occasion the promotion was intended for. If an occasion is set, the redemption window will need to fall within the date range @@ -630,17 +637,22 @@ class PromotionAsset(proto.Message): end_date (str): Last date of when this asset is effective and still serving, in yyyy-MM-dd format. - ad_schedule_targets (MutableSequence[google.ads.googleads.v19.common.types.AdScheduleInfo]): + ad_schedule_targets (MutableSequence[google.ads.googleads.v23.common.types.AdScheduleInfo]): List of non-overlapping schedules specifying all time intervals for which the asset may serve. There can be a maximum of 6 schedules per day, 42 in total. + terms_and_conditions_text (str): + Terms and conditions of the promotion. + terms_and_conditions_uri (str): + URI to the terms and conditions of the + promotion. percent_off (int): Percentage off discount in the promotion. 1,000,000 = 100%. Either this or money_amount_off is required. This field is a member of `oneof`_ ``discount_type``. - money_amount_off (google.ads.googleads.v19.common.types.Money): + money_amount_off (google.ads.googleads.v23.common.types.Money): Money amount off for discount in the promotion. Either this or percent_off is required. @@ -650,10 +662,21 @@ class PromotionAsset(proto.Message): eligible for the promotion. This field is a member of `oneof`_ ``promotion_trigger``. - orders_over_amount (google.ads.googleads.v19.common.types.Money): + orders_over_amount (google.ads.googleads.v23.common.types.Money): The amount the total order needs to be for the user to be eligible for the promotion. + This field is a member of `oneof`_ ``promotion_trigger``. + promotion_barcode_info (google.ads.googleads.v23.common.types.PromotionBarcodeInfo): + Barcode info used to generate promotion + barcode for user to be eligible for the + promotion. + + This field is a member of `oneof`_ ``promotion_trigger``. + promotion_qr_code_info (google.ads.googleads.v23.common.types.PromotionQrCodeInfo): + QR code info used to generate promotion QR + code for user to be eligible for the promotion. + This field is a member of `oneof`_ ``promotion_trigger``. """ @@ -702,6 +725,14 @@ class PromotionAsset(proto.Message): message=criteria.AdScheduleInfo, ) ) + terms_and_conditions_text: str = proto.Field( + proto.STRING, + number=14, + ) + terms_and_conditions_uri: str = proto.Field( + proto.STRING, + number=15, + ) percent_off: int = proto.Field( proto.INT64, number=3, @@ -724,6 +755,58 @@ class PromotionAsset(proto.Message): oneof="promotion_trigger", message=feed_common.Money, ) + promotion_barcode_info: "PromotionBarcodeInfo" = proto.Field( + proto.MESSAGE, + number=16, + oneof="promotion_trigger", + message="PromotionBarcodeInfo", + ) + promotion_qr_code_info: "PromotionQrCodeInfo" = proto.Field( + proto.MESSAGE, + number=17, + oneof="promotion_trigger", + message="PromotionQrCodeInfo", + ) + + +class PromotionBarcodeInfo(proto.Message): + r"""Barcode info to generate promotion barcode. + + Attributes: + type_ (google.ads.googleads.v23.enums.types.PromotionBarcodeTypeEnum.PromotionBarcodeType): + Barcode type used to generate barcode with + the correct format. + barcode_content (str): + Promotion message to be encoded in the + barcode. + """ + + type_: ( + promotion_barcode_type.PromotionBarcodeTypeEnum.PromotionBarcodeType + ) = proto.Field( + proto.ENUM, + number=1, + enum=promotion_barcode_type.PromotionBarcodeTypeEnum.PromotionBarcodeType, + ) + barcode_content: str = proto.Field( + proto.STRING, + number=2, + ) + + +class PromotionQrCodeInfo(proto.Message): + r"""QR code info to generate promotion QR code. + + Attributes: + qr_code_content (str): + Promotion message to be encoded in the QR + code. + """ + + qr_code_content: str = proto.Field( + proto.STRING, + number=1, + ) class CalloutAsset(proto.Message): @@ -740,7 +823,7 @@ class CalloutAsset(proto.Message): end_date (str): Last date of when this asset is effective and still serving, in yyyy-MM-dd format. - ad_schedule_targets (MutableSequence[google.ads.googleads.v19.common.types.AdScheduleInfo]): + ad_schedule_targets (MutableSequence[google.ads.googleads.v23.common.types.AdScheduleInfo]): List of non-overlapping schedules specifying all time intervals for which the asset may serve. There can be a maximum of 6 schedules per @@ -819,7 +902,7 @@ class SitelinkAsset(proto.Message): end_date (str): Last date of when this asset is effective and still serving, in yyyy-MM-dd format. - ad_schedule_targets (MutableSequence[google.ads.googleads.v19.common.types.AdScheduleInfo]): + ad_schedule_targets (MutableSequence[google.ads.googleads.v23.common.types.AdScheduleInfo]): List of non-overlapping schedules specifying all time intervals for which the asset may serve. There can be a maximum of 6 schedules per @@ -1001,7 +1084,7 @@ class MobileAppAsset(proto.Message): mobile application. It should just contain the platform native id, like "com.android.ebay" for Android or "12345689" for iOS. - app_store (google.ads.googleads.v19.enums.types.MobileAppVendorEnum.MobileAppVendor): + app_store (google.ads.googleads.v23.enums.types.MobileAppVendorEnum.MobileAppVendor): Required. The application store that distributes this specific app. link_text (str): @@ -1074,7 +1157,7 @@ class CallAsset(proto.Message): phone_number (str): Required. The advertiser's raw phone number. Examples: '1234567890', '(123)456-7890' - call_conversion_reporting_state (google.ads.googleads.v19.enums.types.CallConversionReportingStateEnum.CallConversionReportingState): + call_conversion_reporting_state (google.ads.googleads.v23.enums.types.CallConversionReportingStateEnum.CallConversionReportingState): Indicates whether this CallAsset should use its own call conversion setting, follow the account level setting, or disable call @@ -1084,7 +1167,7 @@ class CallAsset(proto.Message): not set, the default conversion action is used. This field only has effect if call_conversion_reporting_state is set to USE_RESOURCE_LEVEL_CALL_CONVERSION_ACTION. - ad_schedule_targets (MutableSequence[google.ads.googleads.v19.common.types.AdScheduleInfo]): + ad_schedule_targets (MutableSequence[google.ads.googleads.v23.common.types.AdScheduleInfo]): List of non-overlapping schedules specifying all time intervals for which the asset may serve. There can be a maximum of 6 schedules per @@ -1123,14 +1206,14 @@ class PriceAsset(proto.Message): r"""An asset representing a list of price offers. Attributes: - type_ (google.ads.googleads.v19.enums.types.PriceExtensionTypeEnum.PriceExtensionType): + type_ (google.ads.googleads.v23.enums.types.PriceExtensionTypeEnum.PriceExtensionType): Required. The type of the price asset. - price_qualifier (google.ads.googleads.v19.enums.types.PriceExtensionPriceQualifierEnum.PriceExtensionPriceQualifier): + price_qualifier (google.ads.googleads.v23.enums.types.PriceExtensionPriceQualifierEnum.PriceExtensionPriceQualifier): The price qualifier of the price asset. language_code (str): Required. The language of the price asset. Represented as BCP 47 language tag. - price_offerings (MutableSequence[google.ads.googleads.v19.common.types.PriceOffering]): + price_offerings (MutableSequence[google.ads.googleads.v23.common.types.PriceOffering]): The price offerings of the price asset. The size of this collection should be between 3 and 8, inclusive. @@ -1173,10 +1256,10 @@ class PriceOffering(proto.Message): Required. The description of the price offering. The length of this string should be between 1 and 25, inclusive. - price (google.ads.googleads.v19.common.types.Money): + price (google.ads.googleads.v23.common.types.Money): Required. The price value of the price offering. - unit (google.ads.googleads.v19.enums.types.PriceExtensionPriceUnitEnum.PriceExtensionPriceUnit): + unit (google.ads.googleads.v23.enums.types.PriceExtensionPriceUnitEnum.PriceExtensionPriceUnit): The price unit of the price offering. final_url (str): Required. The final URL after all cross @@ -1220,7 +1303,7 @@ class CallToActionAsset(proto.Message): r"""A call to action asset. Attributes: - call_to_action (google.ads.googleads.v19.enums.types.CallToActionTypeEnum.CallToActionType): + call_to_action (google.ads.googleads.v23.enums.types.CallToActionTypeEnum.CallToActionType): Call to action. """ @@ -1700,7 +1783,7 @@ class DynamicFlightsAsset(proto.Message): PAR,LON. custom_mapping (str): A custom field which can be multiple key to values mapping - separated by delimiters (",", "|" and ":"), in the forms of + separated by delimiters (",", "\|" and ":"), in the forms of ": , , ... , \| : , ... , \| ... \| : , ... ," for example, wifi: most \| aircraft: 320, 77W \| @@ -2209,14 +2292,14 @@ class LocationAsset(proto.Message): asset type. See https://developers.google.com/places/web-service/place-id to learn more about Place ID. - business_profile_locations (MutableSequence[google.ads.googleads.v19.common.types.BusinessProfileLocation]): + business_profile_locations (MutableSequence[google.ads.googleads.v23.common.types.BusinessProfileLocation]): The list of business locations for the customer. This will only be returned if the Location Asset is syncing from the Business Profile account. It is possible to have multiple Business Profile listings under the same account that point to the same Place ID. - location_ownership_type (google.ads.googleads.v19.enums.types.LocationOwnershipTypeEnum.LocationOwnershipType): + location_ownership_type (google.ads.googleads.v23.enums.types.LocationOwnershipTypeEnum.LocationOwnershipType): The type of location ownership. If the type is BUSINESS_OWNER, it will be served as a location extension. If the type is AFFILIATE, it will be served as an affiliate @@ -2308,23 +2391,36 @@ class HotelPropertyAsset(proto.Message): class BusinessMessageAsset(proto.Message): r"""A business message asset. + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - message_provider (google.ads.googleads.v19.enums.types.BusinessMessageProviderEnum.BusinessMessageProvider): + message_provider (google.ads.googleads.v23.enums.types.BusinessMessageProviderEnum.BusinessMessageProvider): Required. Message provider of the business message asset. starter_message (str): Required. A welcome message to prompt the user to initiate a conversation. - call_to_action (google.ads.googleads.v19.common.types.BusinessMessageCallToActionInfo): + call_to_action (google.ads.googleads.v23.common.types.BusinessMessageCallToActionInfo): A call to action for the business message asset. This field is a member of `oneof`_ ``_call_to_action``. - whatsapp_info (google.ads.googleads.v19.common.types.WhatsappBusinessMessageInfo): + whatsapp_info (google.ads.googleads.v23.common.types.WhatsappBusinessMessageInfo): Whatsapp. + This field is a member of `oneof`_ ``message_provider_data``. + facebook_messenger_info (google.ads.googleads.v23.common.types.FacebookMessengerBusinessMessageInfo): + Facebook Messenger. + + This field is a member of `oneof`_ ``message_provider_data``. + zalo_info (google.ads.googleads.v23.common.types.ZaloBusinessMessageInfo): + Zalo. + This field is a member of `oneof`_ ``message_provider_data``. """ @@ -2351,6 +2447,20 @@ class BusinessMessageAsset(proto.Message): oneof="message_provider_data", message="WhatsappBusinessMessageInfo", ) + facebook_messenger_info: "FacebookMessengerBusinessMessageInfo" = ( + proto.Field( + proto.MESSAGE, + number=6, + oneof="message_provider_data", + message="FacebookMessengerBusinessMessageInfo", + ) + ) + zalo_info: "ZaloBusinessMessageInfo" = proto.Field( + proto.MESSAGE, + number=7, + oneof="message_provider_data", + message="ZaloBusinessMessageInfo", + ) class WhatsappBusinessMessageInfo(proto.Message): @@ -2376,11 +2486,61 @@ class WhatsappBusinessMessageInfo(proto.Message): ) +class FacebookMessengerBusinessMessageInfo(proto.Message): + r"""Facebook Messenger information to use for messaging. + + Attributes: + page_name (str): + Required. Facebook page name used for + starting a chat on Facebook Messenger. + """ + + page_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ZaloBusinessMessageInfo(proto.Message): + r"""Zalo information to use for messaging. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + oa_id (int): + Zalo Official Account ID of the advertiser. + + This field is a member of `oneof`_ ``zalo_id``. + custom_name (str): + Custom name generated by the advertiser for + their Zalo Account. These names will usually be + registered brands or trademarks. + + This field is a member of `oneof`_ ``zalo_id``. + """ + + oa_id: int = proto.Field( + proto.INT64, + number=1, + oneof="zalo_id", + ) + custom_name: str = proto.Field( + proto.STRING, + number=2, + oneof="zalo_id", + ) + + class BusinessMessageCallToActionInfo(proto.Message): r"""Display information that encourages the user to take action. Attributes: - call_to_action_selection (google.ads.googleads.v19.enums.types.BusinessMessageCallToActionTypeEnum.BusinessMessageCallToActionType): + call_to_action_selection (google.ads.googleads.v23.enums.types.BusinessMessageCallToActionTypeEnum.BusinessMessageCallToActionType): Required. Pre-defined call to action text. call_to_action_description (str): Required. Text providing a clear value @@ -2419,4 +2579,23 @@ class AppDeepLinkAsset(proto.Message): ) +class YouTubeVideoListAsset(proto.Message): + r"""A YouTube video list asset. + + Attributes: + youtube_videos (MutableSequence[google.ads.googleads.v23.common.types.AdVideoAsset]): + List of videos. Each is a reference to a + YouTube video asset. Minimum of 2 videos + required and maximum of 5 allowed. + """ + + youtube_videos: MutableSequence[ad_asset.AdVideoAsset] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message=ad_asset.AdVideoAsset, + ) + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/common/types/asset_usage.py b/google/ads/googleads/v23/common/types/asset_usage.py similarity index 87% rename from google/ads/googleads/v19/common/types/asset_usage.py rename to google/ads/googleads/v23/common/types/asset_usage.py index 149acaa59..10d66930f 100644 --- a/google/ads/googleads/v19/common/types/asset_usage.py +++ b/google/ads/googleads/v23/common/types/asset_usage.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( served_asset_field_type as gage_served_asset_field_type, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "AssetUsage", }, @@ -38,7 +38,7 @@ class AssetUsage(proto.Message): Attributes: asset (str): Resource name of the asset. - served_asset_field_type (google.ads.googleads.v19.enums.types.ServedAssetFieldTypeEnum.ServedAssetFieldType): + served_asset_field_type (google.ads.googleads.v23.enums.types.ServedAssetFieldTypeEnum.ServedAssetFieldType): The served field type of the asset. """ diff --git a/google/ads/googleads/v23/common/types/audience_insights_attribute.py b/google/ads/googleads/v23/common/types/audience_insights_attribute.py new file mode 100644 index 000000000..b1dda4f80 --- /dev/null +++ b/google/ads/googleads/v23/common/types/audience_insights_attribute.py @@ -0,0 +1,654 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import audience_insights_dimension +from google.ads.googleads.v23.enums.types import ( + insights_knowledge_graph_entity_capabilities, +) +from google.ads.googleads.v23.enums.types import ( + user_list_type as gage_user_list_type, +) +from google.ads.googleads.v23.enums.types import youtube_video_property + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", + manifest={ + "AudienceInsightsAttributeMetadata", + "AudienceInsightsAttribute", + "AudienceInsightsEntity", + "AudienceInsightsCategory", + "AudienceInsightsLineup", + "YouTubeChannelAttributeMetadata", + "YouTubeVideoAttributeMetadata", + "LineupAttributeMetadata", + "LocationAttributeMetadata", + "UserInterestAttributeMetadata", + "KnowledgeGraphAttributeMetadata", + "UserListAttributeMetadata", + "AudienceInsightsAttributeMetadataGroup", + }, +) + + +class AudienceInsightsAttributeMetadata(proto.Message): + r"""An audience attribute, with metadata about it, returned in + response to a search. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + dimension (google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension): + The type of the attribute. + attribute (google.ads.googleads.v23.common.types.AudienceInsightsAttribute): + The attribute itself. + display_name (str): + The human-readable name of the attribute. + display_info (str): + A string that supplements the display_name to identify the + attribute. If the dimension is TOPIC, this is a brief + description of the Knowledge Graph entity, such as "American + singer-songwriter". If the dimension is CATEGORY, this is + the complete path to the category in The Product & Service + taxonomy, for example "/Apparel/Clothing/Outerwear". + potential_youtube_reach (int): + An estimate of the number of reachable + YouTube users matching this attribute in the + requested location, or zero if that information + is not available for this attribute. This field + is not populated in every response. + subscriber_share (float): + The share of subscribers within this + attribute, between and including 0 and + 1. This field is not populated in every + response. + viewer_share (float): + The share of viewers within this attribute, + between and including 0 and + 1. This field is not populated in every + response. + youtube_channel_metadata (google.ads.googleads.v23.common.types.YouTubeChannelAttributeMetadata): + Special metadata for a YouTube channel. + + This field is a member of `oneof`_ ``dimension_metadata``. + youtube_video_metadata (google.ads.googleads.v23.common.types.YouTubeVideoAttributeMetadata): + Special metadata for a YouTube video. + + This field is a member of `oneof`_ ``dimension_metadata``. + lineup_attribute_metadata (google.ads.googleads.v23.common.types.LineupAttributeMetadata): + Special metadata for a YouTube Lineup. + + This field is a member of `oneof`_ ``dimension_metadata``. + location_attribute_metadata (google.ads.googleads.v23.common.types.LocationAttributeMetadata): + Special metadata for a Location. + + This field is a member of `oneof`_ ``dimension_metadata``. + user_interest_attribute_metadata (google.ads.googleads.v23.common.types.UserInterestAttributeMetadata): + Special metadata for a User Interest. + + This field is a member of `oneof`_ ``dimension_metadata``. + knowledge_graph_attribute_metadata (google.ads.googleads.v23.common.types.KnowledgeGraphAttributeMetadata): + Special metadata for a Knowledge Graph + Entity. + + This field is a member of `oneof`_ ``dimension_metadata``. + user_list_attribute_metadata (google.ads.googleads.v23.common.types.UserListAttributeMetadata): + Special metadata for a User List. + + This field is a member of `oneof`_ ``dimension_metadata``. + """ + + dimension: ( + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ) = proto.Field( + proto.ENUM, + number=1, + enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, + ) + attribute: "AudienceInsightsAttribute" = proto.Field( + proto.MESSAGE, + number=2, + message="AudienceInsightsAttribute", + ) + display_name: str = proto.Field( + proto.STRING, + number=3, + ) + display_info: str = proto.Field( + proto.STRING, + number=4, + ) + potential_youtube_reach: int = proto.Field( + proto.INT64, + number=8, + ) + subscriber_share: float = proto.Field( + proto.DOUBLE, + number=9, + ) + viewer_share: float = proto.Field( + proto.DOUBLE, + number=13, + ) + youtube_channel_metadata: "YouTubeChannelAttributeMetadata" = proto.Field( + proto.MESSAGE, + number=5, + oneof="dimension_metadata", + message="YouTubeChannelAttributeMetadata", + ) + youtube_video_metadata: "YouTubeVideoAttributeMetadata" = proto.Field( + proto.MESSAGE, + number=10, + oneof="dimension_metadata", + message="YouTubeVideoAttributeMetadata", + ) + lineup_attribute_metadata: "LineupAttributeMetadata" = proto.Field( + proto.MESSAGE, + number=14, + oneof="dimension_metadata", + message="LineupAttributeMetadata", + ) + location_attribute_metadata: "LocationAttributeMetadata" = proto.Field( + proto.MESSAGE, + number=7, + oneof="dimension_metadata", + message="LocationAttributeMetadata", + ) + user_interest_attribute_metadata: "UserInterestAttributeMetadata" = ( + proto.Field( + proto.MESSAGE, + number=11, + oneof="dimension_metadata", + message="UserInterestAttributeMetadata", + ) + ) + knowledge_graph_attribute_metadata: "KnowledgeGraphAttributeMetadata" = ( + proto.Field( + proto.MESSAGE, + number=12, + oneof="dimension_metadata", + message="KnowledgeGraphAttributeMetadata", + ) + ) + user_list_attribute_metadata: "UserListAttributeMetadata" = proto.Field( + proto.MESSAGE, + number=15, + oneof="dimension_metadata", + message="UserListAttributeMetadata", + ) + + +class AudienceInsightsAttribute(proto.Message): + r"""An audience attribute that can be used to request insights about the + audience. Valid inputs for these fields are available from + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v23.services.AudienceInsightsService.ListAudienceInsightsAttributes]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + age_range (google.ads.googleads.v23.common.types.AgeRangeInfo): + An audience attribute defined by an age + range. + + This field is a member of `oneof`_ ``attribute``. + gender (google.ads.googleads.v23.common.types.GenderInfo): + An audience attribute defined by a gender. + + This field is a member of `oneof`_ ``attribute``. + location (google.ads.googleads.v23.common.types.LocationInfo): + An audience attribute defined by a geographic + location. + + This field is a member of `oneof`_ ``attribute``. + user_interest (google.ads.googleads.v23.common.types.UserInterestInfo): + An Affinity or In-Market audience. + + This field is a member of `oneof`_ ``attribute``. + entity (google.ads.googleads.v23.common.types.AudienceInsightsEntity): + An audience attribute defined by interest in + a topic represented by a Knowledge Graph entity. + + This field is a member of `oneof`_ ``attribute``. + category (google.ads.googleads.v23.common.types.AudienceInsightsCategory): + An audience attribute defined by interest in + a Product & Service category. + + This field is a member of `oneof`_ ``attribute``. + lineup (google.ads.googleads.v23.common.types.AudienceInsightsLineup): + A YouTube Lineup. + + This field is a member of `oneof`_ ``attribute``. + parental_status (google.ads.googleads.v23.common.types.ParentalStatusInfo): + A Parental Status value (parent, or not a + parent). + + This field is a member of `oneof`_ ``attribute``. + income_range (google.ads.googleads.v23.common.types.IncomeRangeInfo): + A household income percentile range. + + This field is a member of `oneof`_ ``attribute``. + youtube_channel (google.ads.googleads.v23.common.types.YouTubeChannelInfo): + A YouTube channel. + + This field is a member of `oneof`_ ``attribute``. + youtube_video (google.ads.googleads.v23.common.types.YouTubeVideoInfo): + A YouTube video. + + This field is a member of `oneof`_ ``attribute``. + device (google.ads.googleads.v23.common.types.DeviceInfo): + A device type. (Mobile, Desktop, Tablet) + + This field is a member of `oneof`_ ``attribute``. + user_list (google.ads.googleads.v23.common.types.UserListInfo): + A User List. + + This field is a member of `oneof`_ ``attribute``. + """ + + age_range: criteria.AgeRangeInfo = proto.Field( + proto.MESSAGE, + number=1, + oneof="attribute", + message=criteria.AgeRangeInfo, + ) + gender: criteria.GenderInfo = proto.Field( + proto.MESSAGE, + number=2, + oneof="attribute", + message=criteria.GenderInfo, + ) + location: criteria.LocationInfo = proto.Field( + proto.MESSAGE, + number=3, + oneof="attribute", + message=criteria.LocationInfo, + ) + user_interest: criteria.UserInterestInfo = proto.Field( + proto.MESSAGE, + number=4, + oneof="attribute", + message=criteria.UserInterestInfo, + ) + entity: "AudienceInsightsEntity" = proto.Field( + proto.MESSAGE, + number=5, + oneof="attribute", + message="AudienceInsightsEntity", + ) + category: "AudienceInsightsCategory" = proto.Field( + proto.MESSAGE, + number=6, + oneof="attribute", + message="AudienceInsightsCategory", + ) + lineup: "AudienceInsightsLineup" = proto.Field( + proto.MESSAGE, + number=13, + oneof="attribute", + message="AudienceInsightsLineup", + ) + parental_status: criteria.ParentalStatusInfo = proto.Field( + proto.MESSAGE, + number=8, + oneof="attribute", + message=criteria.ParentalStatusInfo, + ) + income_range: criteria.IncomeRangeInfo = proto.Field( + proto.MESSAGE, + number=9, + oneof="attribute", + message=criteria.IncomeRangeInfo, + ) + youtube_channel: criteria.YouTubeChannelInfo = proto.Field( + proto.MESSAGE, + number=10, + oneof="attribute", + message=criteria.YouTubeChannelInfo, + ) + youtube_video: criteria.YouTubeVideoInfo = proto.Field( + proto.MESSAGE, + number=11, + oneof="attribute", + message=criteria.YouTubeVideoInfo, + ) + device: criteria.DeviceInfo = proto.Field( + proto.MESSAGE, + number=12, + oneof="attribute", + message=criteria.DeviceInfo, + ) + user_list: criteria.UserListInfo = proto.Field( + proto.MESSAGE, + number=14, + oneof="attribute", + message=criteria.UserListInfo, + ) + + +class AudienceInsightsEntity(proto.Message): + r"""A Knowledge Graph entity, represented by its machine id. + + Attributes: + knowledge_graph_machine_id (str): + Required. The machine ID (mid) of the + Knowledge Graph entity. + """ + + knowledge_graph_machine_id: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AudienceInsightsCategory(proto.Message): + r"""A Product and Service category. + + Attributes: + category_id (str): + Required. The criterion ID of the category. + """ + + category_id: str = proto.Field( + proto.STRING, + number=1, + ) + + +class AudienceInsightsLineup(proto.Message): + r"""A YouTube Lineup. + + Attributes: + lineup_id (str): + Required. The numeric ID of the lineup. + """ + + lineup_id: str = proto.Field( + proto.STRING, + number=1, + ) + + +class YouTubeChannelAttributeMetadata(proto.Message): + r"""Metadata associated with a YouTube channel attribute. + + Attributes: + subscriber_count (int): + The approximate number of subscribers to the + YouTube channel. + """ + + subscriber_count: int = proto.Field( + proto.INT64, + number=1, + ) + + +class YouTubeVideoAttributeMetadata(proto.Message): + r"""Metadata for a YouTube video attribute. + + Attributes: + thumbnail_url (str): + The URL of the video thumbnail, prefixed by + "https://img.youtube.com/". + video_url (str): + The URL of the video, prefixed by + "https://www.youtube.com/". + views_count (int): + The total number of views. + likes_count (int): + The total number of likes. + comments_count (int): + The total number of comments. + video_properties (MutableSequence[google.ads.googleads.v23.enums.types.YouTubeVideoPropertyEnum.YouTubeVideoProperty]): + The properties of this video (such as shorts, + live stream). + publish_date (str): + The date that the video was created. + Formatted as "yyyy-mm-dd". + """ + + thumbnail_url: str = proto.Field( + proto.STRING, + number=1, + ) + video_url: str = proto.Field( + proto.STRING, + number=2, + ) + views_count: int = proto.Field( + proto.INT64, + number=3, + ) + likes_count: int = proto.Field( + proto.INT64, + number=4, + ) + comments_count: int = proto.Field( + proto.INT64, + number=5, + ) + video_properties: MutableSequence[ + youtube_video_property.YouTubeVideoPropertyEnum.YouTubeVideoProperty + ] = proto.RepeatedField( + proto.ENUM, + number=6, + enum=youtube_video_property.YouTubeVideoPropertyEnum.YouTubeVideoProperty, + ) + publish_date: str = proto.Field( + proto.STRING, + number=7, + ) + + +class LineupAttributeMetadata(proto.Message): + r"""Metadata associated with a Lineup attribute. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + inventory_country (google.ads.googleads.v23.common.types.LocationInfo): + The national market associated with the + lineup. + median_monthly_inventory (int): + The median number of impressions per month on + this lineup. + + This field is a member of `oneof`_ ``_median_monthly_inventory``. + channel_count_lower_bound (int): + The lower end of a range containing the + number of channels in the lineup. + + This field is a member of `oneof`_ ``_channel_count_lower_bound``. + channel_count_upper_bound (int): + The upper end of a range containing the + number of channels in the lineup. + + This field is a member of `oneof`_ ``_channel_count_upper_bound``. + sample_channels (MutableSequence[google.ads.googleads.v23.common.types.LineupAttributeMetadata.SampleChannel]): + Examples of channels that are included in the + lineup. + """ + + class SampleChannel(proto.Message): + r"""A YouTube channel returned as an example of the content in a + lineup. + + Attributes: + youtube_channel (google.ads.googleads.v23.common.types.YouTubeChannelInfo): + A YouTube channel. + display_name (str): + The name of the sample channel. + youtube_channel_metadata (google.ads.googleads.v23.common.types.YouTubeChannelAttributeMetadata): + Metadata for the sample channel. + """ + + youtube_channel: criteria.YouTubeChannelInfo = proto.Field( + proto.MESSAGE, + number=1, + message=criteria.YouTubeChannelInfo, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + youtube_channel_metadata: "YouTubeChannelAttributeMetadata" = ( + proto.Field( + proto.MESSAGE, + number=3, + message="YouTubeChannelAttributeMetadata", + ) + ) + + inventory_country: criteria.LocationInfo = proto.Field( + proto.MESSAGE, + number=1, + message=criteria.LocationInfo, + ) + median_monthly_inventory: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + channel_count_lower_bound: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + channel_count_upper_bound: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + sample_channels: MutableSequence[SampleChannel] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=SampleChannel, + ) + + +class LocationAttributeMetadata(proto.Message): + r"""Metadata associated with a Location attribute. + + Attributes: + country_location (google.ads.googleads.v23.common.types.LocationInfo): + The country location that this attribute’s + sub country location is located in. + """ + + country_location: criteria.LocationInfo = proto.Field( + proto.MESSAGE, + number=1, + message=criteria.LocationInfo, + ) + + +class UserInterestAttributeMetadata(proto.Message): + r"""Metadata associated with a User Interest attribute. + + Attributes: + user_interest_description (str): + English language text description of the user + interest category (200 characters max). + """ + + user_interest_description: str = proto.Field( + proto.STRING, + number=1, + ) + + +class KnowledgeGraphAttributeMetadata(proto.Message): + r"""Metadata associated with a Knowledge Graph Entity attribute. + + Attributes: + entity_capabilities (MutableSequence[google.ads.googleads.v23.enums.types.InsightsKnowledgeGraphEntityCapabilitiesEnum.InsightsKnowledgeGraphEntityCapabilities]): + The capabilities of the entity used in + [ContentCreatorInsightsService][]. + related_categories (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata]): + A list of CATEGORY attributes related to this + entity. + """ + + entity_capabilities: MutableSequence[ + insights_knowledge_graph_entity_capabilities.InsightsKnowledgeGraphEntityCapabilitiesEnum.InsightsKnowledgeGraphEntityCapabilities + ] = proto.RepeatedField( + proto.ENUM, + number=1, + enum=insights_knowledge_graph_entity_capabilities.InsightsKnowledgeGraphEntityCapabilitiesEnum.InsightsKnowledgeGraphEntityCapabilities, + ) + related_categories: MutableSequence["AudienceInsightsAttributeMetadata"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=2, + message="AudienceInsightsAttributeMetadata", + ) + ) + + +class UserListAttributeMetadata(proto.Message): + r"""Metadata associated with a User List attribute. + + Attributes: + user_list_type (google.ads.googleads.v23.enums.types.UserListTypeEnum.UserListType): + The user list type. + """ + + user_list_type: gage_user_list_type.UserListTypeEnum.UserListType = ( + proto.Field( + proto.ENUM, + number=1, + enum=gage_user_list_type.UserListTypeEnum.UserListType, + ) + ) + + +class AudienceInsightsAttributeMetadataGroup(proto.Message): + r"""A group of audience attributes with metadata, returned in + response to a search. + + Attributes: + attributes (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata]): + Attributes with metadata returned in response + to a search. + """ + + attributes: MutableSequence["AudienceInsightsAttributeMetadata"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="AudienceInsightsAttributeMetadata", + ) + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/common/types/audiences.py b/google/ads/googleads/v23/common/types/audiences.py similarity index 90% rename from google/ads/googleads/v19/common/types/audiences.py rename to google/ads/googleads/v23/common/types/audiences.py index 6a3355c7a..04dbeba4f 100644 --- a/google/ads/googleads/v19/common/types/audiences.py +++ b/google/ads/googleads/v23/common/types/audiences.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import gender_type -from google.ads.googleads.v19.enums.types import income_range_type -from google.ads.googleads.v19.enums.types import parental_status_type +from google.ads.googleads.v23.enums.types import gender_type +from google.ads.googleads.v23.enums.types import income_range_type +from google.ads.googleads.v23.enums.types import parental_status_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "AudienceDimension", "AudienceExclusionDimension", @@ -58,25 +58,25 @@ class AudienceDimension(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - age (google.ads.googleads.v19.common.types.AgeDimension): + age (google.ads.googleads.v23.common.types.AgeDimension): Dimension specifying users by their age. This field is a member of `oneof`_ ``dimension``. - gender (google.ads.googleads.v19.common.types.GenderDimension): + gender (google.ads.googleads.v23.common.types.GenderDimension): Dimension specifying users by their gender. This field is a member of `oneof`_ ``dimension``. - household_income (google.ads.googleads.v19.common.types.HouseholdIncomeDimension): + household_income (google.ads.googleads.v23.common.types.HouseholdIncomeDimension): Dimension specifying users by their household income. This field is a member of `oneof`_ ``dimension``. - parental_status (google.ads.googleads.v19.common.types.ParentalStatusDimension): + parental_status (google.ads.googleads.v23.common.types.ParentalStatusDimension): Dimension specifying users by their parental status. This field is a member of `oneof`_ ``dimension``. - audience_segments (google.ads.googleads.v19.common.types.AudienceSegmentDimension): + audience_segments (google.ads.googleads.v23.common.types.AudienceSegmentDimension): Dimension specifying users by their membership in other audience segments. @@ -120,7 +120,7 @@ class AudienceExclusionDimension(proto.Message): audience. Attributes: - exclusions (MutableSequence[google.ads.googleads.v19.common.types.ExclusionSegment]): + exclusions (MutableSequence[google.ads.googleads.v23.common.types.ExclusionSegment]): Audience segment to be excluded. """ @@ -137,7 +137,7 @@ class ExclusionSegment(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - user_list (google.ads.googleads.v19.common.types.UserListSegment): + user_list (google.ads.googleads.v23.common.types.UserListSegment): User list segment to be excluded. This field is a member of `oneof`_ ``segment``. @@ -157,7 +157,7 @@ class AgeDimension(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - age_ranges (MutableSequence[google.ads.googleads.v19.common.types.AgeSegment]): + age_ranges (MutableSequence[google.ads.googleads.v23.common.types.AgeSegment]): Contiguous age range to be included in the dimension. include_undetermined (bool): @@ -216,7 +216,7 @@ class GenderDimension(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - genders (MutableSequence[google.ads.googleads.v19.enums.types.GenderTypeEnum.GenderType]): + genders (MutableSequence[google.ads.googleads.v23.enums.types.GenderTypeEnum.GenderType]): Included gender demographic segments. include_undetermined (bool): Include users whose gender is not determined. @@ -244,7 +244,7 @@ class HouseholdIncomeDimension(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - income_ranges (MutableSequence[google.ads.googleads.v19.enums.types.IncomeRangeTypeEnum.IncomeRangeType]): + income_ranges (MutableSequence[google.ads.googleads.v23.enums.types.IncomeRangeTypeEnum.IncomeRangeType]): Included household income demographic segments. include_undetermined (bool): @@ -274,7 +274,7 @@ class ParentalStatusDimension(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - parental_statuses (MutableSequence[google.ads.googleads.v19.enums.types.ParentalStatusTypeEnum.ParentalStatusType]): + parental_statuses (MutableSequence[google.ads.googleads.v23.enums.types.ParentalStatusTypeEnum.ParentalStatusType]): Included parental status demographic segments. include_undetermined (bool): @@ -303,7 +303,7 @@ class AudienceSegmentDimension(proto.Message): audience segments. Attributes: - segments (MutableSequence[google.ads.googleads.v19.common.types.AudienceSegment]): + segments (MutableSequence[google.ads.googleads.v23.common.types.AudienceSegment]): Included audience segments. Users are included if they belong to at least one segment. """ @@ -326,23 +326,23 @@ class AudienceSegment(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - user_list (google.ads.googleads.v19.common.types.UserListSegment): + user_list (google.ads.googleads.v23.common.types.UserListSegment): User list segment. This field is a member of `oneof`_ ``segment``. - user_interest (google.ads.googleads.v19.common.types.UserInterestSegment): + user_interest (google.ads.googleads.v23.common.types.UserInterestSegment): Affinity or In-market segment. This field is a member of `oneof`_ ``segment``. - life_event (google.ads.googleads.v19.common.types.LifeEventSegment): + life_event (google.ads.googleads.v23.common.types.LifeEventSegment): Live-event audience segment. This field is a member of `oneof`_ ``segment``. - detailed_demographic (google.ads.googleads.v19.common.types.DetailedDemographicSegment): + detailed_demographic (google.ads.googleads.v23.common.types.DetailedDemographicSegment): Detailed demographic segment. This field is a member of `oneof`_ ``segment``. - custom_audience (google.ads.googleads.v19.common.types.CustomAudienceSegment): + custom_audience (google.ads.googleads.v23.common.types.CustomAudienceSegment): Custom audience segment. This field is a member of `oneof`_ ``segment``. diff --git a/google/ads/googleads/v19/common/types/bidding.py b/google/ads/googleads/v23/common/types/bidding.py similarity index 86% rename from google/ads/googleads/v19/common/types/bidding.py rename to google/ads/googleads/v23/common/types/bidding.py index 4d6ec4136..ce224502e 100644 --- a/google/ads/googleads/v19/common/types/bidding.py +++ b/google/ads/googleads/v23/common/types/bidding.py @@ -18,19 +18,19 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import fixed_cpm_goal -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import fixed_cpm_goal +from google.ads.googleads.v23.enums.types import ( fixed_cpm_target_frequency_time_unit, ) -from google.ads.googleads.v19.enums.types import target_frequency_time_unit -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import target_frequency_time_unit +from google.ads.googleads.v23.enums.types import ( target_impression_share_location, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "Commission", "EnhancedCpc", @@ -50,6 +50,7 @@ "FixedCpm", "FixedCpmTargetFrequencyGoalInfo", "TargetCpv", + "TargetCpc", }, ) @@ -174,6 +175,9 @@ class MaximizeConversionValue(proto.Message): r"""An automated bidding strategy to help get the most conversion value for your campaigns while spending your budget. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + Attributes: target_roas (float): The target return on ad spend (ROAS) option. @@ -194,6 +198,16 @@ class MaximizeConversionValue(proto.Message): strategy. The limit applies to all keywords managed by the strategy. Mutable for portfolio bidding strategies only. + target_roas_tolerance_percent_millis (int): + The percent of ROAS(return on advertising + spend) degradation tolerance allowed to increase + traffic diversity and conversion volume, + specified in millis (for example, 10,000 = 10%). + A value of 10,000 means that the advertiser can + expect ROAS degradation of up to 10% of the + specified target ROAS. + + This field is a member of `oneof`_ ``_target_roas_tolerance_percent_millis``. """ target_roas: float = proto.Field( @@ -208,6 +222,11 @@ class MaximizeConversionValue(proto.Message): proto.INT64, number=4, ) + target_roas_tolerance_percent_millis: int = proto.Field( + proto.INT64, + number=5, + optional=True, + ) class TargetCpa(proto.Message): @@ -268,7 +287,7 @@ class TargetCpm(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - target_frequency_goal (google.ads.googleads.v19.common.types.TargetCpmTargetFrequencyGoal): + target_frequency_goal (google.ads.googleads.v23.common.types.TargetCpmTargetFrequencyGoal): Target Frequency bidding goal details. This field is a member of `oneof`_ ``goal``. @@ -289,7 +308,7 @@ class TargetCpmTargetFrequencyGoal(proto.Message): target_count (int): Target Frequency count representing how many times you want to reach a single user. - time_unit (google.ads.googleads.v19.enums.types.TargetFrequencyTimeUnitEnum.TargetFrequencyTimeUnit): + time_unit (google.ads.googleads.v23.enums.types.TargetFrequencyTimeUnitEnum.TargetFrequencyTimeUnit): Time window expressing the period over which you want to reach the specified target_count. """ @@ -316,7 +335,7 @@ class TargetImpressionShare(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - location (google.ads.googleads.v19.enums.types.TargetImpressionShareLocationEnum.TargetImpressionShareLocation): + location (google.ads.googleads.v23.enums.types.TargetImpressionShareLocationEnum.TargetImpressionShareLocation): The targeted location on the search results page. location_fraction_micros (int): @@ -381,6 +400,17 @@ class TargetRoas(proto.Message): for portfolio bid strategies. This field is a member of `oneof`_ ``_cpc_bid_floor_micros``. + target_roas_tolerance_percent_millis (int): + The percent of ROAS(return on advertising + spend) degradation tolerance allowed to increase + traffic diversity and conversion volume, + specified in millis (for example, 10,000 = 10%). + A value of 10,000 means that the advertiser can + expect ROAS degradation of up to 10% of the + specified target ROAS. This field is only + mutable for portfolio bidding strategies. + + This field is a member of `oneof`_ ``_target_roas_tolerance_percent_millis``. """ target_roas: float = proto.Field( @@ -398,6 +428,11 @@ class TargetRoas(proto.Message): number=6, optional=True, ) + target_roas_tolerance_percent_millis: int = proto.Field( + proto.INT64, + number=7, + optional=True, + ) class TargetSpend(proto.Message): @@ -484,10 +519,10 @@ class FixedCpm(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - goal (google.ads.googleads.v19.enums.types.FixedCpmGoalEnum.FixedCpmGoal): + goal (google.ads.googleads.v23.enums.types.FixedCpmGoalEnum.FixedCpmGoal): Fixed CPM bidding goal. Determines the exact bidding optimization parameters. - target_frequency_info (google.ads.googleads.v19.common.types.FixedCpmTargetFrequencyGoalInfo): + target_frequency_info (google.ads.googleads.v23.common.types.FixedCpmTargetFrequencyGoalInfo): Target frequency bidding goal details. This field is a member of `oneof`_ ``goal_info``. @@ -516,7 +551,7 @@ class FixedCpmTargetFrequencyGoalInfo(proto.Message): Target frequency count represents the number of times an advertiser wants to show the ad to target a single user. - time_unit (google.ads.googleads.v19.enums.types.FixedCpmTargetFrequencyTimeUnitEnum.FixedCpmTargetFrequencyTimeUnit): + time_unit (google.ads.googleads.v23.enums.types.FixedCpmTargetFrequencyTimeUnitEnum.FixedCpmTargetFrequencyTimeUnit): Time window expressing the period over which you want to reach the specified target_count. """ @@ -542,4 +577,23 @@ class TargetCpv(proto.Message): """ +class TargetCpc(proto.Message): + r"""An automated bidding strategy that sets bids to help get as + many clicks as possible at the target cost-per-click (CPC) you + set. + + Attributes: + target_cpc_micros (int): + Average CPC target. + This target should be greater than or equal to + minimum billable unit based on the currency for + the account. + """ + + target_cpc_micros: int = proto.Field( + proto.INT64, + number=1, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/common/types/campaign_goal_settings.py b/google/ads/googleads/v23/common/types/campaign_goal_settings.py new file mode 100644 index 000000000..e5d37edc8 --- /dev/null +++ b/google/ads/googleads/v23/common/types/campaign_goal_settings.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import goal_common +from google.ads.googleads.v23.enums.types import ( + customer_lifecycle_optimization_mode, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", + manifest={ + "CampaignGoalSettings", + }, +) + + +class CampaignGoalSettings(proto.Message): + r"""Campaign Goal settings.""" + + class CampaignRetentionGoalSettings(proto.Message): + r"""Retention campaign goal settings. + + Attributes: + value_settings_override (google.ads.googleads.v23.common.types.CustomerLifecycleOptimizationValueSettings): + Retention goal campaign specific value + settings. + target_option (google.ads.googleads.v23.enums.types.CustomerLifecycleOptimizationModeEnum.CustomerLifecycleOptimizationMode): + Retention goal optimization mode for this campaign. + + Defaults to TARGET_ALL. Only customers on the allowlist can + set target_option. + """ + + value_settings_override: ( + goal_common.CustomerLifecycleOptimizationValueSettings + ) = proto.Field( + proto.MESSAGE, + number=1, + message=goal_common.CustomerLifecycleOptimizationValueSettings, + ) + target_option: ( + customer_lifecycle_optimization_mode.CustomerLifecycleOptimizationModeEnum.CustomerLifecycleOptimizationMode + ) = proto.Field( + proto.ENUM, + number=2, + enum=customer_lifecycle_optimization_mode.CustomerLifecycleOptimizationModeEnum.CustomerLifecycleOptimizationMode, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/common/types/click_location.py b/google/ads/googleads/v23/common/types/click_location.py similarity index 96% rename from google/ads/googleads/v19/common/types/click_location.py rename to google/ads/googleads/v23/common/types/click_location.py index d19d848b8..e2cdfd6b5 100644 --- a/google/ads/googleads/v19/common/types/click_location.py +++ b/google/ads/googleads/v23/common/types/click_location.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "ClickLocation", }, diff --git a/google/ads/googleads/v19/common/types/consent.py b/google/ads/googleads/v23/common/types/consent.py similarity index 84% rename from google/ads/googleads/v19/common/types/consent.py rename to google/ads/googleads/v23/common/types/consent.py index 3be587800..49dd298f9 100644 --- a/google/ads/googleads/v19/common/types/consent.py +++ b/google/ads/googleads/v23/common/types/consent.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import consent_status +from google.ads.googleads.v23.enums.types import consent_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "Consent", }, @@ -34,9 +34,9 @@ class Consent(proto.Message): r"""Consent Attributes: - ad_user_data (google.ads.googleads.v19.enums.types.ConsentStatusEnum.ConsentStatus): + ad_user_data (google.ads.googleads.v23.enums.types.ConsentStatusEnum.ConsentStatus): This represents consent for ad user data. - ad_personalization (google.ads.googleads.v19.enums.types.ConsentStatusEnum.ConsentStatus): + ad_personalization (google.ads.googleads.v23.enums.types.ConsentStatusEnum.ConsentStatus): This represents consent for ad personalization. This can only be set for OfflineUserDataJobService and UserDataService. diff --git a/google/ads/googleads/v19/common/types/criteria.py b/google/ads/googleads/v23/common/types/criteria.py similarity index 84% rename from google/ads/googleads/v19/common/types/criteria.py rename to google/ads/googleads/v23/common/types/criteria.py index e2e0920b7..1cb6b34bb 100644 --- a/google/ads/googleads/v19/common/types/criteria.py +++ b/google/ads/googleads/v23/common/types/criteria.py @@ -19,42 +19,42 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import age_range_type -from google.ads.googleads.v19.enums.types import app_payment_model_type -from google.ads.googleads.v19.enums.types import brand_request_rejection_reason -from google.ads.googleads.v19.enums.types import brand_state -from google.ads.googleads.v19.enums.types import content_label_type -from google.ads.googleads.v19.enums.types import day_of_week as gage_day_of_week -from google.ads.googleads.v19.enums.types import device -from google.ads.googleads.v19.enums.types import gender_type -from google.ads.googleads.v19.enums.types import hotel_date_selection_type -from google.ads.googleads.v19.enums.types import income_range_type -from google.ads.googleads.v19.enums.types import interaction_type -from google.ads.googleads.v19.enums.types import keyword_match_type -from google.ads.googleads.v19.enums.types import listing_group_type -from google.ads.googleads.v19.enums.types import location_group_radius_units -from google.ads.googleads.v19.enums.types import minute_of_hour -from google.ads.googleads.v19.enums.types import parental_status_type -from google.ads.googleads.v19.enums.types import product_category_level -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import age_range_type +from google.ads.googleads.v23.enums.types import app_payment_model_type +from google.ads.googleads.v23.enums.types import brand_request_rejection_reason +from google.ads.googleads.v23.enums.types import brand_state +from google.ads.googleads.v23.enums.types import content_label_type +from google.ads.googleads.v23.enums.types import day_of_week as gage_day_of_week +from google.ads.googleads.v23.enums.types import device +from google.ads.googleads.v23.enums.types import gender_type +from google.ads.googleads.v23.enums.types import hotel_date_selection_type +from google.ads.googleads.v23.enums.types import income_range_type +from google.ads.googleads.v23.enums.types import interaction_type +from google.ads.googleads.v23.enums.types import keyword_match_type +from google.ads.googleads.v23.enums.types import listing_group_type +from google.ads.googleads.v23.enums.types import location_group_radius_units +from google.ads.googleads.v23.enums.types import minute_of_hour +from google.ads.googleads.v23.enums.types import parental_status_type +from google.ads.googleads.v23.enums.types import product_category_level +from google.ads.googleads.v23.enums.types import ( product_channel as gage_product_channel, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( product_channel_exclusivity as gage_product_channel_exclusivity, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( product_condition as gage_product_condition, ) -from google.ads.googleads.v19.enums.types import product_custom_attribute_index -from google.ads.googleads.v19.enums.types import product_type_level -from google.ads.googleads.v19.enums.types import proximity_radius_units -from google.ads.googleads.v19.enums.types import webpage_condition_operand -from google.ads.googleads.v19.enums.types import webpage_condition_operator +from google.ads.googleads.v23.enums.types import product_custom_attribute_index +from google.ads.googleads.v23.enums.types import product_type_level +from google.ads.googleads.v23.enums.types import proximity_radius_units +from google.ads.googleads.v23.enums.types import webpage_condition_operand +from google.ads.googleads.v23.enums.types import webpage_condition_operator __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "KeywordInfo", "PlacementInfo", @@ -115,6 +115,7 @@ "UserInterestInfo", "WebpageInfo", "WebpageConditionInfo", + "WebpageListInfo", "WebpageSampleInfo", "OperatingSystemVersionInfo", "AppPaymentModelInfo", @@ -130,6 +131,12 @@ "SearchThemeInfo", "BrandInfo", "BrandListInfo", + "LifeEventInfo", + "ExtendedDemographicInfo", + "VideoLineupInfo", + "PlacementListInfo", + "VerticalAdsItemGroupRuleListInfo", + "VerticalAdsItemGroupRuleInfo", }, ) @@ -145,7 +152,7 @@ class KeywordInfo(proto.Message): characters and 10 words). This field is a member of `oneof`_ ``_text``. - match_type (google.ads.googleads.v19.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + match_type (google.ads.googleads.v23.enums.types.KeywordMatchTypeEnum.KeywordMatchType): The match type of the keyword. """ @@ -298,7 +305,7 @@ class DeviceInfo(proto.Message): r"""A device criterion. Attributes: - type_ (google.ads.googleads.v19.enums.types.DeviceEnum.Device): + type_ (google.ads.googleads.v23.enums.types.DeviceEnum.Device): Type of the device. """ @@ -315,9 +322,9 @@ class ListingGroupInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - type_ (google.ads.googleads.v19.enums.types.ListingGroupTypeEnum.ListingGroupType): + type_ (google.ads.googleads.v23.enums.types.ListingGroupTypeEnum.ListingGroupType): Type of the listing group. - case_value (google.ads.googleads.v19.common.types.ListingDimensionInfo): + case_value (google.ads.googleads.v23.common.types.ListingDimensionInfo): Dimension value with which this listing group is refining its parent. Undefined for the root group. @@ -327,7 +334,7 @@ class ListingGroupInfo(proto.Message): the root group. This field is a member of `oneof`_ ``_parent_ad_group_criterion``. - path (google.ads.googleads.v19.common.types.ListingDimensionPath): + path (google.ads.googleads.v23.common.types.ListingDimensionPath): The path of dimensions defining this listing group. @@ -363,7 +370,7 @@ class ListingDimensionPath(proto.Message): r"""The path of dimensions defining a listing group. Attributes: - dimensions (MutableSequence[google.ads.googleads.v19.common.types.ListingDimensionInfo]): + dimensions (MutableSequence[google.ads.googleads.v23.common.types.ListingDimensionInfo]): The complete path of dimensions through the listing group hierarchy, from the root (excluding the root itself) to this listing @@ -381,7 +388,7 @@ class ListingScopeInfo(proto.Message): r"""A listing scope criterion. Attributes: - dimensions (MutableSequence[google.ads.googleads.v19.common.types.ListingDimensionInfo]): + dimensions (MutableSequence[google.ads.googleads.v23.common.types.ListingDimensionInfo]): Scope of the campaign criterion. """ @@ -403,108 +410,108 @@ class ListingDimensionInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - hotel_id (google.ads.googleads.v19.common.types.HotelIdInfo): + hotel_id (google.ads.googleads.v23.common.types.HotelIdInfo): Advertiser-specific hotel ID. This field is a member of `oneof`_ ``dimension``. - hotel_class (google.ads.googleads.v19.common.types.HotelClassInfo): + hotel_class (google.ads.googleads.v23.common.types.HotelClassInfo): Class of the hotel as a number of stars 1 to 5. This field is a member of `oneof`_ ``dimension``. - hotel_country_region (google.ads.googleads.v19.common.types.HotelCountryRegionInfo): + hotel_country_region (google.ads.googleads.v23.common.types.HotelCountryRegionInfo): Country or Region the hotel is located in. This field is a member of `oneof`_ ``dimension``. - hotel_state (google.ads.googleads.v19.common.types.HotelStateInfo): + hotel_state (google.ads.googleads.v23.common.types.HotelStateInfo): State the hotel is located in. This field is a member of `oneof`_ ``dimension``. - hotel_city (google.ads.googleads.v19.common.types.HotelCityInfo): + hotel_city (google.ads.googleads.v23.common.types.HotelCityInfo): City the hotel is located in. This field is a member of `oneof`_ ``dimension``. - product_category (google.ads.googleads.v19.common.types.ProductCategoryInfo): + product_category (google.ads.googleads.v23.common.types.ProductCategoryInfo): Category of a product offer. This field is a member of `oneof`_ ``dimension``. - product_brand (google.ads.googleads.v19.common.types.ProductBrandInfo): + product_brand (google.ads.googleads.v23.common.types.ProductBrandInfo): Brand of a product offer. This field is a member of `oneof`_ ``dimension``. - product_channel (google.ads.googleads.v19.common.types.ProductChannelInfo): + product_channel (google.ads.googleads.v23.common.types.ProductChannelInfo): Locality of a product offer. This field is a member of `oneof`_ ``dimension``. - product_channel_exclusivity (google.ads.googleads.v19.common.types.ProductChannelExclusivityInfo): + product_channel_exclusivity (google.ads.googleads.v23.common.types.ProductChannelExclusivityInfo): Availability of a product offer. This field is a member of `oneof`_ ``dimension``. - product_condition (google.ads.googleads.v19.common.types.ProductConditionInfo): + product_condition (google.ads.googleads.v23.common.types.ProductConditionInfo): Condition of a product offer. This field is a member of `oneof`_ ``dimension``. - product_custom_attribute (google.ads.googleads.v19.common.types.ProductCustomAttributeInfo): + product_custom_attribute (google.ads.googleads.v23.common.types.ProductCustomAttributeInfo): Custom attribute of a product offer. This field is a member of `oneof`_ ``dimension``. - product_item_id (google.ads.googleads.v19.common.types.ProductItemIdInfo): + product_item_id (google.ads.googleads.v23.common.types.ProductItemIdInfo): Item id of a product offer. This field is a member of `oneof`_ ``dimension``. - product_type (google.ads.googleads.v19.common.types.ProductTypeInfo): + product_type (google.ads.googleads.v23.common.types.ProductTypeInfo): Type of a product offer. This field is a member of `oneof`_ ``dimension``. - product_grouping (google.ads.googleads.v19.common.types.ProductGroupingInfo): + product_grouping (google.ads.googleads.v23.common.types.ProductGroupingInfo): Grouping of a product offer. This listing dimension is deprecated and it is supported only in Display campaigns. This field is a member of `oneof`_ ``dimension``. - product_labels (google.ads.googleads.v19.common.types.ProductLabelsInfo): + product_labels (google.ads.googleads.v23.common.types.ProductLabelsInfo): Labels of a product offer. This listing dimension is deprecated and it is supported only in Display campaigns. This field is a member of `oneof`_ ``dimension``. - product_legacy_condition (google.ads.googleads.v19.common.types.ProductLegacyConditionInfo): + product_legacy_condition (google.ads.googleads.v23.common.types.ProductLegacyConditionInfo): Legacy condition of a product offer. This listing dimension is deprecated and it is supported only in Display campaigns. This field is a member of `oneof`_ ``dimension``. - product_type_full (google.ads.googleads.v19.common.types.ProductTypeFullInfo): + product_type_full (google.ads.googleads.v23.common.types.ProductTypeFullInfo): Full type of a product offer. This listing dimension is deprecated and it is supported only in Display campaigns. This field is a member of `oneof`_ ``dimension``. - activity_id (google.ads.googleads.v19.common.types.ActivityIdInfo): + activity_id (google.ads.googleads.v23.common.types.ActivityIdInfo): Advertiser-specific activity ID. This field is a member of `oneof`_ ``dimension``. - activity_rating (google.ads.googleads.v19.common.types.ActivityRatingInfo): + activity_rating (google.ads.googleads.v23.common.types.ActivityRatingInfo): Rating of the activity as a number 1 to 5, where 5 is the best. This field is a member of `oneof`_ ``dimension``. - activity_country (google.ads.googleads.v19.common.types.ActivityCountryInfo): + activity_country (google.ads.googleads.v23.common.types.ActivityCountryInfo): The country where the travel activity is available. This field is a member of `oneof`_ ``dimension``. - activity_state (google.ads.googleads.v19.common.types.ActivityStateInfo): + activity_state (google.ads.googleads.v23.common.types.ActivityStateInfo): The state where the travel activity is available. This field is a member of `oneof`_ ``dimension``. - activity_city (google.ads.googleads.v19.common.types.ActivityCityInfo): + activity_city (google.ads.googleads.v23.common.types.ActivityCityInfo): The city where the travel activity is available. This field is a member of `oneof`_ ``dimension``. - unknown_listing_dimension (google.ads.googleads.v19.common.types.UnknownListingDimensionInfo): + unknown_listing_dimension (google.ads.googleads.v23.common.types.UnknownListingDimensionInfo): Unknown dimension. Set when no other listing dimension is set. @@ -760,7 +767,7 @@ class ProductCategoryInfo(proto.Message): https://support.google.com/merchants/answer/6324436 This field is a member of `oneof`_ ``_category_id``. - level (google.ads.googleads.v19.enums.types.ProductCategoryLevelEnum.ProductCategoryLevel): + level (google.ads.googleads.v23.enums.types.ProductCategoryLevelEnum.ProductCategoryLevel): Level of the product category. """ @@ -801,7 +808,7 @@ class ProductChannelInfo(proto.Message): r"""Locality of a product offer. Attributes: - channel (google.ads.googleads.v19.enums.types.ProductChannelEnum.ProductChannel): + channel (google.ads.googleads.v23.enums.types.ProductChannelEnum.ProductChannel): Value of the locality. """ @@ -818,7 +825,7 @@ class ProductChannelExclusivityInfo(proto.Message): r"""Availability of a product offer. Attributes: - channel_exclusivity (google.ads.googleads.v19.enums.types.ProductChannelExclusivityEnum.ProductChannelExclusivity): + channel_exclusivity (google.ads.googleads.v23.enums.types.ProductChannelExclusivityEnum.ProductChannelExclusivity): Value of the availability. """ @@ -835,7 +842,7 @@ class ProductConditionInfo(proto.Message): r"""Condition of a product offer. Attributes: - condition (google.ads.googleads.v19.enums.types.ProductConditionEnum.ProductCondition): + condition (google.ads.googleads.v23.enums.types.ProductConditionEnum.ProductCondition): Value of the condition. """ @@ -858,7 +865,7 @@ class ProductCustomAttributeInfo(proto.Message): String value of the product custom attribute. This field is a member of `oneof`_ ``_value``. - index (google.ads.googleads.v19.enums.types.ProductCustomAttributeIndexEnum.ProductCustomAttributeIndex): + index (google.ads.googleads.v23.enums.types.ProductCustomAttributeIndexEnum.ProductCustomAttributeIndex): Indicates the index of the custom attribute. """ @@ -905,7 +912,7 @@ class ProductTypeInfo(proto.Message): Value of the type. This field is a member of `oneof`_ ``_value``. - level (google.ads.googleads.v19.enums.types.ProductTypeLevelEnum.ProductTypeLevel): + level (google.ads.googleads.v23.enums.types.ProductTypeLevelEnum.ProductTypeLevel): Level of the type. """ @@ -1016,7 +1023,7 @@ class HotelDateSelectionTypeInfo(proto.Message): selected). Attributes: - type_ (google.ads.googleads.v19.enums.types.HotelDateSelectionTypeEnum.HotelDateSelectionType): + type_ (google.ads.googleads.v23.enums.types.HotelDateSelectionTypeEnum.HotelDateSelectionType): Type of the hotel date selection """ @@ -1113,7 +1120,7 @@ class HotelCheckInDayInfo(proto.Message): r"""Criterion for day of the week the booking is for. Attributes: - day_of_week (google.ads.googleads.v19.enums.types.DayOfWeekEnum.DayOfWeek): + day_of_week (google.ads.googleads.v23.enums.types.DayOfWeekEnum.DayOfWeek): The day of the week. """ @@ -1228,7 +1235,7 @@ class InteractionTypeInfo(proto.Message): r"""Criterion for Interaction Type. Attributes: - type_ (google.ads.googleads.v19.enums.types.InteractionTypeEnum.InteractionType): + type_ (google.ads.googleads.v23.enums.types.InteractionTypeEnum.InteractionType): The interaction type. """ @@ -1251,12 +1258,12 @@ class AdScheduleInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - start_minute (google.ads.googleads.v19.enums.types.MinuteOfHourEnum.MinuteOfHour): + start_minute (google.ads.googleads.v23.enums.types.MinuteOfHourEnum.MinuteOfHour): Minutes after the start hour at which this schedule starts. This field is required for CREATE operations and is prohibited on UPDATE operations. - end_minute (google.ads.googleads.v19.enums.types.MinuteOfHourEnum.MinuteOfHour): + end_minute (google.ads.googleads.v23.enums.types.MinuteOfHourEnum.MinuteOfHour): Minutes after the end hour at which this schedule ends. The schedule is exclusive of the end minute. @@ -1280,7 +1287,7 @@ class AdScheduleInfo(proto.Message): is prohibited on UPDATE operations. This field is a member of `oneof`_ ``_end_hour``. - day_of_week (google.ads.googleads.v19.enums.types.DayOfWeekEnum.DayOfWeek): + day_of_week (google.ads.googleads.v23.enums.types.DayOfWeekEnum.DayOfWeek): Day of the week the schedule applies to. This field is required for CREATE operations and @@ -1318,7 +1325,7 @@ class AgeRangeInfo(proto.Message): r"""An age range criterion. Attributes: - type_ (google.ads.googleads.v19.enums.types.AgeRangeTypeEnum.AgeRangeType): + type_ (google.ads.googleads.v23.enums.types.AgeRangeTypeEnum.AgeRangeType): Type of the age range. """ @@ -1333,7 +1340,7 @@ class GenderInfo(proto.Message): r"""A gender criterion. Attributes: - type_ (google.ads.googleads.v19.enums.types.GenderTypeEnum.GenderType): + type_ (google.ads.googleads.v23.enums.types.GenderTypeEnum.GenderType): Type of the gender. """ @@ -1348,7 +1355,7 @@ class IncomeRangeInfo(proto.Message): r"""An income range criterion. Attributes: - type_ (google.ads.googleads.v19.enums.types.IncomeRangeTypeEnum.IncomeRangeType): + type_ (google.ads.googleads.v23.enums.types.IncomeRangeTypeEnum.IncomeRangeType): Type of the income range. """ @@ -1363,7 +1370,7 @@ class ParentalStatusInfo(proto.Message): r"""A parental status criterion. Attributes: - type_ (google.ads.googleads.v19.enums.types.ParentalStatusTypeEnum.ParentalStatusType): + type_ (google.ads.googleads.v23.enums.types.ParentalStatusTypeEnum.ParentalStatusType): Type of the parental status. """ @@ -1451,16 +1458,16 @@ class ProximityInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - geo_point (google.ads.googleads.v19.common.types.GeoPointInfo): + geo_point (google.ads.googleads.v23.common.types.GeoPointInfo): Latitude and longitude. radius (float): The radius of the proximity. This field is a member of `oneof`_ ``_radius``. - radius_units (google.ads.googleads.v19.enums.types.ProximityRadiusUnitsEnum.ProximityRadiusUnits): + radius_units (google.ads.googleads.v23.enums.types.ProximityRadiusUnitsEnum.ProximityRadiusUnits): The unit of measurement of the radius. Default is KILOMETERS. - address (google.ads.googleads.v19.common.types.AddressInfo): + address (google.ads.googleads.v23.common.types.AddressInfo): Full address. """ @@ -1643,19 +1650,37 @@ class LanguageInfo(proto.Message): class IpBlockInfo(proto.Message): - r"""An IpBlock criterion used for IP exclusions. We allow: + r"""An IpBlock criterion used for excluding IP addresses. - - IPv4 and IPv6 addresses - - individual addresses (192.168.0.1) - - masks for individual addresses (192.168.0.1/32) - - masks for Class C networks (192.168.0.1/24) + We support excluding individual IP addresses or CIDR blocks. Create + one IpBlockInfo criterion for each individual IP address or CIDR + block you want to exclude. You can exclude up to 500 IP addresses + per campaign. For more details, see `Exclude IP + addresses `__. + + IPv4 examples: + + - Individual address: 192.168.0.1 + + - Individual address as CIDR block: 192.168.0.1/32 + + - CIDR block: 192.168.0.0/24 + + IPv6 examples: + + - Individual address: 2001:db8:a0b:12f0::1 + + - Individual address as CIDR block: 2001:db8:a0b:12f0::1/128 + + - CIDR block: 2001:db8::/48 .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: ip_address (str): - The IP address of this IP block. + The IP address or the CIDR block to be + excluded. This field is a member of `oneof`_ ``_ip_address``. """ @@ -1671,7 +1696,7 @@ class ContentLabelInfo(proto.Message): r"""Content Label for category exclusion. Attributes: - type_ (google.ads.googleads.v19.enums.types.ContentLabelTypeEnum.ContentLabelType): + type_ (google.ads.googleads.v23.enums.types.ContentLabelTypeEnum.ContentLabelType): Content label type, required for CREATE operations. """ @@ -1741,7 +1766,7 @@ class WebpageInfo(proto.Message): is prohibited on UPDATE operations. This field is a member of `oneof`_ ``_criterion_name``. - conditions (MutableSequence[google.ads.googleads.v19.common.types.WebpageConditionInfo]): + conditions (MutableSequence[google.ads.googleads.v23.common.types.WebpageConditionInfo]): Conditions, or logical expressions, for webpage targeting. The list of webpage targeting conditions are and-ed together when evaluated @@ -1759,7 +1784,7 @@ class WebpageInfo(proto.Message): campaign. For instance, when coverage returns as 1, it indicates it has 100% coverage. This field is read-only. - sample (google.ads.googleads.v19.common.types.WebpageSampleInfo): + sample (google.ads.googleads.v23.common.types.WebpageSampleInfo): List of sample urls that match the website target. This field is read-only. """ @@ -1793,9 +1818,9 @@ class WebpageConditionInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - operand (google.ads.googleads.v19.enums.types.WebpageConditionOperandEnum.WebpageConditionOperand): + operand (google.ads.googleads.v23.enums.types.WebpageConditionOperandEnum.WebpageConditionOperand): Operand of webpage targeting condition. - operator (google.ads.googleads.v19.enums.types.WebpageConditionOperatorEnum.WebpageConditionOperator): + operator (google.ads.googleads.v23.enums.types.WebpageConditionOperatorEnum.WebpageConditionOperator): Operator of webpage targeting condition. argument (str): Argument of webpage targeting condition. @@ -1824,6 +1849,25 @@ class WebpageConditionInfo(proto.Message): ) +class WebpageListInfo(proto.Message): + r"""Represents a list of webpage criteria. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + shared_set (str): + Shared set resource name of the webpage list. + + This field is a member of `oneof`_ ``_shared_set``. + """ + + shared_set: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + + class WebpageSampleInfo(proto.Message): r"""List of sample urls that match the website target @@ -1862,7 +1906,7 @@ class AppPaymentModelInfo(proto.Message): r"""An app payment model criterion. Attributes: - type_ (google.ads.googleads.v19.enums.types.AppPaymentModelTypeEnum.AppPaymentModelType): + type_ (google.ads.googleads.v23.enums.types.AppPaymentModelTypeEnum.AppPaymentModelType): Type of the app payment model. """ @@ -1955,7 +1999,7 @@ class LocationGroupInfo(proto.Message): must be set in CREATE operations. This field is a member of `oneof`_ ``_radius``. - radius_units (google.ads.googleads.v19.enums.types.LocationGroupRadiusUnitsEnum.LocationGroupRadiusUnits): + radius_units (google.ads.googleads.v23.enums.types.LocationGroupRadiusUnitsEnum.LocationGroupRadiusUnits): Unit of the radius. Miles and meters are supported for geo target constants. Milli miles and meters are supported for feed item sets and @@ -2152,12 +2196,12 @@ class BrandInfo(proto.Message): Output only. The primary url of a brand. This field is a member of `oneof`_ ``_primary_url``. - rejection_reason (google.ads.googleads.v19.enums.types.BrandRequestRejectionReasonEnum.BrandRequestRejectionReason): + rejection_reason (google.ads.googleads.v23.enums.types.BrandRequestRejectionReasonEnum.BrandRequestRejectionReason): Output only. The rejection reason when a brand status is REJECTED. This field is a member of `oneof`_ ``_rejection_reason``. - status (google.ads.googleads.v19.enums.types.BrandStateEnum.BrandState): + status (google.ads.googleads.v23.enums.types.BrandStateEnum.BrandState): Output only. The status of a brand. This field is a member of `oneof`_ ``_status``. @@ -2216,4 +2260,173 @@ class BrandListInfo(proto.Message): ) +class LifeEventInfo(proto.Message): + r"""Represents a life event criterion. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + life_event_id (int): + Taxonomy id of the life event. + + This field is a member of `oneof`_ ``_life_event_id``. + """ + + life_event_id: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + + +class ExtendedDemographicInfo(proto.Message): + r"""Represents an extended demographic criterion. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + extended_demographic_id (int): + Taxonomy id of the extended demographic + group. + + This field is a member of `oneof`_ ``_extended_demographic_id``. + """ + + extended_demographic_id: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + + +class VideoLineupInfo(proto.Message): + r"""A Video lineup criterion. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + video_lineup_id (int): + ID for a Video lineup. Contact your Google + business development representative for details. + + This field is a member of `oneof`_ ``_video_lineup_id``. + """ + + video_lineup_id: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + + +class PlacementListInfo(proto.Message): + r"""A Placement List criterion. Represents a shared set + of placements that can be excluded at the account-level. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + shared_set (str): + The PlacementListInfo shared set resource + name. + + This field is a member of `oneof`_ ``_shared_set``. + """ + + shared_set: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + + +class VerticalAdsItemGroupRuleListInfo(proto.Message): + r"""A criterion for targeting a shared set of rules for item + groups in Vertical Ads (e.g., for hotel ads). + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + shared_set (str): + The shared set resource name of the vertical + ads item group rule list. + + This field is a member of `oneof`_ ``_shared_set``. + """ + + shared_set: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + + +class VerticalAdsItemGroupRuleInfo(proto.Message): + r"""A criterion to represent a single item group rule in Vertical + Ads. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + item_code (str): + The id specifying a particular Vertical Ad + listing. + + This field is a member of `oneof`_ ``dimension``. + country_criterion_id (str): + The resource name of the Geo Target Constant + for the country. + + This field is a member of `oneof`_ ``dimension``. + region_criterion_id (str): + The resource name of the Geo Target Constant + for the region. + + This field is a member of `oneof`_ ``dimension``. + city_criterion_id (str): + The resource name of the Geo Target Constant + for the city. + + This field is a member of `oneof`_ ``dimension``. + hotel_class (int): + Integer value specifying the class rating for + a hotel. Ranges from 1 to 5 stars. + + This field is a member of `oneof`_ ``dimension``. + """ + + item_code: str = proto.Field( + proto.STRING, + number=1, + oneof="dimension", + ) + country_criterion_id: str = proto.Field( + proto.STRING, + number=2, + oneof="dimension", + ) + region_criterion_id: str = proto.Field( + proto.STRING, + number=3, + oneof="dimension", + ) + city_criterion_id: str = proto.Field( + proto.STRING, + number=4, + oneof="dimension", + ) + hotel_class: int = proto.Field( + proto.INT64, + number=6, + oneof="dimension", + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/common/types/criterion_category_availability.py b/google/ads/googleads/v23/common/types/criterion_category_availability.py similarity index 90% rename from google/ads/googleads/v19/common/types/criterion_category_availability.py rename to google/ads/googleads/v23/common/types/criterion_category_availability.py index 631572deb..8c1e858fc 100644 --- a/google/ads/googleads/v19/common/types/criterion_category_availability.py +++ b/google/ads/googleads/v23/common/types/criterion_category_availability.py @@ -19,23 +19,23 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( advertising_channel_sub_type as gage_advertising_channel_sub_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( advertising_channel_type as gage_advertising_channel_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( criterion_category_channel_availability_mode, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( criterion_category_locale_availability_mode, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "CriterionCategoryAvailability", "CriterionCategoryChannelAvailability", @@ -49,10 +49,10 @@ class CriterionCategoryAvailability(proto.Message): channel. Attributes: - channel (google.ads.googleads.v19.common.types.CriterionCategoryChannelAvailability): + channel (google.ads.googleads.v23.common.types.CriterionCategoryChannelAvailability): Channel types and subtypes that are available to the category. - locale (MutableSequence[google.ads.googleads.v19.common.types.CriterionCategoryLocaleAvailability]): + locale (MutableSequence[google.ads.googleads.v23.common.types.CriterionCategoryLocaleAvailability]): Locales that are available to the category for the channel. """ @@ -79,7 +79,7 @@ class CriterionCategoryChannelAvailability(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - availability_mode (google.ads.googleads.v19.enums.types.CriterionCategoryChannelAvailabilityModeEnum.CriterionCategoryChannelAvailabilityMode): + availability_mode (google.ads.googleads.v23.enums.types.CriterionCategoryChannelAvailabilityModeEnum.CriterionCategoryChannelAvailabilityMode): Format of the channel availability. Can be ALL_CHANNELS (the rest of the fields will not be set), CHANNEL_TYPE (only advertising_channel_type type will be set, the category is @@ -87,9 +87,9 @@ class CriterionCategoryChannelAvailability(proto.Message): CHANNEL_TYPE_AND_SUBTYPES (advertising_channel_type, advertising_channel_sub_type, and include_default_channel_sub_type will all be set). - advertising_channel_type (google.ads.googleads.v19.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): + advertising_channel_type (google.ads.googleads.v23.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): Channel type the category is available to. - advertising_channel_sub_type (MutableSequence[google.ads.googleads.v19.enums.types.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType]): + advertising_channel_sub_type (MutableSequence[google.ads.googleads.v23.enums.types.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType]): Channel subtypes under the channel type the category is available to. include_default_channel_sub_type (bool): @@ -136,7 +136,7 @@ class CriterionCategoryLocaleAvailability(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - availability_mode (google.ads.googleads.v19.enums.types.CriterionCategoryLocaleAvailabilityModeEnum.CriterionCategoryLocaleAvailabilityMode): + availability_mode (google.ads.googleads.v23.enums.types.CriterionCategoryLocaleAvailabilityModeEnum.CriterionCategoryLocaleAvailabilityMode): Format of the locale availability. Can be LAUNCHED_TO_ALL (both country and language will be empty), COUNTRY (only country will be set), LANGUAGE (only language wil be set), diff --git a/google/ads/googleads/v19/common/types/custom_parameter.py b/google/ads/googleads/v23/common/types/custom_parameter.py similarity index 94% rename from google/ads/googleads/v19/common/types/custom_parameter.py rename to google/ads/googleads/v23/common/types/custom_parameter.py index cfac2247d..45e6d0f89 100644 --- a/google/ads/googleads/v19/common/types/custom_parameter.py +++ b/google/ads/googleads/v23/common/types/custom_parameter.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "CustomParameter", }, diff --git a/google/ads/googleads/v19/common/types/customizer_value.py b/google/ads/googleads/v23/common/types/customizer_value.py similarity index 89% rename from google/ads/googleads/v19/common/types/customizer_value.py rename to google/ads/googleads/v23/common/types/customizer_value.py index ee83d9bc0..50cbba5b2 100644 --- a/google/ads/googleads/v19/common/types/customizer_value.py +++ b/google/ads/googleads/v23/common/types/customizer_value.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import customizer_attribute_type +from google.ads.googleads.v23.enums.types import customizer_attribute_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "CustomizerValue", }, @@ -35,7 +35,7 @@ class CustomizerValue(proto.Message): entities like CustomerCustomizer, CampaignCustomizer, etc. Attributes: - type_ (google.ads.googleads.v19.enums.types.CustomizerAttributeTypeEnum.CustomizerAttributeType): + type_ (google.ads.googleads.v23.enums.types.CustomizerAttributeTypeEnum.CustomizerAttributeType): Required. The data type for the customizer value. It must match the attribute type. The string_value content must match the constraints associated with the type. diff --git a/google/ads/googleads/v19/common/types/dates.py b/google/ads/googleads/v23/common/types/dates.py similarity index 88% rename from google/ads/googleads/v19/common/types/dates.py rename to google/ads/googleads/v23/common/types/dates.py index f0b233c0d..dfb6be366 100644 --- a/google/ads/googleads/v19/common/types/dates.py +++ b/google/ads/googleads/v23/common/types/dates.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import month_of_year +from google.ads.googleads.v23.enums.types import month_of_year __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "DateRange", "YearMonthRange", @@ -68,9 +68,9 @@ class YearMonthRange(proto.Message): 2020, Jan 2020). Attributes: - start (google.ads.googleads.v19.common.types.YearMonth): + start (google.ads.googleads.v23.common.types.YearMonth): The inclusive start year month. - end (google.ads.googleads.v19.common.types.YearMonth): + end (google.ads.googleads.v23.common.types.YearMonth): The inclusive end year month. """ @@ -92,7 +92,7 @@ class YearMonth(proto.Message): Attributes: year (int): The year (for example, 2020). - month (google.ads.googleads.v19.enums.types.MonthOfYearEnum.MonthOfYear): + month (google.ads.googleads.v23.enums.types.MonthOfYearEnum.MonthOfYear): The month of the year. (for example, FEBRUARY). """ diff --git a/google/ads/googleads/v19/common/types/extensions.py b/google/ads/googleads/v23/common/types/extensions.py similarity index 95% rename from google/ads/googleads/v19/common/types/extensions.py rename to google/ads/googleads/v23/common/types/extensions.py index 9d210fb42..7ffdad665 100644 --- a/google/ads/googleads/v19/common/types/extensions.py +++ b/google/ads/googleads/v23/common/types/extensions.py @@ -19,15 +19,15 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import custom_parameter -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import custom_parameter +from google.ads.googleads.v23.enums.types import ( call_conversion_reporting_state as gage_call_conversion_reporting_state, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "CallFeedItem", "CalloutFeedItem", @@ -71,7 +71,7 @@ class CallFeedItem(proto.Message): Optional. This field is a member of `oneof`_ ``_call_conversion_tracking_disabled``. - call_conversion_reporting_state (google.ads.googleads.v19.enums.types.CallConversionReportingStateEnum.CallConversionReportingState): + call_conversion_reporting_state (google.ads.googleads.v23.enums.types.CallConversionReportingStateEnum.CallConversionReportingState): Enum value that indicates whether this call extension uses its own call conversion setting (or just have call conversion disabled), or @@ -169,7 +169,7 @@ class SitelinkFeedItem(proto.Message): URL template for constructing a tracking URL. This field is a member of `oneof`_ ``_tracking_url_template``. - url_custom_parameters (MutableSequence[google.ads.googleads.v19.common.types.CustomParameter]): + url_custom_parameters (MutableSequence[google.ads.googleads.v23.common.types.CustomParameter]): A list of mappings to be used for substituting URL custom parameter tags in the tracking_url_template, final_urls, and/or final_mobile_urls. diff --git a/google/ads/googleads/v19/common/types/feed_common.py b/google/ads/googleads/v23/common/types/feed_common.py similarity index 94% rename from google/ads/googleads/v19/common/types/feed_common.py rename to google/ads/googleads/v23/common/types/feed_common.py index c71af7c52..442eac641 100644 --- a/google/ads/googleads/v19/common/types/feed_common.py +++ b/google/ads/googleads/v23/common/types/feed_common.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "Money", }, diff --git a/google/ads/googleads/v19/common/types/final_app_url.py b/google/ads/googleads/v23/common/types/final_app_url.py similarity index 90% rename from google/ads/googleads/v19/common/types/final_app_url.py rename to google/ads/googleads/v23/common/types/final_app_url.py index 07a8e8f58..b05b20d83 100644 --- a/google/ads/googleads/v19/common/types/final_app_url.py +++ b/google/ads/googleads/v23/common/types/final_app_url.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import app_url_operating_system_type +from google.ads.googleads.v23.enums.types import app_url_operating_system_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "FinalAppUrl", }, @@ -38,7 +38,7 @@ class FinalAppUrl(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - os_type (google.ads.googleads.v19.enums.types.AppUrlOperatingSystemTypeEnum.AppUrlOperatingSystemType): + os_type (google.ads.googleads.v23.enums.types.AppUrlOperatingSystemTypeEnum.AppUrlOperatingSystemType): The operating system targeted by this URL. Required. url (str): diff --git a/google/ads/googleads/v19/common/types/frequency_cap.py b/google/ads/googleads/v23/common/types/frequency_cap.py similarity index 86% rename from google/ads/googleads/v19/common/types/frequency_cap.py rename to google/ads/googleads/v23/common/types/frequency_cap.py index 3557085f1..aa3d4482e 100644 --- a/google/ads/googleads/v19/common/types/frequency_cap.py +++ b/google/ads/googleads/v23/common/types/frequency_cap.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import frequency_cap_event_type -from google.ads.googleads.v19.enums.types import frequency_cap_level -from google.ads.googleads.v19.enums.types import frequency_cap_time_unit +from google.ads.googleads.v23.enums.types import frequency_cap_event_type +from google.ads.googleads.v23.enums.types import frequency_cap_level +from google.ads.googleads.v23.enums.types import frequency_cap_time_unit __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "FrequencyCapEntry", "FrequencyCapKey", @@ -42,7 +42,7 @@ class FrequencyCapEntry(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - key (google.ads.googleads.v19.common.types.FrequencyCapKey): + key (google.ads.googleads.v23.common.types.FrequencyCapKey): The key of a particular frequency cap. There can be no more than one frequency cap with the same key. @@ -73,14 +73,14 @@ class FrequencyCapKey(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - level (google.ads.googleads.v19.enums.types.FrequencyCapLevelEnum.FrequencyCapLevel): + level (google.ads.googleads.v23.enums.types.FrequencyCapLevelEnum.FrequencyCapLevel): The level on which the cap is to be applied (for example, ad group ad, ad group). The cap is applied to all the entities of this level. - event_type (google.ads.googleads.v19.enums.types.FrequencyCapEventTypeEnum.FrequencyCapEventType): + event_type (google.ads.googleads.v23.enums.types.FrequencyCapEventTypeEnum.FrequencyCapEventType): The type of event that the cap applies to (for example, impression). - time_unit (google.ads.googleads.v19.enums.types.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit): + time_unit (google.ads.googleads.v23.enums.types.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit): Unit of time the cap is defined at (for example, day, week). time_length (int): diff --git a/google/ads/googleads/v23/common/types/goal_common.py b/google/ads/googleads/v23/common/types/goal_common.py new file mode 100644 index 000000000..4a1837001 --- /dev/null +++ b/google/ads/googleads/v23/common/types/goal_common.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", + manifest={ + "CustomerLifecycleOptimizationValueSettings", + }, +) + + +class CustomerLifecycleOptimizationValueSettings(proto.Message): + r"""Lifecycle goal optimization value settings. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + additional_value (float): + Value of the lifecycle goal. For example, for + retention goals, value is the incremental + conversion value for lapsed customers who are + not of high value. + + This field is a member of `oneof`_ ``_additional_value``. + additional_high_lifetime_value (float): + High lifetime value of the lifecycle goal. + For example, for customer acquisition goals, + high lifetime value is the incremental + conversion value for lapsed customers who are of + high value. High lifetime value should be + greater than value, if set. + + This field is a member of `oneof`_ ``_additional_high_lifetime_value``. + """ + + additional_value: float = proto.Field( + proto.DOUBLE, + number=1, + optional=True, + ) + additional_high_lifetime_value: float = proto.Field( + proto.DOUBLE, + number=2, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/common/types/goal_setting.py b/google/ads/googleads/v23/common/types/goal_setting.py new file mode 100644 index 000000000..fa6389b6a --- /dev/null +++ b/google/ads/googleads/v23/common/types/goal_setting.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import goal_common + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", + manifest={ + "GoalSetting", + }, +) + + +class GoalSetting(proto.Message): + r"""Goal setting.""" + + class RetentionGoal(proto.Message): + r"""Retention goal settings. + + Attributes: + value_settings (google.ads.googleads.v23.common.types.CustomerLifecycleOptimizationValueSettings): + Retention goal value settings. + """ + + value_settings: ( + goal_common.CustomerLifecycleOptimizationValueSettings + ) = proto.Field( + proto.MESSAGE, + number=1, + message=goal_common.CustomerLifecycleOptimizationValueSettings, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/common/types/keyword_plan_common.py b/google/ads/googleads/v23/common/types/keyword_plan_common.py similarity index 89% rename from google/ads/googleads/v19/common/types/keyword_plan_common.py rename to google/ads/googleads/v23/common/types/keyword_plan_common.py index a3956cdd6..9a48635e8 100644 --- a/google/ads/googleads/v19/common/types/keyword_plan_common.py +++ b/google/ads/googleads/v23/common/types/keyword_plan_common.py @@ -19,19 +19,19 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import dates -from google.ads.googleads.v19.enums.types import device as gage_device -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import dates +from google.ads.googleads.v23.enums.types import device as gage_device +from google.ads.googleads.v23.enums.types import ( keyword_plan_aggregate_metric_type, ) -from google.ads.googleads.v19.enums.types import keyword_plan_competition_level -from google.ads.googleads.v19.enums.types import keyword_plan_concept_group_type -from google.ads.googleads.v19.enums.types import month_of_year +from google.ads.googleads.v23.enums.types import keyword_plan_competition_level +from google.ads.googleads.v23.enums.types import keyword_plan_concept_group_type +from google.ads.googleads.v23.enums.types import month_of_year __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanHistoricalMetrics", "HistoricalMetricsOptions", @@ -62,10 +62,10 @@ class KeywordPlanHistoricalMetrics(proto.Message): this query, averaged for the past 12 months. This field is a member of `oneof`_ ``_avg_monthly_searches``. - monthly_search_volumes (MutableSequence[google.ads.googleads.v19.common.types.MonthlySearchVolume]): + monthly_search_volumes (MutableSequence[google.ads.googleads.v23.common.types.MonthlySearchVolume]): Approximate number of searches on this query for the past twelve months. - competition (google.ads.googleads.v19.enums.types.KeywordPlanCompetitionLevelEnum.KeywordPlanCompetitionLevel): + competition (google.ads.googleads.v23.enums.types.KeywordPlanCompetitionLevelEnum.KeywordPlanCompetitionLevel): The competition level for the query. competition_index (int): The competition index for the query in the range [0, 100]. @@ -140,7 +140,7 @@ class HistoricalMetricsOptions(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - year_month_range (google.ads.googleads.v19.common.types.YearMonthRange): + year_month_range (google.ads.googleads.v23.common.types.YearMonthRange): The year month range for historical metrics. If not specified, metrics for the past 12 months are returned. Search metrics are available for the past 4 years. If the @@ -178,7 +178,7 @@ class MonthlySearchVolume(proto.Message): 2020). This field is a member of `oneof`_ ``_year``. - month (google.ads.googleads.v19.enums.types.MonthOfYearEnum.MonthOfYear): + month (google.ads.googleads.v23.enums.types.MonthOfYearEnum.MonthOfYear): The month of the search volume. monthly_searches (int): Approximate number of searches for the month. @@ -209,7 +209,7 @@ class KeywordPlanAggregateMetrics(proto.Message): r"""The aggregate metrics specification of the request. Attributes: - aggregate_metric_types (MutableSequence[google.ads.googleads.v19.enums.types.KeywordPlanAggregateMetricTypeEnum.KeywordPlanAggregateMetricType]): + aggregate_metric_types (MutableSequence[google.ads.googleads.v23.enums.types.KeywordPlanAggregateMetricTypeEnum.KeywordPlanAggregateMetricType]): The list of aggregate metrics to fetch data. """ @@ -226,7 +226,7 @@ class KeywordPlanAggregateMetricResults(proto.Message): r"""The aggregated historical metrics for keyword plan keywords. Attributes: - device_searches (MutableSequence[google.ads.googleads.v19.common.types.KeywordPlanDeviceSearches]): + device_searches (MutableSequence[google.ads.googleads.v23.common.types.KeywordPlanDeviceSearches]): The aggregate searches for all the keywords segmented by device for the specified time. Supports the following device types: MOBILE, @@ -255,7 +255,7 @@ class KeywordPlanDeviceSearches(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - device (google.ads.googleads.v19.enums.types.DeviceEnum.Device): + device (google.ads.googleads.v23.enums.types.DeviceEnum.Device): The device type. search_count (int): The total searches for the device. @@ -279,7 +279,7 @@ class KeywordAnnotations(proto.Message): r"""The annotations for the keyword plan keywords. Attributes: - concepts (MutableSequence[google.ads.googleads.v19.common.types.KeywordConcept]): + concepts (MutableSequence[google.ads.googleads.v23.common.types.KeywordConcept]): The list of concepts for the keyword. """ @@ -296,7 +296,7 @@ class KeywordConcept(proto.Message): Attributes: name (str): The concept name for the keyword in the concept_group. - concept_group (google.ads.googleads.v19.common.types.ConceptGroup): + concept_group (google.ads.googleads.v23.common.types.ConceptGroup): The concept group of the concept details. """ @@ -317,7 +317,7 @@ class ConceptGroup(proto.Message): Attributes: name (str): The concept group name. - type_ (google.ads.googleads.v19.enums.types.KeywordPlanConceptGroupTypeEnum.KeywordPlanConceptGroupType): + type_ (google.ads.googleads.v23.enums.types.KeywordPlanConceptGroupTypeEnum.KeywordPlanConceptGroupType): The concept group type. """ diff --git a/google/ads/googleads/v19/common/types/lifecycle_goals.py b/google/ads/googleads/v23/common/types/lifecycle_goals.py similarity index 95% rename from google/ads/googleads/v19/common/types/lifecycle_goals.py rename to google/ads/googleads/v23/common/types/lifecycle_goals.py index 1b782eac3..0175c5757 100644 --- a/google/ads/googleads/v19/common/types/lifecycle_goals.py +++ b/google/ads/googleads/v23/common/types/lifecycle_goals.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "LifecycleGoalValueSettings", }, diff --git a/google/ads/googleads/v19/common/types/local_services.py b/google/ads/googleads/v23/common/types/local_services.py similarity index 93% rename from google/ads/googleads/v19/common/types/local_services.py rename to google/ads/googleads/v23/common/types/local_services.py index fc9840912..a5c906489 100644 --- a/google/ads/googleads/v19/common/types/local_services.py +++ b/google/ads/googleads/v23/common/types/local_services.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesDocumentReadOnly", }, diff --git a/google/ads/googleads/v19/common/types/metric_goal.py b/google/ads/googleads/v23/common/types/metric_goal.py similarity index 83% rename from google/ads/googleads/v19/common/types/metric_goal.py rename to google/ads/googleads/v23/common/types/metric_goal.py index cbd54cbb1..fe3843e20 100644 --- a/google/ads/googleads/v19/common/types/metric_goal.py +++ b/google/ads/googleads/v23/common/types/metric_goal.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import experiment_metric -from google.ads.googleads.v19.enums.types import experiment_metric_direction +from google.ads.googleads.v23.enums.types import experiment_metric +from google.ads.googleads.v23.enums.types import experiment_metric_direction __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "MetricGoal", }, @@ -35,10 +35,10 @@ class MetricGoal(proto.Message): r"""A metric goal for an experiment. Attributes: - metric (google.ads.googleads.v19.enums.types.ExperimentMetricEnum.ExperimentMetric): + metric (google.ads.googleads.v23.enums.types.ExperimentMetricEnum.ExperimentMetric): The metric of the goal. For example, clicks, impressions, cost, conversions, etc. - direction (google.ads.googleads.v19.enums.types.ExperimentMetricDirectionEnum.ExperimentMetricDirection): + direction (google.ads.googleads.v23.enums.types.ExperimentMetricDirectionEnum.ExperimentMetricDirection): The metric direction of the goal. For example, increase, decrease, no change. """ diff --git a/google/ads/googleads/v19/common/types/metrics.py b/google/ads/googleads/v23/common/types/metrics.py similarity index 82% rename from google/ads/googleads/v19/common/types/metrics.py rename to google/ads/googleads/v23/common/types/metrics.py index 28eee94b1..d2573671c 100644 --- a/google/ads/googleads/v19/common/types/metrics.py +++ b/google/ads/googleads/v23/common/types/metrics.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import interaction_event_type -from google.ads.googleads.v19.enums.types import quality_score_bucket +from google.ads.googleads.v23.enums.types import interaction_event_type +from google.ads.googleads.v23.enums.types import quality_score_bucket __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "Metrics", "SearchVolumeRange", @@ -140,18 +140,18 @@ class Metrics(proto.Message): This field is a member of `oneof`_ ``_all_conversions_value_per_cost``. all_conversions_from_click_to_call (float): The number of times people clicked the "Call" - button to call a store during or after clicking - an ad. This number doesn't include whether or - not calls were connected, or the duration of any - calls. + button to call a business during or after + clicking an ad. This number doesn't include + whether or not calls were connected, or the + duration of any calls. This metric applies to feed items only. This field is a member of `oneof`_ ``_all_conversions_from_click_to_call``. all_conversions_from_directions (float): The number of times people clicked a "Get - directions" button to navigate to a store after - clicking an ad. + directions" button to navigate to a business + after clicking an ad. This metric applies to feed items only. @@ -164,34 +164,36 @@ class Metrics(proto.Message): This field is a member of `oneof`_ ``_all_conversions_from_interactions_value_per_interaction``. all_conversions_from_menu (float): The number of times people clicked a link to - view a store's menu after clicking an ad. + view a business's menu after clicking an ad. This metric applies to feed items only. This field is a member of `oneof`_ ``_all_conversions_from_menu``. all_conversions_from_order (float): The number of times people placed an order at - a store after clicking an ad. + a business after clicking an ad. + This metric applies to feed items only. This field is a member of `oneof`_ ``_all_conversions_from_order``. all_conversions_from_other_engagement (float): The number of other conversions (for example, posting a review or saving a location for a - store) that occurred after people clicked an ad. + business) that occurred after people clicked an + ad. This metric applies to feed items only. This field is a member of `oneof`_ ``_all_conversions_from_other_engagement``. all_conversions_from_store_visit (float): Estimated number of times people visited a - store after clicking an ad. + business after clicking an ad. This metric applies to feed items only. This field is a member of `oneof`_ ``_all_conversions_from_store_visit``. all_conversions_from_store_website (float): The number of times that people were taken to - a store's URL after clicking an ad. + a business's URL after clicking an ad. This metric applies to feed items only. @@ -281,13 +283,13 @@ class Metrics(proto.Message): Average cost-per-thousand impressions (CPM). This field is a member of `oneof`_ ``_average_cpm``. - average_cpv (float): + trueview_average_cpv (float): The average amount you pay each time someone views your ad. The average CPV is defined by the total cost of all ad views divided by the number - of views. + of TrueView views. - This field is a member of `oneof`_ ``_average_cpv``. + This field is a member of `oneof`_ ``_trueview_average_cpv``. average_page_views (float): Average number of pages viewed per session. @@ -509,11 +511,29 @@ class Metrics(proto.Message): all_conversions. This field is a member of `oneof`_ ``_cross_device_conversions``. + cross_device_conversions_by_conversion_date (float): + The number of cross-device conversions by conversion date. + Details for the by_conversion_date columns are available at + https://support.google.com/google-ads/answer/9549009. + + This field is a member of `oneof`_ ``_cross_device_conversions_by_conversion_date``. + cross_device_conversions_value (float): + The sum of the value of cross-device + conversions. + + This field is a member of `oneof`_ ``_cross_device_conversions_value``. cross_device_conversions_value_micros (int): The sum of the value of cross-device conversions, in micros. This field is a member of `oneof`_ ``_cross_device_conversions_value_micros``. + cross_device_conversions_value_by_conversion_date (float): + The sum of cross-device conversions value by conversion + date. Details for the by_conversion_date columns are + available at + https://support.google.com/google-ads/answer/9549009. + + This field is a member of `oneof`_ ``_cross_device_conversions_value_by_conversion_date``. ctr (float): The number of clicks your ad receives (Clicks) divided by the number of times your ad @@ -605,16 +625,16 @@ class Metrics(proto.Message): could have had given their feed performance. This field is a member of `oneof`_ ``_hotel_eligible_impressions``. - historical_creative_quality_score (google.ads.googleads.v19.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + historical_creative_quality_score (google.ads.googleads.v23.enums.types.QualityScoreBucketEnum.QualityScoreBucket): The creative historical quality score. - historical_landing_page_quality_score (google.ads.googleads.v19.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + historical_landing_page_quality_score (google.ads.googleads.v23.enums.types.QualityScoreBucketEnum.QualityScoreBucket): The quality of historical landing page experience. historical_quality_score (int): The historical quality score. This field is a member of `oneof`_ ``_historical_quality_score``. - historical_search_predicted_ctr (google.ads.googleads.v19.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + historical_search_predicted_ctr (google.ads.googleads.v23.enums.types.QualityScoreBucketEnum.QualityScoreBucket): The historical search predicted click through rate (CTR). gmail_forwards (int): @@ -633,8 +653,8 @@ class Metrics(proto.Message): This field is a member of `oneof`_ ``_gmail_secondary_clicks``. impressions_from_store_reach (int): - The number of times a store's location-based - ad was shown. + The number of times a business's + location-based ad was shown. This metric applies to feed items only. This field is a member of `oneof`_ ``_impressions_from_store_reach``. @@ -658,7 +678,7 @@ class Metrics(proto.Message): shopping ads, views for video ads, and so on. This field is a member of `oneof`_ ``_interactions``. - interaction_event_types (MutableSequence[google.ads.googleads.v19.enums.types.InteractionEventTypeEnum.InteractionEventType]): + interaction_event_types (MutableSequence[google.ads.googleads.v23.enums.types.InteractionEventTypeEnum.InteractionEventType]): The types of payable and free interactions. invalid_click_rate (float): The percentage of clicks filtered out of your @@ -914,7 +934,7 @@ class Metrics(proto.Message): organic results on certain queries. This field is a member of `oneof`_ ``_search_top_impression_share``. - search_volume (google.ads.googleads.v19.common.types.SearchVolumeRange): + search_volume (google.ads.googleads.v23.common.types.SearchVolumeRange): Search volume range for a search term insight category. @@ -1012,18 +1032,18 @@ class Metrics(proto.Message): watched 75% of your video. This field is a member of `oneof`_ ``_video_quartile_p75_rate``. - video_view_rate (float): - The number of views your TrueView video ad + video_trueview_view_rate (float): + The number of TrueView views your video ad receives divided by its number of impressions, including thumbnail impressions for TrueView in-display ads. - This field is a member of `oneof`_ ``_video_view_rate``. - video_views (int): - The number of times your video ads were - viewed. + This field is a member of `oneof`_ ``_video_trueview_view_rate``. + video_trueview_views (int): + The number of TrueView views your video ads + received. - This field is a member of `oneof`_ ``_video_views``. + This field is a member of `oneof`_ ``_video_trueview_views``. view_through_conversions (int): The total number of view-through conversions. These happen when a customer sees an image or @@ -1086,10 +1106,10 @@ class Metrics(proto.Message): This field is a member of `oneof`_ ``_all_conversions_from_location_asset_other_engagement``. all_conversions_from_location_asset_store_visits (float): - Estimated number of visits to the store after - a chargeable ad event (click or impression). - This measure is coming from Asset based - location. + Estimated number of visits to the business + after a chargeable ad event (click or + impression). This measure is coming from Asset + based location. This field is a member of `oneof`_ ``_all_conversions_from_location_asset_store_visits``. all_conversions_from_location_asset_website (float): @@ -1100,7 +1120,7 @@ class Metrics(proto.Message): This field is a member of `oneof`_ ``_all_conversions_from_location_asset_website``. eligible_impressions_from_location_asset_store_reach (int): - Number of impressions in which the store + Number of impressions in which the business location was shown or the location was used for targeting. This measure is coming from Asset based location. @@ -1138,9 +1158,9 @@ class Metrics(proto.Message): This field is a member of `oneof`_ ``_view_through_conversions_from_location_asset_other_engagement``. view_through_conversions_from_location_asset_store_visits (float): - Estimated number of visits to the store after - an impression. This measure is coming from Asset - based location. + Estimated number of visits to the business + after an impression. This measure is coming from + Asset based location. This field is a member of `oneof`_ ``_view_through_conversions_from_location_asset_store_visits``. view_through_conversions_from_location_asset_website (float): @@ -1498,43 +1518,6 @@ class Metrics(proto.Message): which the asset is used. This metric can only be selected with ChannelAggregateAssetView and CampaignAggregateAssetView. - sample_best_performance_entities (MutableSequence[str]): - A list of up to 20 sample linked resources - with impressions in the last 30 days where the - asset had the AssetPerformanceLabel.BEST - performance label. This metric can only be - selected with ChannelAggregateAssetView and - CampaignAggregateAssetView. - sample_good_performance_entities (MutableSequence[str]): - A list of up to 20 sample linked resources - with impressions in the last 30 days where the - asset had the AssetPerformanceLabel.GOOD - performance label. This metric can only be - selected with ChannelAggregateAssetView and - CampaignAggregateAssetView. - sample_low_performance_entities (MutableSequence[str]): - A list of up to 20 sample linked resources - with impressions in the last 30 days where the - asset had the AssetPerformanceLabel.LOW - performance label. This metric can only be - selected with ChannelAggregateAssetView and - CampaignAggregateAssetView. - sample_learning_performance_entities (MutableSequence[str]): - A list of up to 20 sample linked resources - with impressions in the last 30 days where the - asset had the AssetPerformanceLabel.LEARNING - performance label. - This metric can only be selected with - ChannelAggregateAssetView and - CampaignAggregateAssetView. - sample_unrated_performance_entities (MutableSequence[str]): - A list of up to 20 sample linked resources - with impressions in the last 30 days where the - assets had AssetPerformanceLabel performance - label other than BEST, GOOD, LOW, and LEARNING. - This metric can only be selected with - ChannelAggregateAssetView and - CampaignAggregateAssetView. asset_pinned_total_count (int): Number of total usages in which the asset is pinned. This metric can only be selected with @@ -1583,104 +1566,9 @@ class Metrics(proto.Message): This metric is only supported in Search channel. This field is a member of `oneof`_ ``_asset_pinned_as_description_position_two_count``. - asset_best_performance_impression_percentage (float): - Percentage of impressions the asset received - in ads with AssetPerformanceLabel.BEST. - This metric can only be selected with - ChannelAggregateAssetView and - CampaignAggregateAssetView. - This metric is only supported in Search channel. - - This field is a member of `oneof`_ ``_asset_best_performance_impression_percentage``. - asset_good_performance_impression_percentage (float): - Percentage of impressions the asset received - in ads with AssetPerformanceLabel.GOOD. - This metric can only be selected with - ChannelAggregateAssetView and - CampaignAggregateAssetView. - This metric is only supported in Search channel. - - This field is a member of `oneof`_ ``_asset_good_performance_impression_percentage``. - asset_low_performance_impression_percentage (float): - Percentage of impressions the asset received - in ads with AssetPerformanceLabel.LOW. - This metric can only be selected with - ChannelAggregateAssetView and - CampaignAggregateAssetView. - This metric is only supported in Search channel. - - This field is a member of `oneof`_ ``_asset_low_performance_impression_percentage``. - asset_learning_performance_impression_percentage (float): - Percentage of impressions the asset received - in ads with AssetPerformanceLabel.LEARNING. - This metric can only be selected with - ChannelAggregateAssetView and - CampaignAggregateAssetView. - This metric is only supported in Search channel. - - This field is a member of `oneof`_ ``_asset_learning_performance_impression_percentage``. - asset_unrated_performance_impression_percentage (float): - Percentage of impressions the asset received - in ads with AssetPerformanceLabel other than - BEST, GOOD, LOW, and LEARNING. This metric can - only be selected with ChannelAggregateAssetView - and CampaignAggregateAssetView. - This metric is only supported in Search channel. - - This field is a member of `oneof`_ ``_asset_unrated_performance_impression_percentage``. - asset_best_performance_cost_percentage (float): - Percentage of cost the asset received in ads - with AssetPerformanceLabel.BEST. - This metric can only be selected with - ChannelAggregateAssetView and - CampaignAggregateAssetView. - This metric is only supported in Performance Max - channel. - - This field is a member of `oneof`_ ``_asset_best_performance_cost_percentage``. - asset_good_performance_cost_percentage (float): - Percentage of cost the asset received in ads - with AssetPerformanceLabel.GOOD. - This metric can only be selected with - ChannelAggregateAssetView and - CampaignAggregateAssetView. - This metric is only supported in Performance Max - channel. - - This field is a member of `oneof`_ ``_asset_good_performance_cost_percentage``. - asset_low_performance_cost_percentage (float): - Percentage of cost the asset received in ads - with AssetPerformanceLabel.LOW. - This metric can only be selected with - ChannelAggregateAssetView and - CampaignAggregateAssetView. - This metric is only supported in Performance Max - channel. - - This field is a member of `oneof`_ ``_asset_low_performance_cost_percentage``. - asset_learning_performance_cost_percentage (float): - Percentage of cost the asset received in ads - with AssetPerformanceLabel.LEARNING. - This metric can only be selected with - ChannelAggregateAssetView and - CampaignAggregateAssetView. - This metric is only supported in Performance Max - channel. - - This field is a member of `oneof`_ ``_asset_learning_performance_cost_percentage``. - asset_unrated_performance_cost_percentage (float): - Percentage of cost the asset received in ads - with AssetPerformanceLabel other than BEST, - GOOD, LOW, and LEARNING. This metric can only be - selected with ChannelAggregateAssetView and - CampaignAggregateAssetView. - This metric is only supported in Performance Max - channel. - - This field is a member of `oneof`_ ``_asset_unrated_performance_cost_percentage``. store_visits_last_click_model_attributed_conversions (float): - The amount of store visits attributed by the - last click model. + The amount of business visits attributed by + the last click model. This field is a member of `oneof`_ ``_store_visits_last_click_model_attributed_conversions``. results_conversions_purchase (float): @@ -1688,24 +1576,24 @@ class Metrics(proto.Message): goals results. This field is a member of `oneof`_ ``_results_conversions_purchase``. - video_view_rate_in_feed (float): - The number of video views divided by number - of impressions that can potentially lead to - video views for in-feed formats. - - This field is a member of `oneof`_ ``_video_view_rate_in_feed``. - video_view_rate_in_stream (float): - The number of video views divided by number - of impressions that can potentially lead to - video views for in-stream formats. - - This field is a member of `oneof`_ ``_video_view_rate_in_stream``. - video_view_rate_shorts (float): - The number of video views divided by number - of impressions that can potentially lead to - video views for in shorts formats. - - This field is a member of `oneof`_ ``_video_view_rate_shorts``. + video_trueview_view_rate_in_feed (float): + The number of TrueView views divided by + number of impressions that can potentially lead + to TrueView views for in-feed formats. + + This field is a member of `oneof`_ ``_video_trueview_view_rate_in_feed``. + video_trueview_view_rate_in_stream (float): + The number of TrueView views divided by + number of impressions that can potentially lead + to TrueView views for in-stream formats. + + This field is a member of `oneof`_ ``_video_trueview_view_rate_in_stream``. + video_trueview_view_rate_shorts (float): + The number of TrueView views divided by + number of impressions that can potentially lead + to TrueView views for Shorts ads. + + This field is a member of `oneof`_ ``_video_trueview_view_rate_shorts``. coviewed_impressions (int): All co-viewed impressions represent the total number of people who saw your ad. This includes people who are signed @@ -1723,6 +1611,240 @@ class Metrics(proto.Message): segmentations are mandatory to get the primary impressions. This field is a member of `oneof`_ ``_primary_impressions``. + platform_comparable_conversions_from_interactions_rate (float): + Platform comparable conversions from interactions divided by + the number of ad interactions (such as clicks for text ads + or views for video ads). This only includes conversion + actions for which include_in_conversions_metric attribute is + set to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. + + This field is a member of `oneof`_ ``_platform_comparable_conversions_from_interactions_rate``. + platform_comparable_conversions (float): + The number of platform comparable conversions. This only + includes conversion actions for which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. + + This field is a member of `oneof`_ ``_platform_comparable_conversions``. + platform_comparable_conversions_value (float): + The value of platform comparable conversions. This only + includes conversion actions which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. + + This field is a member of `oneof`_ ``_platform_comparable_conversions_value``. + platform_comparable_conversions_value_per_cost (float): + The value of conversions divided by the cost of ad + interactions. This only includes conversion actions for + which include_in_conversions_metric attribute is set to + true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. + + This field is a member of `oneof`_ ``_platform_comparable_conversions_value_per_cost``. + platform_comparable_conversions_by_conversion_date (float): + The number of platform comparable conversions. When this + metric is segmented by date, the values in the date segment + represent the conversion date. This only includes conversion + actions for which include_in_conversions_metric attribute is + set to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. + + This field is a member of `oneof`_ ``_platform_comparable_conversions_by_conversion_date``. + platform_comparable_conversions_value_by_conversion_date (float): + The value of platform comparable conversions. When this + metric is segmented by date, the values in the date segment + represent the conversion date. This only includes conversion + actions for which include_in_conversions_metric attribute is + set to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. + + This field is a member of `oneof`_ ``_platform_comparable_conversions_value_by_conversion_date``. + platform_comparable_conversions_from_interactions_value_per_interaction (float): + The value of platform comparable conversions from + interactions divided by the number of ad interactions. This + only includes conversion actions for which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. + + This field is a member of `oneof`_ ``_platform_comparable_conversions_from_interactions_value_per_interaction``. + cost_per_platform_comparable_conversion (float): + The cost of ad interactions divided by the number of + platform comparable conversions. This only includes + conversion actions for which include_in_conversions_metric + attribute is set to true. If you use conversion-based + bidding, your bid strategies will optimize for these + conversions. + + This field is a member of `oneof`_ ``_cost_per_platform_comparable_conversion``. + value_per_platform_comparable_conversion (float): + The value of platform comparable conversions divided by the + number of platform comparable conversions. This only + includes conversion actions for which + include_in_conversions_metric attribute is set to true. If + you use conversion-based bidding, your bid strategies will + optimize for these conversions. + + This field is a member of `oneof`_ ``_value_per_platform_comparable_conversion``. + value_per_platform_comparable_conversions_by_conversion_date (float): + The value of platform comparable conversions divided by the + number of platform comparable conversions. When this metric + is segmented by date, the values in the date segment + represent the conversion date. This only includes conversion + actions for which include_in_conversions_metric attribute is + set to true. If you use conversion-based bidding, your bid + strategies will optimize for these conversions. + + This field is a member of `oneof`_ ``_value_per_platform_comparable_conversions_by_conversion_date``. + cost_converted_currency_per_platform_comparable_conversion (float): + The cost of the platform comparable + conversion in the currency of the authorized + customer. + + This field is a member of `oneof`_ ``_cost_converted_currency_per_platform_comparable_conversion``. + value_adjustment (float): + The conversion value rule adjustment from + biddable conversions in all conversion + categories. + + This field is a member of `oneof`_ ``_value_adjustment``. + all_value_adjustment (float): + The conversion value rule adjustment from all + conversions in all conversion categories. + + This field is a member of `oneof`_ ``_all_value_adjustment``. + clicks_unique_query_clusters (int): + Unique query intent cluster count for clicks. + + This field is a member of `oneof`_ ``_clicks_unique_query_clusters``. + conversions_unique_query_clusters (int): + Unique query intent cluster count for + conversions. + + This field is a member of `oneof`_ ``_conversions_unique_query_clusters``. + impressions_unique_query_clusters (int): + Unique query intent cluster count for + impressions. + + This field is a member of `oneof`_ ``_impressions_unique_query_clusters``. + video_watch_time_duration_millis (int): + Total watch time duration in milliseconds for + video impressions that started playing. For a + small percentage of impressions, we may not be + able to measure the watch time accurately. In + such cases, we adjust the total time to account + for any unmeasured time by applying the average + watch time of impressions that were measured. + + This field is a member of `oneof`_ ``_video_watch_time_duration_millis``. + average_video_watch_time_duration_millis (int): + Average video watch time duration in + milliseconds for video impressions that started + playing. + + This field is a member of `oneof`_ ``_average_video_watch_time_duration_millis``. + svr (int): + This feature is available to allowlisted + accounts only. + + This field is a member of `oneof`_ ``_svr``. + active_view_audibility_measurable_impressions (int): + The number of impressions for which Active + View could measure if the ad was audible. + + This field is a member of `oneof`_ ``_active_view_audibility_measurable_impressions``. + active_view_audibility_measurable_impressions_rate (float): + The number of impressions for which Active + View could measure if the ad was audible, + divided by the total number of impressions with + Active View audio enabled. + + This field is a member of `oneof`_ ``_active_view_audibility_measurable_impressions_rate``. + active_view_audibility_invalid_measurable_impressions_rate (float): + The number of impressions for which Active + View could measure audibility, but that were + filtered out by traffic quality filters, divided + by the total number of impressions measurable + for audibility. + + This field is a member of `oneof`_ ``_active_view_audibility_invalid_measurable_impressions_rate``. + active_view_audibility_invalid_givt_measurable_impressions_rate (float): + The number of impressions for which Active + View could measure audibility, but that were + filtered out by traffic quality filters, divided + by the total number of impressions measurable + for audibility. Only includes GIVT (general + invalid traffic) impressions. + + This field is a member of `oneof`_ ``_active_view_audibility_invalid_givt_measurable_impressions_rate``. + active_view_audible_impressions (int): + The number of impressions that were audible + (volume > 0%) at any point during the ad + playback. + + This field is a member of `oneof`_ ``_active_view_audible_impressions``. + active_view_audible_impressions_rate (float): + The number of impressions that were audible + (volume > 0%) at any point during the ad + playback, divided by the total number of + impressions measurable for audibility. + + This field is a member of `oneof`_ ``_active_view_audible_impressions_rate``. + active_view_audible_two_seconds_impressions (int): + The number of impressions that were audible + for at least 2 seconds (cumulative). + + This field is a member of `oneof`_ ``_active_view_audible_two_seconds_impressions``. + active_view_audible_two_seconds_impressions_rate (float): + The number of impressions that were audible + for at least 2 seconds (cumulative), divided by + the total number of impressions measurable for + audibility. + + This field is a member of `oneof`_ ``_active_view_audible_two_seconds_impressions_rate``. + active_view_audible_thirty_seconds_impressions (int): + The number of impressions that were audible + for at least 30 seconds (cumulative). + + This field is a member of `oneof`_ ``_active_view_audible_thirty_seconds_impressions``. + active_view_audible_thirty_seconds_impressions_rate (float): + The number of impressions that were audible + for at least 30 seconds (cumulative), divided by + the total number of impressions measurable for + audibility. + + This field is a member of `oneof`_ ``_active_view_audible_thirty_seconds_impressions_rate``. + active_view_audible_quartile_p25_rate (float): + The number of impressions that were audible + at the first quartile of the ad playback, + divided by the total number of impressions + measurable for audibility. + + This field is a member of `oneof`_ ``_active_view_audible_quartile_p25_rate``. + active_view_audible_quartile_p50_rate (float): + The number of impressions that were audible + at the second quartile of the ad playback, + divided by the total number of impressions + measurable for audibility. + + This field is a member of `oneof`_ ``_active_view_audible_quartile_p50_rate``. + active_view_audible_quartile_p75_rate (float): + The number of impressions that were audible + at the third quartile of the ad playback, + divided by the total number of impressions + measurable for audibility. + + This field is a member of `oneof`_ ``_active_view_audible_quartile_p75_rate``. + active_view_audible_quartile_p100_rate (float): + The number of impressions that were audible + at the fourth quartile of the ad playback, + divided by the total number of impressions + measurable for audibility. + + This field is a member of `oneof`_ ``_active_view_audible_quartile_p100_rate``. """ absolute_top_impression_percentage: float = proto.Field( @@ -1894,9 +2016,9 @@ class Metrics(proto.Message): number=206, optional=True, ) - average_cpv: float = proto.Field( + trueview_average_cpv: float = proto.Field( proto.DOUBLE, - number=207, + number=405, optional=True, ) average_page_views: float = proto.Field( @@ -2049,11 +2171,26 @@ class Metrics(proto.Message): number=173, optional=True, ) + cross_device_conversions_by_conversion_date: float = proto.Field( + proto.DOUBLE, + number=372, + optional=True, + ) + cross_device_conversions_value: float = proto.Field( + proto.DOUBLE, + number=253, + optional=True, + ) cross_device_conversions_value_micros: int = proto.Field( proto.INT64, number=312, optional=True, ) + cross_device_conversions_value_by_conversion_date: float = proto.Field( + proto.DOUBLE, + number=373, + optional=True, + ) ctr: float = proto.Field( proto.DOUBLE, number=174, @@ -2422,14 +2559,14 @@ class Metrics(proto.Message): number=135, optional=True, ) - video_view_rate: float = proto.Field( + video_trueview_view_rate: float = proto.Field( proto.DOUBLE, - number=153, + number=406, optional=True, ) - video_views: int = proto.Field( + video_trueview_views: int = proto.Field( proto.INT64, - number=154, + number=407, optional=True, ) view_through_conversions: int = proto.Field( @@ -2639,34 +2776,6 @@ class Metrics(proto.Message): proto.STRING, number=342, ) - sample_best_performance_entities: MutableSequence[str] = ( - proto.RepeatedField( - proto.STRING, - number=343, - ) - ) - sample_good_performance_entities: MutableSequence[str] = ( - proto.RepeatedField( - proto.STRING, - number=344, - ) - ) - sample_low_performance_entities: MutableSequence[str] = proto.RepeatedField( - proto.STRING, - number=345, - ) - sample_learning_performance_entities: MutableSequence[str] = ( - proto.RepeatedField( - proto.STRING, - number=346, - ) - ) - sample_unrated_performance_entities: MutableSequence[str] = ( - proto.RepeatedField( - proto.STRING, - number=347, - ) - ) asset_pinned_total_count: int = proto.Field( proto.INT64, number=348, @@ -2697,89 +2806,216 @@ class Metrics(proto.Message): number=353, optional=True, ) - asset_best_performance_impression_percentage: float = proto.Field( + store_visits_last_click_model_attributed_conversions: float = proto.Field( proto.DOUBLE, - number=354, + number=365, optional=True, ) - asset_good_performance_impression_percentage: float = proto.Field( + results_conversions_purchase: float = proto.Field( proto.DOUBLE, - number=355, + number=366, optional=True, ) - asset_low_performance_impression_percentage: float = proto.Field( + video_trueview_view_rate_in_feed: float = proto.Field( proto.DOUBLE, - number=356, + number=408, optional=True, ) - asset_learning_performance_impression_percentage: float = proto.Field( + video_trueview_view_rate_in_stream: float = proto.Field( proto.DOUBLE, - number=357, + number=409, optional=True, ) - asset_unrated_performance_impression_percentage: float = proto.Field( + video_trueview_view_rate_shorts: float = proto.Field( proto.DOUBLE, - number=358, + number=410, + optional=True, + ) + coviewed_impressions: int = proto.Field( + proto.INT64, + number=380, optional=True, ) - asset_best_performance_cost_percentage: float = proto.Field( + primary_impressions: int = proto.Field( + proto.INT64, + number=381, + optional=True, + ) + platform_comparable_conversions_from_interactions_rate: float = proto.Field( proto.DOUBLE, - number=359, + number=382, optional=True, ) - asset_good_performance_cost_percentage: float = proto.Field( + platform_comparable_conversions: float = proto.Field( proto.DOUBLE, - number=360, + number=383, optional=True, ) - asset_low_performance_cost_percentage: float = proto.Field( + platform_comparable_conversions_value: float = proto.Field( proto.DOUBLE, - number=361, + number=384, optional=True, ) - asset_learning_performance_cost_percentage: float = proto.Field( + platform_comparable_conversions_value_per_cost: float = proto.Field( proto.DOUBLE, - number=362, + number=385, optional=True, ) - asset_unrated_performance_cost_percentage: float = proto.Field( + platform_comparable_conversions_by_conversion_date: float = proto.Field( proto.DOUBLE, - number=363, + number=386, optional=True, ) - store_visits_last_click_model_attributed_conversions: float = proto.Field( + platform_comparable_conversions_value_by_conversion_date: float = ( + proto.Field( + proto.DOUBLE, + number=387, + optional=True, + ) + ) + platform_comparable_conversions_from_interactions_value_per_interaction: ( + float + ) = proto.Field( proto.DOUBLE, - number=365, + number=388, optional=True, ) - results_conversions_purchase: float = proto.Field( + cost_per_platform_comparable_conversion: float = proto.Field( proto.DOUBLE, - number=366, + number=389, optional=True, ) - video_view_rate_in_feed: float = proto.Field( + value_per_platform_comparable_conversion: float = proto.Field( proto.DOUBLE, - number=367, + number=390, optional=True, ) - video_view_rate_in_stream: float = proto.Field( + value_per_platform_comparable_conversions_by_conversion_date: float = ( + proto.Field( + proto.DOUBLE, + number=391, + optional=True, + ) + ) + cost_converted_currency_per_platform_comparable_conversion: float = ( + proto.Field( + proto.DOUBLE, + number=392, + optional=True, + ) + ) + value_adjustment: float = proto.Field( proto.DOUBLE, - number=368, + number=398, optional=True, ) - video_view_rate_shorts: float = proto.Field( + all_value_adjustment: float = proto.Field( proto.DOUBLE, - number=369, + number=399, optional=True, ) - coviewed_impressions: int = proto.Field( + clicks_unique_query_clusters: int = proto.Field( proto.INT64, - number=380, + number=400, optional=True, ) - primary_impressions: int = proto.Field( + conversions_unique_query_clusters: int = proto.Field( proto.INT64, - number=381, + number=401, + optional=True, + ) + impressions_unique_query_clusters: int = proto.Field( + proto.INT64, + number=402, + optional=True, + ) + video_watch_time_duration_millis: int = proto.Field( + proto.INT64, + number=403, + optional=True, + ) + average_video_watch_time_duration_millis: int = proto.Field( + proto.INT64, + number=404, + optional=True, + ) + svr: int = proto.Field( + proto.INT64, + number=411, + optional=True, + ) + active_view_audibility_measurable_impressions: int = proto.Field( + proto.INT64, + number=412, + optional=True, + ) + active_view_audibility_measurable_impressions_rate: float = proto.Field( + proto.DOUBLE, + number=413, + optional=True, + ) + active_view_audibility_invalid_measurable_impressions_rate: float = ( + proto.Field( + proto.DOUBLE, + number=414, + optional=True, + ) + ) + active_view_audibility_invalid_givt_measurable_impressions_rate: float = ( + proto.Field( + proto.DOUBLE, + number=415, + optional=True, + ) + ) + active_view_audible_impressions: int = proto.Field( + proto.INT64, + number=416, + optional=True, + ) + active_view_audible_impressions_rate: float = proto.Field( + proto.DOUBLE, + number=417, + optional=True, + ) + active_view_audible_two_seconds_impressions: int = proto.Field( + proto.INT64, + number=418, + optional=True, + ) + active_view_audible_two_seconds_impressions_rate: float = proto.Field( + proto.DOUBLE, + number=419, + optional=True, + ) + active_view_audible_thirty_seconds_impressions: int = proto.Field( + proto.INT64, + number=420, + optional=True, + ) + active_view_audible_thirty_seconds_impressions_rate: float = proto.Field( + proto.DOUBLE, + number=421, + optional=True, + ) + active_view_audible_quartile_p25_rate: float = proto.Field( + proto.DOUBLE, + number=422, + optional=True, + ) + active_view_audible_quartile_p50_rate: float = proto.Field( + proto.DOUBLE, + number=423, + optional=True, + ) + active_view_audible_quartile_p75_rate: float = proto.Field( + proto.DOUBLE, + number=424, + optional=True, + ) + active_view_audible_quartile_p100_rate: float = proto.Field( + proto.DOUBLE, + number=425, optional=True, ) diff --git a/google/ads/googleads/v19/common/types/offline_user_data.py b/google/ads/googleads/v23/common/types/offline_user_data.py similarity index 96% rename from google/ads/googleads/v19/common/types/offline_user_data.py rename to google/ads/googleads/v23/common/types/offline_user_data.py index e6bc3319e..271e687ff 100644 --- a/google/ads/googleads/v19/common/types/offline_user_data.py +++ b/google/ads/googleads/v23/common/types/offline_user_data.py @@ -19,15 +19,15 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import consent as gagc_consent -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import consent as gagc_consent +from google.ads.googleads.v23.enums.types import ( user_identifier_source as gage_user_identifier_source, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "OfflineUserAddressInfo", "UserIdentifier", @@ -142,7 +142,7 @@ class UserIdentifier(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - user_identifier_source (google.ads.googleads.v19.enums.types.UserIdentifierSourceEnum.UserIdentifierSource): + user_identifier_source (google.ads.googleads.v23.enums.types.UserIdentifierSourceEnum.UserIdentifierSource): Source of the user identifier when the upload is from Store Sales, ConversionUploadService, or ConversionAdjustmentUploadService. @@ -174,7 +174,7 @@ class UserIdentifier(proto.Message): Match and Store Sales. This field is a member of `oneof`_ ``identifier``. - address_info (google.ads.googleads.v19.common.types.OfflineUserAddressInfo): + address_info (google.ads.googleads.v23.common.types.OfflineUserAddressInfo): Address information. Accepted only for Customer Match, Store Sales, and ConversionAdjustmentUploadService. @@ -256,7 +256,7 @@ class TransactionAttribute(proto.Message): transactions which are part of the same order. This field is a member of `oneof`_ ``_order_id``. - store_attribute (google.ads.googleads.v19.common.types.StoreAttribute): + store_attribute (google.ads.googleads.v23.common.types.StoreAttribute): Store attributes of the transaction. custom_value (str): Value of the custom variable for each @@ -264,7 +264,7 @@ class TransactionAttribute(proto.Message): provided in the store sales metadata. This field is a member of `oneof`_ ``_custom_value``. - item_attribute (google.ads.googleads.v19.common.types.ItemAttribute): + item_attribute (google.ads.googleads.v23.common.types.ItemAttribute): Item attributes of the transaction. Accessible only to customers on the allow-list. """ @@ -396,18 +396,18 @@ class UserData(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - user_identifiers (MutableSequence[google.ads.googleads.v19.common.types.UserIdentifier]): + user_identifiers (MutableSequence[google.ads.googleads.v23.common.types.UserIdentifier]): User identification info. Required. - transaction_attribute (google.ads.googleads.v19.common.types.TransactionAttribute): + transaction_attribute (google.ads.googleads.v23.common.types.TransactionAttribute): Additional transactions/attributes associated with the user. Required when updating store sales data. - user_attribute (google.ads.googleads.v19.common.types.UserAttribute): + user_attribute (google.ads.googleads.v23.common.types.UserAttribute): Additional attributes associated with the user. Required when updating customer match attributes. These have an expiration of 540 days. - consent (google.ads.googleads.v19.common.types.Consent): + consent (google.ads.googleads.v23.common.types.Consent): The consent setting for the user. If set, will override the job level consent for this user. @@ -475,7 +475,7 @@ class UserAttribute(proto.Message): YYYY-MM-DD HH:MM:SS[+/-HH:MM], where [+/-HH:MM] is an optional timezone offset from UTC. If the offset is absent, the API will use the account's timezone as default. - shopping_loyalty (google.ads.googleads.v19.common.types.ShoppingLoyalty): + shopping_loyalty (google.ads.googleads.v23.common.types.ShoppingLoyalty): The shopping loyalty related data. Shopping utilizes this data to provide users with a better experience. Accessible only to merchants @@ -492,7 +492,7 @@ class UserAttribute(proto.Message): [+/-HH:MM] is an optional timezone offset from UTC. If the offset is absent, the API will use the account's timezone as default. - event_attribute (MutableSequence[google.ads.googleads.v19.common.types.EventAttribute]): + event_attribute (MutableSequence[google.ads.googleads.v23.common.types.EventAttribute]): Optional. Advertiser defined events and their attributes. All the values in the nested fields are required. Currently this field is in beta. @@ -559,7 +559,7 @@ class EventAttribute(proto.Message): is YYYY-MM-DD HH:MM:SS[+/-HH:MM], where [+/-HH:MM] is an optional timezone offset from UTC. If the offset is absent, the API will use the account's timezone as default. - item_attribute (MutableSequence[google.ads.googleads.v19.common.types.EventItemAttribute]): + item_attribute (MutableSequence[google.ads.googleads.v23.common.types.EventItemAttribute]): Required. Item attributes of the event. """ @@ -631,7 +631,7 @@ class CustomerMatchUserListMetadata(proto.Message): Required for job of CUSTOMER_MATCH_USER_LIST type. This field is a member of `oneof`_ ``_user_list``. - consent (google.ads.googleads.v19.common.types.Consent): + consent (google.ads.googleads.v23.common.types.Consent): The consent setting for all the users in this job. @@ -683,7 +683,7 @@ class StoreSalesMetadata(proto.Message): Accessible only to customers on the allow-list. This field is a member of `oneof`_ ``_custom_key``. - third_party_metadata (google.ads.googleads.v19.common.types.StoreSalesThirdPartyMetadata): + third_party_metadata (google.ads.googleads.v23.common.types.StoreSalesThirdPartyMetadata): Metadata for a third party Store Sales upload. """ diff --git a/google/ads/googleads/v19/common/types/policy.py b/google/ads/googleads/v23/common/types/policy.py similarity index 86% rename from google/ads/googleads/v19/common/types/policy.py rename to google/ads/googleads/v23/common/types/policy.py index d05526a66..2c8e26146 100644 --- a/google/ads/googleads/v19/common/types/policy.py +++ b/google/ads/googleads/v23/common/types/policy.py @@ -19,21 +19,21 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import policy_topic_entry_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import policy_topic_entry_type +from google.ads.googleads.v23.enums.types import ( policy_topic_evidence_destination_mismatch_url_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( policy_topic_evidence_destination_not_working_device, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( policy_topic_evidence_destination_not_working_dns_error_type, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "PolicyViolationKey", "PolicyValidationParameter", @@ -84,27 +84,32 @@ class PolicyValidationParameter(proto.Message): Attributes: ignorable_policy_topics (MutableSequence[str]): - The list of policy topics that should not - cause a PolicyFindingError to be reported. This - field is currently only compatible with Enhanced - Text Ad. It corresponds to the - PolicyTopicEntry.topic field. - - Resources violating these policies will be - saved, but will not be eligible to serve. They - may begin serving at a later time due to a - change in policies, re-review of the resource, - or a change in advertiser certificates. - exempt_policy_violation_keys (MutableSequence[google.ads.googleads.v19.common.types.PolicyViolationKey]): + The list of policy topics that should not cause a + ``PolicyFindingError`` to be reported. This field is used + for ad policy exemptions. It corresponds to the + ``PolicyTopicEntry.topic`` field. + + If this field is populated, then + ``exempt_policy_violation_keys`` must be empty. + + Resources that violate these policies will be saved, but + will not be eligible to serve. They may begin serving at a + later time due to a change in policies, re-review of the + resource, or a change in advertiser certificates. + exempt_policy_violation_keys (MutableSequence[google.ads.googleads.v23.common.types.PolicyViolationKey]): The list of policy violation keys that should not cause a - PolicyViolationError to be reported. Not all policy - violations are exemptable, refer to the is_exemptible field - in the returned PolicyViolationError. - - Resources violating these polices will be saved, but will - not be eligible to serve. They may begin serving at a later - time due to a change in policies, re-review of the resource, - or a change in advertiser certificates. + ``PolicyViolationError`` to be reported. Not all policy + violations are exemptable. Refer to the ``is_exemptible`` + field in the returned ``PolicyViolationError``. This field + is used for keyword policy exemptions. + + If this field is populated, then ``ignorable_policy_topics`` + must be empty. + + Resources that violate these policies will be saved, but + will not be eligible to serve. They may begin serving at a + later time due to a change in policies, re-review of the + resource, or a change in advertiser certificates. """ ignorable_policy_topics: MutableSequence[str] = proto.RepeatedField( @@ -142,14 +147,14 @@ class PolicyTopicEntry(proto.Message): API version and may change at any time. This field is a member of `oneof`_ ``_topic``. - type_ (google.ads.googleads.v19.enums.types.PolicyTopicEntryTypeEnum.PolicyTopicEntryType): + type_ (google.ads.googleads.v23.enums.types.PolicyTopicEntryTypeEnum.PolicyTopicEntryType): Describes the negative or positive effect this policy will have on serving. - evidences (MutableSequence[google.ads.googleads.v19.common.types.PolicyTopicEvidence]): + evidences (MutableSequence[google.ads.googleads.v23.common.types.PolicyTopicEvidence]): Additional information that explains policy finding (for example, the brand name for a trademark finding). - constraints (MutableSequence[google.ads.googleads.v19.common.types.PolicyTopicConstraint]): + constraints (MutableSequence[google.ads.googleads.v23.common.types.PolicyTopicConstraint]): Indicates how serving of this resource may be affected (for example, not serving in a country). @@ -190,11 +195,11 @@ class PolicyTopicEvidence(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - website_list (google.ads.googleads.v19.common.types.PolicyTopicEvidence.WebsiteList): + website_list (google.ads.googleads.v23.common.types.PolicyTopicEvidence.WebsiteList): List of websites linked with this resource. This field is a member of `oneof`_ ``value``. - text_list (google.ads.googleads.v19.common.types.PolicyTopicEvidence.TextList): + text_list (google.ads.googleads.v23.common.types.PolicyTopicEvidence.TextList): List of evidence found in the text of a resource. @@ -205,17 +210,17 @@ class PolicyTopicEvidence(proto.Message): "en-US". This field is a member of `oneof`_ ``value``. - destination_text_list (google.ads.googleads.v19.common.types.PolicyTopicEvidence.DestinationTextList): + destination_text_list (google.ads.googleads.v23.common.types.PolicyTopicEvidence.DestinationTextList): The text in the destination of the resource that is causing a policy finding. This field is a member of `oneof`_ ``value``. - destination_mismatch (google.ads.googleads.v19.common.types.PolicyTopicEvidence.DestinationMismatch): + destination_mismatch (google.ads.googleads.v23.common.types.PolicyTopicEvidence.DestinationMismatch): Mismatch between the destinations of a resource's URLs. This field is a member of `oneof`_ ``value``. - destination_not_working (google.ads.googleads.v19.common.types.PolicyTopicEvidence.DestinationNotWorking): + destination_not_working (google.ads.googleads.v23.common.types.PolicyTopicEvidence.DestinationNotWorking): Details when the destination is returning an HTTP error code or isn't functional in all locations for commonly used devices. @@ -272,7 +277,7 @@ class DestinationMismatch(proto.Message): r"""Evidence of mismatches between the URLs of a resource. Attributes: - url_types (MutableSequence[google.ads.googleads.v19.enums.types.PolicyTopicEvidenceDestinationMismatchUrlTypeEnum.PolicyTopicEvidenceDestinationMismatchUrlType]): + url_types (MutableSequence[google.ads.googleads.v23.enums.types.PolicyTopicEvidenceDestinationMismatchUrlTypeEnum.PolicyTopicEvidenceDestinationMismatchUrlType]): The set of URLs that did not match each other. """ @@ -302,7 +307,7 @@ class DestinationNotWorking(proto.Message): The full URL that didn't work. This field is a member of `oneof`_ ``_expanded_url``. - device (google.ads.googleads.v19.enums.types.PolicyTopicEvidenceDestinationNotWorkingDeviceEnum.PolicyTopicEvidenceDestinationNotWorkingDevice): + device (google.ads.googleads.v23.enums.types.PolicyTopicEvidenceDestinationNotWorkingDeviceEnum.PolicyTopicEvidenceDestinationNotWorkingDevice): The type of device that failed to load the URL. last_checked_date_time (str): @@ -312,7 +317,7 @@ class DestinationNotWorking(proto.Message): 14:34:30". This field is a member of `oneof`_ ``_last_checked_date_time``. - dns_error_type (google.ads.googleads.v19.enums.types.PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum.PolicyTopicEvidenceDestinationNotWorkingDnsErrorType): + dns_error_type (google.ads.googleads.v23.enums.types.PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum.PolicyTopicEvidenceDestinationNotWorkingDnsErrorType): The type of DNS error. This field is a member of `oneof`_ ``reason``. @@ -402,20 +407,20 @@ class PolicyTopicConstraint(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - country_constraint_list (google.ads.googleads.v19.common.types.PolicyTopicConstraint.CountryConstraintList): + country_constraint_list (google.ads.googleads.v23.common.types.PolicyTopicConstraint.CountryConstraintList): Countries where the resource cannot serve. This field is a member of `oneof`_ ``value``. - reseller_constraint (google.ads.googleads.v19.common.types.PolicyTopicConstraint.ResellerConstraint): + reseller_constraint (google.ads.googleads.v23.common.types.PolicyTopicConstraint.ResellerConstraint): Reseller constraint. This field is a member of `oneof`_ ``value``. - certificate_missing_in_country_list (google.ads.googleads.v19.common.types.PolicyTopicConstraint.CountryConstraintList): + certificate_missing_in_country_list (google.ads.googleads.v23.common.types.PolicyTopicConstraint.CountryConstraintList): Countries where a certificate is required for serving. This field is a member of `oneof`_ ``value``. - certificate_domain_mismatch_in_country_list (google.ads.googleads.v19.common.types.PolicyTopicConstraint.CountryConstraintList): + certificate_domain_mismatch_in_country_list (google.ads.googleads.v23.common.types.PolicyTopicConstraint.CountryConstraintList): Countries where the resource's domain is not covered by the certificates associated with it. @@ -435,7 +440,7 @@ class CountryConstraintList(proto.Message): resource. This field is a member of `oneof`_ ``_total_targeted_countries``. - countries (MutableSequence[google.ads.googleads.v19.common.types.PolicyTopicConstraint.CountryConstraint]): + countries (MutableSequence[google.ads.googleads.v23.common.types.PolicyTopicConstraint.CountryConstraint]): Countries in which serving is restricted. """ diff --git a/google/ads/googleads/v19/common/types/policy_summary.py b/google/ads/googleads/v23/common/types/policy_summary.py similarity index 82% rename from google/ads/googleads/v19/common/types/policy_summary.py rename to google/ads/googleads/v23/common/types/policy_summary.py index 72d466131..d91bc6961 100644 --- a/google/ads/googleads/v19/common/types/policy_summary.py +++ b/google/ads/googleads/v23/common/types/policy_summary.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import policy -from google.ads.googleads.v19.enums.types import policy_approval_status -from google.ads.googleads.v19.enums.types import policy_review_status +from google.ads.googleads.v23.common.types import policy +from google.ads.googleads.v23.enums.types import policy_approval_status +from google.ads.googleads.v23.enums.types import policy_review_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "PolicySummary", }, @@ -37,11 +37,11 @@ class PolicySummary(proto.Message): r"""Contains policy summary information. Attributes: - policy_topic_entries (MutableSequence[google.ads.googleads.v19.common.types.PolicyTopicEntry]): + policy_topic_entries (MutableSequence[google.ads.googleads.v23.common.types.PolicyTopicEntry]): The list of policy findings. - review_status (google.ads.googleads.v19.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): + review_status (google.ads.googleads.v23.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): Where in the review process the resource is. - approval_status (google.ads.googleads.v19.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): + approval_status (google.ads.googleads.v23.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): The overall approval status, which is calculated based on the status of its individual policy topic entries. diff --git a/google/ads/googleads/v19/common/types/real_time_bidding_setting.py b/google/ads/googleads/v23/common/types/real_time_bidding_setting.py similarity index 94% rename from google/ads/googleads/v19/common/types/real_time_bidding_setting.py rename to google/ads/googleads/v23/common/types/real_time_bidding_setting.py index 9b419f447..196e4162a 100644 --- a/google/ads/googleads/v19/common/types/real_time_bidding_setting.py +++ b/google/ads/googleads/v23/common/types/real_time_bidding_setting.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "RealTimeBiddingSetting", }, diff --git a/google/ads/googleads/v19/common/types/segments.py b/google/ads/googleads/v23/common/types/segments.py similarity index 77% rename from google/ads/googleads/v19/common/types/segments.py rename to google/ads/googleads/v23/common/types/segments.py index dd0083f3e..d3499e217 100644 --- a/google/ads/googleads/v19/common/types/segments.py +++ b/google/ads/googleads/v23/common/types/segments.py @@ -18,96 +18,110 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import ( ad_destination_type as gage_ad_destination_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( ad_format_type as gage_ad_format_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( ad_network_type as gage_ad_network_type, ) -from google.ads.googleads.v19.enums.types import age_range_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( + ad_sub_network_type as gage_ad_sub_network_type, +) +from google.ads.googleads.v23.enums.types import age_range_type +from google.ads.googleads.v23.enums.types import ( budget_campaign_association_status as gage_budget_campaign_association_status, ) -from google.ads.googleads.v19.enums.types import click_type as gage_click_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import click_type as gage_click_type +from google.ads.googleads.v23.enums.types import ( conversion_action_category as gage_conversion_action_category, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( conversion_attribution_event_type as gage_conversion_attribution_event_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( conversion_lag_bucket as gage_conversion_lag_bucket, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( conversion_or_adjustment_lag_bucket as gage_conversion_or_adjustment_lag_bucket, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( conversion_value_rule_primary_dimension as gage_conversion_value_rule_primary_dimension, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( converting_user_prior_engagement_type_and_ltv_bucket, ) -from google.ads.googleads.v19.enums.types import day_of_week as gage_day_of_week -from google.ads.googleads.v19.enums.types import device as gage_device -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import day_of_week as gage_day_of_week +from google.ads.googleads.v23.enums.types import device as gage_device +from google.ads.googleads.v23.enums.types import ( external_conversion_source as gage_external_conversion_source, ) -from google.ads.googleads.v19.enums.types import gender_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import gender_type +from google.ads.googleads.v23.enums.types import ( hotel_date_selection_type as gage_hotel_date_selection_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( hotel_price_bucket as gage_hotel_price_bucket, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( hotel_rate_type as gage_hotel_rate_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( + landing_page_source as gage_landing_page_source, +) +from google.ads.googleads.v23.enums.types import match_type as gage_match_type +from google.ads.googleads.v23.enums.types import ( month_of_year as gage_month_of_year, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( product_channel as gage_product_channel, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( product_channel_exclusivity as gage_product_channel_exclusivity, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( product_condition as gage_product_condition, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( recommendation_type as gage_recommendation_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( search_engine_results_page_type as gage_search_engine_results_page_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( + search_term_match_source as gage_search_term_match_source, +) +from google.ads.googleads.v23.enums.types import ( search_term_match_type as gage_search_term_match_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( + search_term_targeting_status as gage_search_term_targeting_status, +) +from google.ads.googleads.v23.enums.types import ( sk_ad_network_ad_event_type as gage_sk_ad_network_ad_event_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( sk_ad_network_attribution_credit as gage_sk_ad_network_attribution_credit, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( sk_ad_network_coarse_conversion_value as gage_sk_ad_network_coarse_conversion_value, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( sk_ad_network_source_type as gage_sk_ad_network_source_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( sk_ad_network_user_type as gage_sk_ad_network_user_type, ) -from google.ads.googleads.v19.enums.types import slot as gage_slot +from google.ads.googleads.v23.enums.types import slot as gage_slot +from google.ads.googleads.v23.enums.types import vertical_ads_item_vertical_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "Segments", "Keyword", @@ -151,16 +165,20 @@ class Segments(proto.Message): Advertiser supplied activity ID. This field is a member of `oneof`_ ``_external_activity_id``. - ad_destination_type (google.ads.googleads.v19.enums.types.AdDestinationTypeEnum.AdDestinationType): + ad_destination_type (google.ads.googleads.v23.enums.types.AdDestinationTypeEnum.AdDestinationType): Ad Destination type. - ad_format_type (google.ads.googleads.v19.enums.types.AdFormatTypeEnum.AdFormatType): + ad_format_type (google.ads.googleads.v23.enums.types.AdFormatTypeEnum.AdFormatType): Ad Format type. - ad_network_type (google.ads.googleads.v19.enums.types.AdNetworkTypeEnum.AdNetworkType): + ad_network_type (google.ads.googleads.v23.enums.types.AdNetworkTypeEnum.AdNetworkType): Ad network type. ad_group (str): Resource name of the ad group. This field is a member of `oneof`_ ``_ad_group``. + ad_sub_network_type (google.ads.googleads.v23.enums.types.AdSubNetworkTypeEnum.AdSubNetworkType): + Ad sub network type. Currently only available for ads + running as part of DemandGen campaigns on YouTube and has to + always be selected together with ad_network_type. asset_group (str): Resource name of the asset group. @@ -170,19 +188,19 @@ class Segments(proto.Message): Auction Insights report. This field is a member of `oneof`_ ``_auction_insight_domain``. - budget_campaign_association_status (google.ads.googleads.v19.common.types.BudgetCampaignAssociationStatus): + budget_campaign_association_status (google.ads.googleads.v23.common.types.BudgetCampaignAssociationStatus): Budget campaign association status. campaign (str): Resource name of the campaign. This field is a member of `oneof`_ ``_campaign``. - click_type (google.ads.googleads.v19.enums.types.ClickTypeEnum.ClickType): + click_type (google.ads.googleads.v23.enums.types.ClickTypeEnum.ClickType): Click type. conversion_action (str): Resource name of the conversion action. This field is a member of `oneof`_ ``_conversion_action``. - conversion_action_category (google.ads.googleads.v19.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): + conversion_action_category (google.ads.googleads.v23.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): Conversion action category. conversion_action_name (str): Conversion action name. @@ -198,12 +216,12 @@ class Segments(proto.Message): together results post-adjustment data. This field is a member of `oneof`_ ``_conversion_adjustment``. - conversion_attribution_event_type (google.ads.googleads.v19.enums.types.ConversionAttributionEventTypeEnum.ConversionAttributionEventType): + conversion_attribution_event_type (google.ads.googleads.v23.enums.types.ConversionAttributionEventTypeEnum.ConversionAttributionEventType): Conversion attribution event type. - conversion_lag_bucket (google.ads.googleads.v19.enums.types.ConversionLagBucketEnum.ConversionLagBucket): + conversion_lag_bucket (google.ads.googleads.v23.enums.types.ConversionLagBucketEnum.ConversionLagBucket): An enum value representing the number of days between the impression and the conversion. - conversion_or_adjustment_lag_bucket (google.ads.googleads.v19.enums.types.ConversionOrAdjustmentLagBucketEnum.ConversionOrAdjustmentLagBucket): + conversion_or_adjustment_lag_bucket (google.ads.googleads.v23.enums.types.ConversionOrAdjustmentLagBucketEnum.ConversionOrAdjustmentLagBucket): An enum value representing the number of days between the impression and the conversion or between the impression and adjustments to the @@ -213,11 +231,11 @@ class Segments(proto.Message): yyyy-MM-dd format, for example, 2018-04-17. This field is a member of `oneof`_ ``_date``. - day_of_week (google.ads.googleads.v19.enums.types.DayOfWeekEnum.DayOfWeek): + day_of_week (google.ads.googleads.v23.enums.types.DayOfWeekEnum.DayOfWeek): Day of the week, for example, MONDAY. - device (google.ads.googleads.v19.enums.types.DeviceEnum.Device): + device (google.ads.googleads.v23.enums.types.DeviceEnum.Device): Device to which metrics apply. - external_conversion_source (google.ads.googleads.v19.enums.types.ExternalConversionSourceEnum.ExternalConversionSource): + external_conversion_source (google.ads.googleads.v23.enums.types.ExternalConversionSourceEnum.ExternalConversionSource): External conversion source. geo_target_airport (str): Resource name of the geo target constant that @@ -291,7 +309,7 @@ class Segments(proto.Message): Hotel check-in date. Formatted as yyyy-MM-dd. This field is a member of `oneof`_ ``_hotel_check_in_date``. - hotel_check_in_day_of_week (google.ads.googleads.v19.enums.types.DayOfWeekEnum.DayOfWeek): + hotel_check_in_day_of_week (google.ads.googleads.v23.enums.types.DayOfWeekEnum.DayOfWeek): Hotel check-in day of week. hotel_city (str): Hotel city. @@ -305,7 +323,7 @@ class Segments(proto.Message): Hotel country. This field is a member of `oneof`_ ``_hotel_country``. - hotel_date_selection_type (google.ads.googleads.v19.enums.types.HotelDateSelectionTypeEnum.HotelDateSelectionType): + hotel_date_selection_type (google.ads.googleads.v23.enums.types.HotelDateSelectionTypeEnum.HotelDateSelectionType): Hotel date selection type. hotel_length_of_stay (int): Hotel length of stay. @@ -315,9 +333,9 @@ class Segments(proto.Message): Hotel rate rule ID. This field is a member of `oneof`_ ``_hotel_rate_rule_id``. - hotel_rate_type (google.ads.googleads.v19.enums.types.HotelRateTypeEnum.HotelRateType): + hotel_rate_type (google.ads.googleads.v23.enums.types.HotelRateTypeEnum.HotelRateType): Hotel rate type. - hotel_price_bucket (google.ads.googleads.v19.enums.types.HotelPriceBucketEnum.HotelPriceBucket): + hotel_price_bucket (google.ads.googleads.v23.enums.types.HotelPriceBucketEnum.HotelPriceBucket): Hotel price bucket. hotel_state (str): Hotel state. @@ -335,14 +353,17 @@ class Segments(proto.Message): extension or ad unit. This field is a member of `oneof`_ ``_interaction_on_this_extension``. - keyword (google.ads.googleads.v19.common.types.Keyword): + keyword (google.ads.googleads.v23.common.types.Keyword): Keyword criterion. + landing_page_source (google.ads.googleads.v23.enums.types.LandingPageSourceEnum.LandingPageSource): + The source of a landing page in the landing + page report. month (str): Month as represented by the date of the first day of a month. Formatted as yyyy-MM-dd. This field is a member of `oneof`_ ``_month``. - month_of_year (google.ads.googleads.v19.enums.types.MonthOfYearEnum.MonthOfYear): + month_of_year (google.ads.googleads.v23.enums.types.MonthOfYearEnum.MonthOfYear): Month of the year, for example, January. partner_hotel_id (str): Partner hotel ID. @@ -376,11 +397,11 @@ class Segments(proto.Message): Brand of the product. This field is a member of `oneof`_ ``_product_brand``. - product_channel (google.ads.googleads.v19.enums.types.ProductChannelEnum.ProductChannel): + product_channel (google.ads.googleads.v23.enums.types.ProductChannelEnum.ProductChannel): Channel of the product. - product_channel_exclusivity (google.ads.googleads.v19.enums.types.ProductChannelExclusivityEnum.ProductChannelExclusivity): + product_channel_exclusivity (google.ads.googleads.v23.enums.types.ProductChannelExclusivityEnum.ProductChannelExclusivity): Channel exclusivity of the product. - product_condition (google.ads.googleads.v19.enums.types.ProductConditionEnum.ProductCondition): + product_condition (google.ads.googleads.v23.enums.types.ProductConditionEnum.ProductCondition): Condition of the product. product_country (str): Resource name of the geo target constant for @@ -475,9 +496,60 @@ class Segments(proto.Message): time. This field is a member of `oneof`_ ``_travel_destination_region``. - recommendation_type (google.ads.googleads.v19.enums.types.RecommendationTypeEnum.RecommendationType): + vertical_ads_event_participant_display_names (str): + The display names of participants in an event + listing, like performers, speakers, or teams. + + This field is a member of `oneof`_ ``_vertical_ads_event_participant_display_names``. + vertical_ads_hotel_class (int): + The class of the hotel. Generally in the + range of 1 to 5 stars, but fully customizable in + the hotel feed. + + This field is a member of `oneof`_ ``_vertical_ads_hotel_class``. + vertical_ads_listing (str): + The listing associated with a listing + impression, click or conversion. + + This field is a member of `oneof`_ ``_vertical_ads_listing``. + vertical_ads_listing_brand (str): + The brand associated with a specific listing + within a Vertical Ads context, for example, the + brand of a car rental, a vacation home, or an + event. + + This field is a member of `oneof`_ ``_vertical_ads_listing_brand``. + vertical_ads_listing_city (str): + The city where the vertical ads listing is + located. + + This field is a member of `oneof`_ ``_vertical_ads_listing_city``. + vertical_ads_listing_country (str): + The country where the vertical ads listing is + located. + + This field is a member of `oneof`_ ``_vertical_ads_listing_country``. + vertical_ads_listing_region (str): + The region where the vertical ads listing is + located. + + This field is a member of `oneof`_ ``_vertical_ads_listing_region``. + vertical_ads_partner_account (int): + A specific partner account within a Partner + Center (for example, Hotel Center) that supplies + inventory feed data for Vertical Ads. + + This field is a member of `oneof`_ ``_vertical_ads_partner_account``. + vertical_ads_vertical (google.ads.googleads.v23.enums.types.VerticalAdsItemVerticalTypeEnum.VerticalAdsItemVerticalType): + Type of vertical ad, such as Vacation + Rentals, Car Rentals, or Events, used to + categorize and segment data in the context of + Vertical Ads. + + This field is a member of `oneof`_ ``_vertical_ads_vertical``. + recommendation_type (google.ads.googleads.v23.enums.types.RecommendationTypeEnum.RecommendationType): Recommendation type. - search_engine_results_page_type (google.ads.googleads.v19.enums.types.SearchEngineResultsPageTypeEnum.SearchEngineResultsPageType): + search_engine_results_page_type (google.ads.googleads.v23.enums.types.SearchEngineResultsPageTypeEnum.SearchEngineResultsPageType): Type of the search engine results page. search_subcategory (str): A search term subcategory. An empty string @@ -489,12 +561,21 @@ class Segments(proto.Message): A search term. This field is a member of `oneof`_ ``_search_term``. - search_term_match_type (google.ads.googleads.v19.enums.types.SearchTermMatchTypeEnum.SearchTermMatchType): - Match type of the keyword that triggered the - ad, including variants. - slot (google.ads.googleads.v19.enums.types.SlotEnum.Slot): + search_term_match_type (google.ads.googleads.v23.enums.types.SearchTermMatchTypeEnum.SearchTermMatchType): + Match type of the keyword that triggered the ad. This + segment is for use with keyword_view. For other resources, + use match_type. While match_type is filtered to Broad, + Exact, Phrase and Ai Max, search_term_match_type includes + variants like Near Exact and Near Phrase. + match_type (google.ads.googleads.v23.enums.types.MatchTypeEnum.MatchType): + The match type of the keyword that triggered the ad. This + segment is for use with keyword_view. For other resources, + use search_term_match_type. While match_type is filtered to + Broad, Exact, Phrase and Ai Max, search_term_match_type + includes variants like Near Exact, Near Phrase. + slot (google.ads.googleads.v23.enums.types.SlotEnum.Slot): Position of the ad. - conversion_value_rule_primary_dimension (google.ads.googleads.v19.enums.types.ConversionValueRulePrimaryDimensionEnum.ConversionValueRulePrimaryDimension): + conversion_value_rule_primary_dimension (google.ads.googleads.v23.enums.types.ConversionValueRulePrimaryDimensionEnum.ConversionValueRulePrimaryDimension): Primary dimension of applied conversion value rules. NO_RULE_APPLIED shows the total recorded value of conversions that do not have a value rule applied. ORIGINAL @@ -536,11 +617,11 @@ class Segments(proto.Message): to lean more. This field is a member of `oneof`_ ``_sk_ad_network_redistributed_fine_conversion_value``. - sk_ad_network_user_type (google.ads.googleads.v19.enums.types.SkAdNetworkUserTypeEnum.SkAdNetworkUserType): + sk_ad_network_user_type (google.ads.googleads.v23.enums.types.SkAdNetworkUserTypeEnum.SkAdNetworkUserType): iOS Store Kit Ad Network user type. - sk_ad_network_ad_event_type (google.ads.googleads.v19.enums.types.SkAdNetworkAdEventTypeEnum.SkAdNetworkAdEventType): + sk_ad_network_ad_event_type (google.ads.googleads.v23.enums.types.SkAdNetworkAdEventTypeEnum.SkAdNetworkAdEventType): iOS Store Kit Ad Network ad event type. - sk_ad_network_source_app (google.ads.googleads.v19.common.types.SkAdNetworkSourceApp): + sk_ad_network_source_app (google.ads.googleads.v23.common.types.SkAdNetworkSourceApp): App where the ad that drove the iOS Store Kit Ad Network install was shown. Null value means this segment is not applicable, for example, @@ -548,9 +629,9 @@ class Segments(proto.Message): postbacks sent by Apple. This field is a member of `oneof`_ ``_sk_ad_network_source_app``. - sk_ad_network_attribution_credit (google.ads.googleads.v19.enums.types.SkAdNetworkAttributionCreditEnum.SkAdNetworkAttributionCredit): + sk_ad_network_attribution_credit (google.ads.googleads.v23.enums.types.SkAdNetworkAttributionCreditEnum.SkAdNetworkAttributionCredit): iOS Store Kit Ad Network attribution credit - sk_ad_network_coarse_conversion_value (google.ads.googleads.v19.enums.types.SkAdNetworkCoarseConversionValueEnum.SkAdNetworkCoarseConversionValue): + sk_ad_network_coarse_conversion_value (google.ads.googleads.v23.enums.types.SkAdNetworkCoarseConversionValueEnum.SkAdNetworkCoarseConversionValue): iOS Store Kit Ad Network coarse conversion value. sk_ad_network_source_domain (str): @@ -561,7 +642,7 @@ class Segments(proto.Message): any postbacks sent by Apple. This field is a member of `oneof`_ ``_sk_ad_network_source_domain``. - sk_ad_network_source_type (google.ads.googleads.v19.enums.types.SkAdNetworkSourceTypeEnum.SkAdNetworkSourceType): + sk_ad_network_source_type (google.ads.googleads.v23.enums.types.SkAdNetworkSourceTypeEnum.SkAdNetworkSourceType): The source type where the ad that drove the iOS Store Kit Ad Network install was shown. Null value means this segment is not applicable, for @@ -577,7 +658,7 @@ class Segments(proto.Message): The version of the SKAdNetwork API used. This field is a member of `oneof`_ ``_sk_ad_network_version``. - asset_interaction_target (google.ads.googleads.v19.common.types.AssetInteractionTarget): + asset_interaction_target (google.ads.googleads.v23.common.types.AssetInteractionTarget): Only used with CustomerAsset, CampaignAsset and AdGroupAsset metrics. Indicates whether the interaction metrics occurred on the asset itself or a different asset or ad unit. @@ -591,25 +672,51 @@ class Segments(proto.Message): parts of the served ad this asset is served with. This field is a member of `oneof`_ ``_asset_interaction_target``. - new_versus_returning_customers (google.ads.googleads.v19.enums.types.ConvertingUserPriorEngagementTypeAndLtvBucketEnum.ConvertingUserPriorEngagementTypeAndLtvBucket): + new_versus_returning_customers (google.ads.googleads.v23.enums.types.ConvertingUserPriorEngagementTypeAndLtvBucketEnum.ConvertingUserPriorEngagementTypeAndLtvBucket): This is for segmenting conversions by whether the user is a new customer or a returning customer. This segmentation is typically used to measure the impact of customer acquisition goal. - adjusted_age_range (google.ads.googleads.v19.enums.types.AgeRangeTypeEnum.AgeRangeType): + adjusted_age_range (google.ads.googleads.v23.enums.types.AgeRangeTypeEnum.AgeRangeType): Adjusted age range. This is the age range of the user after applying modeling to get more accurate age and gender information. Currently, both adjusted_age_range and adjusted_gender need to be selected together to get valid reach stats. These segmentations are only available for allowlisted customers. - adjusted_gender (google.ads.googleads.v19.enums.types.GenderTypeEnum.GenderType): + adjusted_gender (google.ads.googleads.v23.enums.types.GenderTypeEnum.GenderType): Adjusted gender. This is the gender of the user after applying modeling to get more accurate age and gender information. Currently, both adjusted_age_range and adjusted_gender need to be selected together to get valid reach stats. These segmentations are only available for allowlisted customers. + search_term_match_source (google.ads.googleads.v23.enums.types.SearchTermMatchSourceEnum.SearchTermMatchSource): + Specifies the source for how the search term + was matched, which reveals the type of ad + campaign responsible. Use this to distinguish + between automated campaigns (like AI Max, + Dynamic Search Ads) and keyword-based campaigns + (Standard). + search_term_targeting_status (google.ads.googleads.v23.enums.types.SearchTermTargetingStatusEnum.SearchTermTargetingStatus): + Indicates whether the search term is + currently one of your targeted or excluded + keywords. + ad_using_product_data (bool): + Indicates whether an ad is using product data + from a Google Merchant Center feed. This segment + is only available for PMax campaigns and will + not return data when any other campaign type is + selected. + + This field is a member of `oneof`_ ``_ad_using_product_data``. + ad_using_video (bool): + Indicates whether an ad is using a video + asset. This segment is only available for PMax + campaigns and will not return data when any + other campaign type is selected. + + This field is a member of `oneof`_ ``_ad_using_video``. """ activity_account_id: int = proto.Field( @@ -668,6 +775,13 @@ class Segments(proto.Message): number=158, optional=True, ) + ad_sub_network_type: ( + gage_ad_sub_network_type.AdSubNetworkTypeEnum.AdSubNetworkType + ) = proto.Field( + proto.ENUM, + number=204, + enum=gage_ad_sub_network_type.AdSubNetworkTypeEnum.AdSubNetworkType, + ) asset_group: str = proto.Field( proto.STRING, number=159, @@ -908,6 +1022,13 @@ class Segments(proto.Message): number=61, message="Keyword", ) + landing_page_source: ( + gage_landing_page_source.LandingPageSourceEnum.LandingPageSource + ) = proto.Field( + proto.ENUM, + number=200, + enum=gage_landing_page_source.LandingPageSourceEnum.LandingPageSource, + ) month: str = proto.Field( proto.STRING, number=90, @@ -1084,6 +1205,54 @@ class Segments(proto.Message): number=195, optional=True, ) + vertical_ads_event_participant_display_names: str = proto.Field( + proto.STRING, + number=205, + optional=True, + ) + vertical_ads_hotel_class: int = proto.Field( + proto.INT64, + number=206, + optional=True, + ) + vertical_ads_listing: str = proto.Field( + proto.STRING, + number=207, + optional=True, + ) + vertical_ads_listing_brand: str = proto.Field( + proto.STRING, + number=208, + optional=True, + ) + vertical_ads_listing_city: str = proto.Field( + proto.STRING, + number=209, + optional=True, + ) + vertical_ads_listing_country: str = proto.Field( + proto.STRING, + number=210, + optional=True, + ) + vertical_ads_listing_region: str = proto.Field( + proto.STRING, + number=211, + optional=True, + ) + vertical_ads_partner_account: int = proto.Field( + proto.INT64, + number=212, + optional=True, + ) + vertical_ads_vertical: ( + vertical_ads_item_vertical_type.VerticalAdsItemVerticalTypeEnum.VerticalAdsItemVerticalType + ) = proto.Field( + proto.ENUM, + number=213, + optional=True, + enum=vertical_ads_item_vertical_type.VerticalAdsItemVerticalTypeEnum.VerticalAdsItemVerticalType, + ) recommendation_type: ( gage_recommendation_type.RecommendationTypeEnum.RecommendationType ) = proto.Field( @@ -1115,6 +1284,11 @@ class Segments(proto.Message): number=22, enum=gage_search_term_match_type.SearchTermMatchTypeEnum.SearchTermMatchType, ) + match_type: gage_match_type.MatchTypeEnum.MatchType = proto.Field( + proto.ENUM, + number=199, + enum=gage_match_type.MatchTypeEnum.MatchType, + ) slot: gage_slot.SlotEnum.Slot = proto.Field( proto.ENUM, number=23, @@ -1233,6 +1407,30 @@ class Segments(proto.Message): number=197, enum=gender_type.GenderTypeEnum.GenderType, ) + search_term_match_source: ( + gage_search_term_match_source.SearchTermMatchSourceEnum.SearchTermMatchSource + ) = proto.Field( + proto.ENUM, + number=198, + enum=gage_search_term_match_source.SearchTermMatchSourceEnum.SearchTermMatchSource, + ) + search_term_targeting_status: ( + gage_search_term_targeting_status.SearchTermTargetingStatusEnum.SearchTermTargetingStatus + ) = proto.Field( + proto.ENUM, + number=201, + enum=gage_search_term_targeting_status.SearchTermTargetingStatusEnum.SearchTermTargetingStatus, + ) + ad_using_product_data: bool = proto.Field( + proto.BOOL, + number=202, + optional=True, + ) + ad_using_video: bool = proto.Field( + proto.BOOL, + number=203, + optional=True, + ) class Keyword(proto.Message): @@ -1245,7 +1443,7 @@ class Keyword(proto.Message): The AdGroupCriterion resource name. This field is a member of `oneof`_ ``_ad_group_criterion``. - info (google.ads.googleads.v19.common.types.KeywordInfo): + info (google.ads.googleads.v23.common.types.KeywordInfo): Keyword info. """ @@ -1271,7 +1469,7 @@ class BudgetCampaignAssociationStatus(proto.Message): The campaign resource name. This field is a member of `oneof`_ ``_campaign``. - status (google.ads.googleads.v19.enums.types.BudgetCampaignAssociationStatusEnum.BudgetCampaignAssociationStatus): + status (google.ads.googleads.v23.enums.types.BudgetCampaignAssociationStatusEnum.BudgetCampaignAssociationStatus): Budget campaign association status. """ diff --git a/google/ads/googleads/v19/common/types/simulation.py b/google/ads/googleads/v23/common/types/simulation.py similarity index 97% rename from google/ads/googleads/v19/common/types/simulation.py rename to google/ads/googleads/v23/common/types/simulation.py index 24f2069f0..315e3c7ce 100644 --- a/google/ads/googleads/v19/common/types/simulation.py +++ b/google/ads/googleads/v23/common/types/simulation.py @@ -21,8 +21,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "CpcBidSimulationPointList", "CpvBidSimulationPointList", @@ -46,7 +46,7 @@ class CpcBidSimulationPointList(proto.Message): r"""A container for simulation points for simulations of type CPC_BID. Attributes: - points (MutableSequence[google.ads.googleads.v19.common.types.CpcBidSimulationPoint]): + points (MutableSequence[google.ads.googleads.v23.common.types.CpcBidSimulationPoint]): Projected metrics for a series of CPC bid amounts. """ @@ -62,7 +62,7 @@ class CpvBidSimulationPointList(proto.Message): r"""A container for simulation points for simulations of type CPV_BID. Attributes: - points (MutableSequence[google.ads.googleads.v19.common.types.CpvBidSimulationPoint]): + points (MutableSequence[google.ads.googleads.v23.common.types.CpvBidSimulationPoint]): Projected metrics for a series of CPV bid amounts. """ @@ -79,7 +79,7 @@ class TargetCpaSimulationPointList(proto.Message): TARGET_CPA. Attributes: - points (MutableSequence[google.ads.googleads.v19.common.types.TargetCpaSimulationPoint]): + points (MutableSequence[google.ads.googleads.v23.common.types.TargetCpaSimulationPoint]): Projected metrics for a series of target CPA amounts. """ @@ -96,7 +96,7 @@ class TargetRoasSimulationPointList(proto.Message): TARGET_ROAS. Attributes: - points (MutableSequence[google.ads.googleads.v19.common.types.TargetRoasSimulationPoint]): + points (MutableSequence[google.ads.googleads.v23.common.types.TargetRoasSimulationPoint]): Projected metrics for a series of target ROAS amounts. """ @@ -113,7 +113,7 @@ class PercentCpcBidSimulationPointList(proto.Message): PERCENT_CPC_BID. Attributes: - points (MutableSequence[google.ads.googleads.v19.common.types.PercentCpcBidSimulationPoint]): + points (MutableSequence[google.ads.googleads.v23.common.types.PercentCpcBidSimulationPoint]): Projected metrics for a series of percent CPC bid amounts. """ @@ -132,7 +132,7 @@ class BudgetSimulationPointList(proto.Message): BUDGET. Attributes: - points (MutableSequence[google.ads.googleads.v19.common.types.BudgetSimulationPoint]): + points (MutableSequence[google.ads.googleads.v23.common.types.BudgetSimulationPoint]): Projected metrics for a series of budget amounts. """ @@ -149,7 +149,7 @@ class TargetImpressionShareSimulationPointList(proto.Message): TARGET_IMPRESSION_SHARE. Attributes: - points (MutableSequence[google.ads.googleads.v19.common.types.TargetImpressionShareSimulationPoint]): + points (MutableSequence[google.ads.googleads.v23.common.types.TargetImpressionShareSimulationPoint]): Projected metrics for a specific target impression share value. """ diff --git a/google/ads/googleads/v19/common/types/tag_snippet.py b/google/ads/googleads/v23/common/types/tag_snippet.py similarity index 88% rename from google/ads/googleads/v19/common/types/tag_snippet.py rename to google/ads/googleads/v23/common/types/tag_snippet.py index ecb98244a..50ae01120 100644 --- a/google/ads/googleads/v19/common/types/tag_snippet.py +++ b/google/ads/googleads/v23/common/types/tag_snippet.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import tracking_code_page_format -from google.ads.googleads.v19.enums.types import tracking_code_type +from google.ads.googleads.v23.enums.types import tracking_code_page_format +from google.ads.googleads.v23.enums.types import tracking_code_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "TagSnippet", }, @@ -37,10 +37,10 @@ class TagSnippet(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - type_ (google.ads.googleads.v19.enums.types.TrackingCodeTypeEnum.TrackingCodeType): + type_ (google.ads.googleads.v23.enums.types.TrackingCodeTypeEnum.TrackingCodeType): The type of the generated tag snippets for tracking conversions. - page_format (google.ads.googleads.v19.enums.types.TrackingCodePageFormatEnum.TrackingCodePageFormat): + page_format (google.ads.googleads.v23.enums.types.TrackingCodePageFormatEnum.TrackingCodePageFormat): The format of the web page where the tracking tag and snippet will be installed, for example, HTML. diff --git a/google/ads/googleads/v19/common/types/targeting_setting.py b/google/ads/googleads/v23/common/types/targeting_setting.py similarity index 91% rename from google/ads/googleads/v19/common/types/targeting_setting.py rename to google/ads/googleads/v23/common/types/targeting_setting.py index 28b50d45d..27bddc29c 100644 --- a/google/ads/googleads/v19/common/types/targeting_setting.py +++ b/google/ads/googleads/v23/common/types/targeting_setting.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( targeting_dimension as gage_targeting_dimension, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "TargetingSetting", "TargetRestriction", @@ -42,10 +42,10 @@ class TargetingSetting(proto.Message): https://support.google.com/google-ads/answer/7365594 Attributes: - target_restrictions (MutableSequence[google.ads.googleads.v19.common.types.TargetRestriction]): + target_restrictions (MutableSequence[google.ads.googleads.v23.common.types.TargetRestriction]): The per-targeting-dimension setting to restrict the reach of your campaign or ad group. - target_restriction_operations (MutableSequence[google.ads.googleads.v19.common.types.TargetRestrictionOperation]): + target_restriction_operations (MutableSequence[google.ads.googleads.v23.common.types.TargetRestrictionOperation]): The list of operations changing the target restrictions. Adding a target restriction with a targeting @@ -76,7 +76,7 @@ class TargetRestriction(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - targeting_dimension (google.ads.googleads.v19.enums.types.TargetingDimensionEnum.TargetingDimension): + targeting_dimension (google.ads.googleads.v23.enums.types.TargetingDimensionEnum.TargetingDimension): The targeting dimension that these settings apply to. bid_only (bool): @@ -111,9 +111,9 @@ class TargetRestrictionOperation(proto.Message): mutate. Attributes: - operator (google.ads.googleads.v19.common.types.TargetRestrictionOperation.Operator): + operator (google.ads.googleads.v23.common.types.TargetRestrictionOperation.Operator): Type of list operation to perform. - value (google.ads.googleads.v19.common.types.TargetRestriction): + value (google.ads.googleads.v23.common.types.TargetRestriction): The target restriction being added to or removed from the list. """ diff --git a/google/ads/googleads/v19/common/types/text_label.py b/google/ads/googleads/v23/common/types/text_label.py similarity index 95% rename from google/ads/googleads/v19/common/types/text_label.py rename to google/ads/googleads/v23/common/types/text_label.py index adae15846..2e964df68 100644 --- a/google/ads/googleads/v19/common/types/text_label.py +++ b/google/ads/googleads/v23/common/types/text_label.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "TextLabel", }, diff --git a/google/ads/googleads/v23/common/types/third_party_integration_partners.py b/google/ads/googleads/v23/common/types/third_party_integration_partners.py new file mode 100644 index 000000000..2b49cc2e3 --- /dev/null +++ b/google/ads/googleads/v23/common/types/third_party_integration_partners.py @@ -0,0 +1,420 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.enums.types import ( + third_party_brand_lift_integration_partner, +) +from google.ads.googleads.v23.enums.types import ( + third_party_brand_safety_integration_partner, +) +from google.ads.googleads.v23.enums.types import ( + third_party_reach_integration_partner, +) +from google.ads.googleads.v23.enums.types import ( + third_party_viewability_integration_partner, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", + manifest={ + "CustomerThirdPartyIntegrationPartners", + "CustomerThirdPartyViewabilityIntegrationPartner", + "CustomerThirdPartyBrandSafetyIntegrationPartner", + "CustomerThirdPartyBrandLiftIntegrationPartner", + "CustomerThirdPartyReachIntegrationPartner", + "CampaignThirdPartyIntegrationPartners", + "CampaignThirdPartyViewabilityIntegrationPartner", + "CampaignThirdPartyBrandSafetyIntegrationPartner", + "CampaignThirdPartyBrandLiftIntegrationPartner", + "CampaignThirdPartyReachIntegrationPartner", + "ThirdPartyIntegrationPartnerData", + }, +) + + +class CustomerThirdPartyIntegrationPartners(proto.Message): + r"""Container for Customer level third party integration + partners. + + Attributes: + viewability_integration_partners (MutableSequence[google.ads.googleads.v23.common.types.CustomerThirdPartyViewabilityIntegrationPartner]): + Allowed third party integration partners for + YouTube viewability verification. + brand_lift_integration_partners (MutableSequence[google.ads.googleads.v23.common.types.CustomerThirdPartyBrandLiftIntegrationPartner]): + Allowed third party integration partners for + Brand Lift verification. + brand_safety_integration_partners (MutableSequence[google.ads.googleads.v23.common.types.CustomerThirdPartyBrandSafetyIntegrationPartner]): + Allowed third party integration partners for + brand safety verification. + reach_integration_partners (MutableSequence[google.ads.googleads.v23.common.types.CustomerThirdPartyReachIntegrationPartner]): + Allowed third party integration partners for + reach verification. + """ + + viewability_integration_partners: MutableSequence[ + "CustomerThirdPartyViewabilityIntegrationPartner" + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="CustomerThirdPartyViewabilityIntegrationPartner", + ) + brand_lift_integration_partners: MutableSequence[ + "CustomerThirdPartyBrandLiftIntegrationPartner" + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="CustomerThirdPartyBrandLiftIntegrationPartner", + ) + brand_safety_integration_partners: MutableSequence[ + "CustomerThirdPartyBrandSafetyIntegrationPartner" + ] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="CustomerThirdPartyBrandSafetyIntegrationPartner", + ) + reach_integration_partners: MutableSequence[ + "CustomerThirdPartyReachIntegrationPartner" + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="CustomerThirdPartyReachIntegrationPartner", + ) + + +class CustomerThirdPartyViewabilityIntegrationPartner(proto.Message): + r"""Container for third party viewability integration data for + Customer. + + Attributes: + viewability_integration_partner (google.ads.googleads.v23.enums.types.ThirdPartyViewabilityIntegrationPartnerEnum.ThirdPartyViewabilityIntegrationPartner): + Allowed third party integration partners for + YouTube viewability verification. + allow_share_cost (bool): + If true, cost data can be shared with this + vendor. + """ + + viewability_integration_partner: ( + third_party_viewability_integration_partner.ThirdPartyViewabilityIntegrationPartnerEnum.ThirdPartyViewabilityIntegrationPartner + ) = proto.Field( + proto.ENUM, + number=1, + enum=third_party_viewability_integration_partner.ThirdPartyViewabilityIntegrationPartnerEnum.ThirdPartyViewabilityIntegrationPartner, + ) + allow_share_cost: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class CustomerThirdPartyBrandSafetyIntegrationPartner(proto.Message): + r"""Container for third party brand safety integration data for + Customer. + + Attributes: + brand_safety_integration_partner (google.ads.googleads.v23.enums.types.ThirdPartyBrandSafetyIntegrationPartnerEnum.ThirdPartyBrandSafetyIntegrationPartner): + Allowed third party integration partners for + brand safety verification. + """ + + brand_safety_integration_partner: ( + third_party_brand_safety_integration_partner.ThirdPartyBrandSafetyIntegrationPartnerEnum.ThirdPartyBrandSafetyIntegrationPartner + ) = proto.Field( + proto.ENUM, + number=1, + enum=third_party_brand_safety_integration_partner.ThirdPartyBrandSafetyIntegrationPartnerEnum.ThirdPartyBrandSafetyIntegrationPartner, + ) + + +class CustomerThirdPartyBrandLiftIntegrationPartner(proto.Message): + r"""Container for third party Brand Lift integration data for + Customer. + + Attributes: + brand_lift_integration_partner (google.ads.googleads.v23.enums.types.ThirdPartyBrandLiftIntegrationPartnerEnum.ThirdPartyBrandLiftIntegrationPartner): + Allowed Third Party integration partners for + Brand Lift verification. + allow_share_cost (bool): + If true, cost data can be shared with this + vendor. + """ + + brand_lift_integration_partner: ( + third_party_brand_lift_integration_partner.ThirdPartyBrandLiftIntegrationPartnerEnum.ThirdPartyBrandLiftIntegrationPartner + ) = proto.Field( + proto.ENUM, + number=1, + enum=third_party_brand_lift_integration_partner.ThirdPartyBrandLiftIntegrationPartnerEnum.ThirdPartyBrandLiftIntegrationPartner, + ) + allow_share_cost: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class CustomerThirdPartyReachIntegrationPartner(proto.Message): + r"""Container for third party reach integration data for + Customer. + + Attributes: + reach_integration_partner (google.ads.googleads.v23.enums.types.ThirdPartyReachIntegrationPartnerEnum.ThirdPartyReachIntegrationPartner): + Allowed Third Party integration partners for + reach verification. + allow_share_cost (bool): + If true, cost data can be shared with this + vendor. + """ + + reach_integration_partner: ( + third_party_reach_integration_partner.ThirdPartyReachIntegrationPartnerEnum.ThirdPartyReachIntegrationPartner + ) = proto.Field( + proto.ENUM, + number=1, + enum=third_party_reach_integration_partner.ThirdPartyReachIntegrationPartnerEnum.ThirdPartyReachIntegrationPartner, + ) + allow_share_cost: bool = proto.Field( + proto.BOOL, + number=2, + ) + + +class CampaignThirdPartyIntegrationPartners(proto.Message): + r"""Container for Campaign level third party integration + partners. + + Attributes: + viewability_integration_partners (MutableSequence[google.ads.googleads.v23.common.types.CampaignThirdPartyViewabilityIntegrationPartner]): + Third party integration partners for YouTube + viewability verification for this Campaign. + brand_lift_integration_partners (MutableSequence[google.ads.googleads.v23.common.types.CampaignThirdPartyBrandLiftIntegrationPartner]): + Third party integration partners for Brand + Lift verification for this Campaign. + brand_safety_integration_partners (MutableSequence[google.ads.googleads.v23.common.types.CampaignThirdPartyBrandSafetyIntegrationPartner]): + Third party integration partners for brand + safety verification for this Campaign. + reach_integration_partners (MutableSequence[google.ads.googleads.v23.common.types.CampaignThirdPartyReachIntegrationPartner]): + Third party integration partners for reach + verification for this Campaign. + """ + + viewability_integration_partners: MutableSequence[ + "CampaignThirdPartyViewabilityIntegrationPartner" + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="CampaignThirdPartyViewabilityIntegrationPartner", + ) + brand_lift_integration_partners: MutableSequence[ + "CampaignThirdPartyBrandLiftIntegrationPartner" + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="CampaignThirdPartyBrandLiftIntegrationPartner", + ) + brand_safety_integration_partners: MutableSequence[ + "CampaignThirdPartyBrandSafetyIntegrationPartner" + ] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message="CampaignThirdPartyBrandSafetyIntegrationPartner", + ) + reach_integration_partners: MutableSequence[ + "CampaignThirdPartyReachIntegrationPartner" + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="CampaignThirdPartyReachIntegrationPartner", + ) + + +class CampaignThirdPartyViewabilityIntegrationPartner(proto.Message): + r"""Container for third party viewability integration data for + Campaign. + + Attributes: + viewability_integration_partner (google.ads.googleads.v23.enums.types.ThirdPartyViewabilityIntegrationPartnerEnum.ThirdPartyViewabilityIntegrationPartner): + Allowed third party integration partners for + YouTube viewability verification. + viewability_integration_partner_data (google.ads.googleads.v23.common.types.ThirdPartyIntegrationPartnerData): + Third party partner data for YouTube + viewability verification. This is optional + metadata for partners to join or attach data to + Ads campaigns. + share_cost (bool): + If true, then cost data will be shared with + this vendor. + """ + + viewability_integration_partner: ( + third_party_viewability_integration_partner.ThirdPartyViewabilityIntegrationPartnerEnum.ThirdPartyViewabilityIntegrationPartner + ) = proto.Field( + proto.ENUM, + number=1, + enum=third_party_viewability_integration_partner.ThirdPartyViewabilityIntegrationPartnerEnum.ThirdPartyViewabilityIntegrationPartner, + ) + viewability_integration_partner_data: "ThirdPartyIntegrationPartnerData" = ( + proto.Field( + proto.MESSAGE, + number=2, + message="ThirdPartyIntegrationPartnerData", + ) + ) + share_cost: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class CampaignThirdPartyBrandSafetyIntegrationPartner(proto.Message): + r"""Container for third party brand safety integration data for + Campaign. + + Attributes: + brand_safety_integration_partner (google.ads.googleads.v23.enums.types.ThirdPartyBrandSafetyIntegrationPartnerEnum.ThirdPartyBrandSafetyIntegrationPartner): + Allowed third party integration partners for + brand safety verification. + brand_safety_integration_partner_data (google.ads.googleads.v23.common.types.ThirdPartyIntegrationPartnerData): + Third party partner data for YouTube brand + safety verification. This is optional metadata + for partners to join or attach data to Ads + campaigns. + """ + + brand_safety_integration_partner: ( + third_party_brand_safety_integration_partner.ThirdPartyBrandSafetyIntegrationPartnerEnum.ThirdPartyBrandSafetyIntegrationPartner + ) = proto.Field( + proto.ENUM, + number=1, + enum=third_party_brand_safety_integration_partner.ThirdPartyBrandSafetyIntegrationPartnerEnum.ThirdPartyBrandSafetyIntegrationPartner, + ) + brand_safety_integration_partner_data: ( + "ThirdPartyIntegrationPartnerData" + ) = proto.Field( + proto.MESSAGE, + number=2, + message="ThirdPartyIntegrationPartnerData", + ) + + +class CampaignThirdPartyBrandLiftIntegrationPartner(proto.Message): + r"""Container for third party Brand Lift integration data for + Campaign. + + Attributes: + brand_lift_integration_partner (google.ads.googleads.v23.enums.types.ThirdPartyBrandLiftIntegrationPartnerEnum.ThirdPartyBrandLiftIntegrationPartner): + Allowed third party integration partners for + Brand Lift verification. + brand_lift_integration_partner_data (google.ads.googleads.v23.common.types.ThirdPartyIntegrationPartnerData): + Third party partner data for YouTube Brand + Lift verification. This is optional metadata for + partners to join or attach data to Ads + campaigns. + share_cost (bool): + If true, then cost data will be shared with + this vendor. + """ + + brand_lift_integration_partner: ( + third_party_brand_lift_integration_partner.ThirdPartyBrandLiftIntegrationPartnerEnum.ThirdPartyBrandLiftIntegrationPartner + ) = proto.Field( + proto.ENUM, + number=1, + enum=third_party_brand_lift_integration_partner.ThirdPartyBrandLiftIntegrationPartnerEnum.ThirdPartyBrandLiftIntegrationPartner, + ) + brand_lift_integration_partner_data: "ThirdPartyIntegrationPartnerData" = ( + proto.Field( + proto.MESSAGE, + number=2, + message="ThirdPartyIntegrationPartnerData", + ) + ) + share_cost: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class CampaignThirdPartyReachIntegrationPartner(proto.Message): + r"""Container for third party reach integration data for + Campaign. + + Attributes: + reach_integration_partner (google.ads.googleads.v23.enums.types.ThirdPartyReachIntegrationPartnerEnum.ThirdPartyReachIntegrationPartner): + Allowed third party integration partners for + reach verification. + reach_integration_partner_data (google.ads.googleads.v23.common.types.ThirdPartyIntegrationPartnerData): + Third party partner data for YouTube Reach + verification. This is optional metadata for + partners to join or attach data to Ads + campaigns. + share_cost (bool): + If true, then cost data will be shared with + this vendor. + """ + + reach_integration_partner: ( + third_party_reach_integration_partner.ThirdPartyReachIntegrationPartnerEnum.ThirdPartyReachIntegrationPartner + ) = proto.Field( + proto.ENUM, + number=1, + enum=third_party_reach_integration_partner.ThirdPartyReachIntegrationPartnerEnum.ThirdPartyReachIntegrationPartner, + ) + reach_integration_partner_data: "ThirdPartyIntegrationPartnerData" = ( + proto.Field( + proto.MESSAGE, + number=2, + message="ThirdPartyIntegrationPartnerData", + ) + ) + share_cost: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class ThirdPartyIntegrationPartnerData(proto.Message): + r"""Contains third party measurement partner related data for + video campaigns. + + Attributes: + client_id (str): + The client ID that allows the measurement + partner to join multiple campaigns for a + particular advertiser. + third_party_placement_id (str): + The third party placement ID that maps the + measurement partner data with a campaign (or a + group of related campaigns) specific data. + """ + + client_id: str = proto.Field( + proto.STRING, + number=1, + ) + third_party_placement_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/common/types/url_collection.py b/google/ads/googleads/v23/common/types/url_collection.py similarity index 95% rename from google/ads/googleads/v19/common/types/url_collection.py rename to google/ads/googleads/v23/common/types/url_collection.py index 8d6de0906..828a685d2 100644 --- a/google/ads/googleads/v19/common/types/url_collection.py +++ b/google/ads/googleads/v23/common/types/url_collection.py @@ -21,8 +21,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "UrlCollection", }, diff --git a/google/ads/googleads/v19/common/types/user_lists.py b/google/ads/googleads/v23/common/types/user_lists.py similarity index 90% rename from google/ads/googleads/v19/common/types/user_lists.py rename to google/ads/googleads/v23/common/types/user_lists.py index 8d2aa9b87..65f78e5e8 100644 --- a/google/ads/googleads/v19/common/types/user_lists.py +++ b/google/ads/googleads/v23/common/types/user_lists.py @@ -19,29 +19,29 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import customer_match_upload_key_type -from google.ads.googleads.v19.enums.types import lookalike_expansion_level -from google.ads.googleads.v19.enums.types import user_list_crm_data_source_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import customer_match_upload_key_type +from google.ads.googleads.v23.enums.types import lookalike_expansion_level +from google.ads.googleads.v23.enums.types import user_list_crm_data_source_type +from google.ads.googleads.v23.enums.types import ( user_list_date_rule_item_operator, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( user_list_flexible_rule_operator, ) -from google.ads.googleads.v19.enums.types import user_list_logical_rule_operator -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import user_list_logical_rule_operator +from google.ads.googleads.v23.enums.types import ( user_list_number_rule_item_operator, ) -from google.ads.googleads.v19.enums.types import user_list_prepopulation_status -from google.ads.googleads.v19.enums.types import user_list_rule_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import user_list_prepopulation_status +from google.ads.googleads.v23.enums.types import user_list_rule_type +from google.ads.googleads.v23.enums.types import ( user_list_string_rule_item_operator, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "LookalikeUserListInfo", "SimilarUserListInfo", @@ -72,7 +72,7 @@ class LookalikeUserListInfo(proto.Message): seed_user_list_ids (MutableSequence[int]): Seed UserList ID from which this list is derived, provided by user. - expansion_level (google.ads.googleads.v19.enums.types.LookalikeExpansionLevelEnum.LookalikeExpansionLevel): + expansion_level (google.ads.googleads.v23.enums.types.LookalikeExpansionLevelEnum.LookalikeExpansionLevel): Expansion level, reflecting the size of the lookalike audience country_codes (MutableSequence[str]): @@ -143,12 +143,12 @@ class CrmBasedUserListInfo(proto.Message): uploading mobile advertising IDs. This field is a member of `oneof`_ ``_app_id``. - upload_key_type (google.ads.googleads.v19.enums.types.CustomerMatchUploadKeyTypeEnum.CustomerMatchUploadKeyType): + upload_key_type (google.ads.googleads.v23.enums.types.CustomerMatchUploadKeyTypeEnum.CustomerMatchUploadKeyType): Matching key type of the list. Mixed data types are not allowed on the same list. This field is required for an ADD operation. - data_source_type (google.ads.googleads.v19.enums.types.UserListCrmDataSourceTypeEnum.UserListCrmDataSourceType): + data_source_type (google.ads.googleads.v23.enums.types.UserListCrmDataSourceTypeEnum.UserListCrmDataSourceType): Data source of the list. Default value is FIRST_PARTY. Only customers on the allow-list can create third-party sourced CRM lists. @@ -180,7 +180,7 @@ class UserListRuleInfo(proto.Message): sites or uploaded by the advertiser. Attributes: - rule_type (google.ads.googleads.v19.enums.types.UserListRuleTypeEnum.UserListRuleType): + rule_type (google.ads.googleads.v23.enums.types.UserListRuleTypeEnum.UserListRuleType): Rule type is used to determine how to group rule items. The default is OR of ANDs (disjunctive normal @@ -190,7 +190,7 @@ class UserListRuleInfo(proto.Message): OR of ANDs is the only supported type for FlexibleRuleUserList. - rule_item_groups (MutableSequence[google.ads.googleads.v19.common.types.UserListRuleItemGroupInfo]): + rule_item_groups (MutableSequence[google.ads.googleads.v23.common.types.UserListRuleItemGroupInfo]): List of rule item groups that defines this rule. Rule item groups are grouped together based on rule_type. """ @@ -215,7 +215,7 @@ class UserListRuleItemGroupInfo(proto.Message): r"""A group of rule items. Attributes: - rule_items (MutableSequence[google.ads.googleads.v19.common.types.UserListRuleItemInfo]): + rule_items (MutableSequence[google.ads.googleads.v23.common.types.UserListRuleItemInfo]): Rule items that will be grouped together based on rule_type. """ @@ -243,22 +243,22 @@ class UserListRuleItemInfo(proto.Message): letters or underscore or UTF8 code that is greater than 127 and consist of US-ascii letters or digits or underscore or UTF8 code that is greater than 127. For websites, there are - two built-in variable URL (name = 'url__') and referrer URL - (name = 'ref_url__'). This field must be populated when - creating a new rule item. + two built-in variable URL (name = 'url\_\_') and referrer + URL (name = 'ref_url\_\_'). This field must be populated + when creating a new rule item. This field is a member of `oneof`_ ``_name``. - number_rule_item (google.ads.googleads.v19.common.types.UserListNumberRuleItemInfo): + number_rule_item (google.ads.googleads.v23.common.types.UserListNumberRuleItemInfo): An atomic rule item composed of a number operation. This field is a member of `oneof`_ ``rule_item``. - string_rule_item (google.ads.googleads.v19.common.types.UserListStringRuleItemInfo): + string_rule_item (google.ads.googleads.v23.common.types.UserListStringRuleItemInfo): An atomic rule item composed of a string operation. This field is a member of `oneof`_ ``rule_item``. - date_rule_item (google.ads.googleads.v19.common.types.UserListDateRuleItemInfo): + date_rule_item (google.ads.googleads.v23.common.types.UserListDateRuleItemInfo): An atomic rule item composed of a date operation. @@ -296,7 +296,7 @@ class UserListDateRuleItemInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - operator (google.ads.googleads.v19.enums.types.UserListDateRuleItemOperatorEnum.UserListDateRuleItemOperator): + operator (google.ads.googleads.v23.enums.types.UserListDateRuleItemOperatorEnum.UserListDateRuleItemOperator): Date comparison operator. This field is required and must be populated when creating new date rule item. @@ -341,7 +341,7 @@ class UserListNumberRuleItemInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - operator (google.ads.googleads.v19.enums.types.UserListNumberRuleItemOperatorEnum.UserListNumberRuleItemOperator): + operator (google.ads.googleads.v23.enums.types.UserListNumberRuleItemOperatorEnum.UserListNumberRuleItemOperator): Number comparison operator. This field is required and must be populated when creating a new number rule item. @@ -373,7 +373,7 @@ class UserListStringRuleItemInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - operator (google.ads.googleads.v19.enums.types.UserListStringRuleItemOperatorEnum.UserListStringRuleItemOperator): + operator (google.ads.googleads.v23.enums.types.UserListStringRuleItemOperatorEnum.UserListStringRuleItemOperator): String comparison operator. This field is required and must be populated when creating a new string rule item. @@ -410,7 +410,7 @@ class FlexibleRuleOperandInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - rule (google.ads.googleads.v19.common.types.UserListRuleInfo): + rule (google.ads.googleads.v23.common.types.UserListRuleInfo): List of rule item groups that defines this rule. Rule item groups are grouped together. lookback_window_days (int): @@ -442,15 +442,15 @@ class FlexibleRuleUserListInfo(proto.Message): user list, minus the users represented by the exclusive operands. Attributes: - inclusive_rule_operator (google.ads.googleads.v19.enums.types.UserListFlexibleRuleOperatorEnum.UserListFlexibleRuleOperator): + inclusive_rule_operator (google.ads.googleads.v23.enums.types.UserListFlexibleRuleOperatorEnum.UserListFlexibleRuleOperator): Operator that defines how the inclusive operands are combined. - inclusive_operands (MutableSequence[google.ads.googleads.v19.common.types.FlexibleRuleOperandInfo]): + inclusive_operands (MutableSequence[google.ads.googleads.v23.common.types.FlexibleRuleOperandInfo]): Rules representing users that should be included in the user list. These are located on the left side of the AND_NOT operator, and joined together by either AND/OR as specified by the inclusive_rule_operator. - exclusive_operands (MutableSequence[google.ads.googleads.v19.common.types.FlexibleRuleOperandInfo]): + exclusive_operands (MutableSequence[google.ads.googleads.v23.common.types.FlexibleRuleOperandInfo]): Rules representing users that should be excluded from the user list. These are located on the right side of the AND_NOT operator, and joined together by OR. @@ -483,7 +483,7 @@ class RuleBasedUserListInfo(proto.Message): r"""Representation of a userlist that is generated by a rule. Attributes: - prepopulation_status (google.ads.googleads.v19.enums.types.UserListPrepopulationStatusEnum.UserListPrepopulationStatus): + prepopulation_status (google.ads.googleads.v23.enums.types.UserListPrepopulationStatusEnum.UserListPrepopulationStatus): The status of pre-population. The field is default to NONE if not set which means the previous users will not be considered. If set to @@ -496,7 +496,7 @@ class RuleBasedUserListInfo(proto.Message): is added. The status will be updated to FINISHED once request is processed, or FAILED if the request fails. - flexible_rule_user_list (google.ads.googleads.v19.common.types.FlexibleRuleUserListInfo): + flexible_rule_user_list (google.ads.googleads.v23.common.types.FlexibleRuleUserListInfo): Flexible rule representation of visitors with one or multiple actions. The flexible user list is defined by two lists of operands – inclusive_operands and @@ -527,7 +527,7 @@ class LogicalUserListInfo(proto.Message): lists. Attributes: - rules (MutableSequence[google.ads.googleads.v19.common.types.UserListLogicalRuleInfo]): + rules (MutableSequence[google.ads.googleads.v23.common.types.UserListLogicalRuleInfo]): Logical list rules that define this user list. The rules are defined as a logical operator (ALL/ANY/NONE) and a list of user @@ -549,9 +549,9 @@ class UserListLogicalRuleInfo(proto.Message): (and/or/not) and a list of user lists as operands. Attributes: - operator (google.ads.googleads.v19.enums.types.UserListLogicalRuleOperatorEnum.UserListLogicalRuleOperator): + operator (google.ads.googleads.v23.enums.types.UserListLogicalRuleOperatorEnum.UserListLogicalRuleOperator): The logical operator of the rule. - rule_operands (MutableSequence[google.ads.googleads.v19.common.types.LogicalUserListOperandInfo]): + rule_operands (MutableSequence[google.ads.googleads.v23.common.types.LogicalUserListOperandInfo]): The list of operands of the rule. """ @@ -595,7 +595,7 @@ class BasicUserListInfo(proto.Message): remarketing actions. Attributes: - actions (MutableSequence[google.ads.googleads.v19.common.types.UserListActionInfo]): + actions (MutableSequence[google.ads.googleads.v23.common.types.UserListActionInfo]): Actions associated with this user list. """ diff --git a/google/ads/googleads/v19/common/types/value.py b/google/ads/googleads/v23/common/types/value.py similarity index 96% rename from google/ads/googleads/v19/common/types/value.py rename to google/ads/googleads/v23/common/types/value.py index c7d74c947..57634b3a2 100644 --- a/google/ads/googleads/v19/common/types/value.py +++ b/google/ads/googleads/v23/common/types/value.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.common", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.common", + marshal="google.ads.googleads.v23", manifest={ "Value", }, diff --git a/google/ads/googleads/v23/enums/__init__.py b/google/ads/googleads/v23/enums/__init__.py new file mode 100644 index 000000000..cfcd96e80 --- /dev/null +++ b/google/ads/googleads/v23/enums/__init__.py @@ -0,0 +1,1059 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from google.ads.googleads.v23 import gapic_version as package_version + +import google.api_core as api_core +import sys + +__version__ = package_version.__version__ + +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata + + +from .types.access_invitation_status import AccessInvitationStatusEnum +from .types.access_reason import AccessReasonEnum +from .types.access_role import AccessRoleEnum +from .types.account_budget_proposal_status import ( + AccountBudgetProposalStatusEnum, +) +from .types.account_budget_proposal_type import AccountBudgetProposalTypeEnum +from .types.account_budget_status import AccountBudgetStatusEnum +from .types.account_link_status import AccountLinkStatusEnum +from .types.ad_destination_type import AdDestinationTypeEnum +from .types.ad_format_type import AdFormatTypeEnum +from .types.ad_group_ad_primary_status import AdGroupAdPrimaryStatusEnum +from .types.ad_group_ad_primary_status_reason import ( + AdGroupAdPrimaryStatusReasonEnum, +) +from .types.ad_group_ad_rotation_mode import AdGroupAdRotationModeEnum +from .types.ad_group_ad_status import AdGroupAdStatusEnum +from .types.ad_group_criterion_approval_status import ( + AdGroupCriterionApprovalStatusEnum, +) +from .types.ad_group_criterion_primary_status import ( + AdGroupCriterionPrimaryStatusEnum, +) +from .types.ad_group_criterion_primary_status_reason import ( + AdGroupCriterionPrimaryStatusReasonEnum, +) +from .types.ad_group_criterion_status import AdGroupCriterionStatusEnum +from .types.ad_group_primary_status import AdGroupPrimaryStatusEnum +from .types.ad_group_primary_status_reason import AdGroupPrimaryStatusReasonEnum +from .types.ad_group_status import AdGroupStatusEnum +from .types.ad_group_type import AdGroupTypeEnum +from .types.ad_network_type import AdNetworkTypeEnum +from .types.ad_serving_optimization_status import ( + AdServingOptimizationStatusEnum, +) +from .types.ad_strength import AdStrengthEnum +from .types.ad_strength_action_item_type import AdStrengthActionItemTypeEnum +from .types.ad_sub_network_type import AdSubNetworkTypeEnum +from .types.ad_type import AdTypeEnum +from .types.advertising_channel_sub_type import AdvertisingChannelSubTypeEnum +from .types.advertising_channel_type import AdvertisingChannelTypeEnum +from .types.age_range_type import AgeRangeTypeEnum +from .types.android_privacy_interaction_type import ( + AndroidPrivacyInteractionTypeEnum, +) +from .types.android_privacy_network_type import AndroidPrivacyNetworkTypeEnum +from .types.app_bidding_goal import AppBiddingGoalEnum +from .types.app_campaign_app_store import AppCampaignAppStoreEnum +from .types.app_campaign_bidding_strategy_goal_type import ( + AppCampaignBiddingStrategyGoalTypeEnum, +) +from .types.app_payment_model_type import AppPaymentModelTypeEnum +from .types.app_url_operating_system_type import AppUrlOperatingSystemTypeEnum +from .types.application_instance import ApplicationInstanceEnum +from .types.asset_automation_status import AssetAutomationStatusEnum +from .types.asset_automation_type import AssetAutomationTypeEnum +from .types.asset_coverage_video_aspect_ratio_requirement import ( + AssetCoverageVideoAspectRatioRequirementEnum, +) +from .types.asset_field_type import AssetFieldTypeEnum +from .types.asset_group_primary_status import AssetGroupPrimaryStatusEnum +from .types.asset_group_primary_status_reason import ( + AssetGroupPrimaryStatusReasonEnum, +) +from .types.asset_group_signal_approval_status import ( + AssetGroupSignalApprovalStatusEnum, +) +from .types.asset_group_status import AssetGroupStatusEnum +from .types.asset_link_primary_status import AssetLinkPrimaryStatusEnum +from .types.asset_link_primary_status_reason import ( + AssetLinkPrimaryStatusReasonEnum, +) +from .types.asset_link_status import AssetLinkStatusEnum +from .types.asset_offline_evaluation_error_reasons import ( + AssetOfflineEvaluationErrorReasonsEnum, +) +from .types.asset_orientation import AssetOrientationEnum +from .types.asset_performance_label import AssetPerformanceLabelEnum +from .types.asset_set_asset_status import AssetSetAssetStatusEnum +from .types.asset_set_link_status import AssetSetLinkStatusEnum +from .types.asset_set_status import AssetSetStatusEnum +from .types.asset_set_type import AssetSetTypeEnum +from .types.asset_source import AssetSourceEnum +from .types.asset_type import AssetTypeEnum +from .types.async_action_status import AsyncActionStatusEnum +from .types.attribution_model import AttributionModelEnum +from .types.audience_insights_dimension import AudienceInsightsDimensionEnum +from .types.audience_insights_marketing_objective import ( + AudienceInsightsMarketingObjectiveEnum, +) +from .types.audience_scope import AudienceScopeEnum +from .types.audience_status import AudienceStatusEnum +from .types.batch_job_status import BatchJobStatusEnum +from .types.benchmarks_marketing_objective import ( + BenchmarksMarketingObjectiveEnum, +) +from .types.benchmarks_source_type import BenchmarksSourceTypeEnum +from .types.bid_modifier_source import BidModifierSourceEnum +from .types.bidding_source import BiddingSourceEnum +from .types.bidding_strategy_status import BiddingStrategyStatusEnum +from .types.bidding_strategy_system_status import ( + BiddingStrategySystemStatusEnum, +) +from .types.bidding_strategy_type import BiddingStrategyTypeEnum +from .types.billing_setup_status import BillingSetupStatusEnum +from .types.brand_request_rejection_reason import ( + BrandRequestRejectionReasonEnum, +) +from .types.brand_safety_suitability import BrandSafetySuitabilityEnum +from .types.brand_state import BrandStateEnum +from .types.budget_campaign_association_status import ( + BudgetCampaignAssociationStatusEnum, +) +from .types.budget_delivery_method import BudgetDeliveryMethodEnum +from .types.budget_period import BudgetPeriodEnum +from .types.budget_status import BudgetStatusEnum +from .types.budget_type import BudgetTypeEnum +from .types.business_message_call_to_action_type import ( + BusinessMessageCallToActionTypeEnum, +) +from .types.business_message_provider import BusinessMessageProviderEnum +from .types.call_conversion_reporting_state import ( + CallConversionReportingStateEnum, +) +from .types.call_to_action_type import CallToActionTypeEnum +from .types.call_tracking_display_location import ( + CallTrackingDisplayLocationEnum, +) +from .types.call_type import CallTypeEnum +from .types.campaign_criterion_status import CampaignCriterionStatusEnum +from .types.campaign_draft_status import CampaignDraftStatusEnum +from .types.campaign_experiment_type import CampaignExperimentTypeEnum +from .types.campaign_group_status import CampaignGroupStatusEnum +from .types.campaign_keyword_match_type import CampaignKeywordMatchTypeEnum +from .types.campaign_primary_status import CampaignPrimaryStatusEnum +from .types.campaign_primary_status_reason import ( + CampaignPrimaryStatusReasonEnum, +) +from .types.campaign_serving_status import CampaignServingStatusEnum +from .types.campaign_shared_set_status import CampaignSharedSetStatusEnum +from .types.campaign_status import CampaignStatusEnum +from .types.chain_relationship_type import ChainRelationshipTypeEnum +from .types.change_client_type import ChangeClientTypeEnum +from .types.change_event_resource_type import ChangeEventResourceTypeEnum +from .types.change_status_operation import ChangeStatusOperationEnum +from .types.change_status_resource_type import ChangeStatusResourceTypeEnum +from .types.click_type import ClickTypeEnum +from .types.combined_audience_status import CombinedAudienceStatusEnum +from .types.consent_status import ConsentStatusEnum +from .types.content_label_type import ContentLabelTypeEnum +from .types.conversion_action_category import ConversionActionCategoryEnum +from .types.conversion_action_counting_type import ( + ConversionActionCountingTypeEnum, +) +from .types.conversion_action_status import ConversionActionStatusEnum +from .types.conversion_action_type import ConversionActionTypeEnum +from .types.conversion_adjustment_type import ConversionAdjustmentTypeEnum +from .types.conversion_attribution_event_type import ( + ConversionAttributionEventTypeEnum, +) +from .types.conversion_custom_variable_status import ( + ConversionCustomVariableStatusEnum, +) +from .types.conversion_customer_type import ConversionCustomerTypeEnum +from .types.conversion_environment_enum import ConversionEnvironmentEnum +from .types.conversion_lag_bucket import ConversionLagBucketEnum +from .types.conversion_or_adjustment_lag_bucket import ( + ConversionOrAdjustmentLagBucketEnum, +) +from .types.conversion_origin import ConversionOriginEnum +from .types.conversion_tracking_status_enum import ConversionTrackingStatusEnum +from .types.conversion_value_rule_primary_dimension import ( + ConversionValueRulePrimaryDimensionEnum, +) +from .types.conversion_value_rule_set_status import ( + ConversionValueRuleSetStatusEnum, +) +from .types.conversion_value_rule_status import ConversionValueRuleStatusEnum +from .types.converting_user_prior_engagement_type_and_ltv_bucket import ( + ConvertingUserPriorEngagementTypeAndLtvBucketEnum, +) +from .types.criterion_category_channel_availability_mode import ( + CriterionCategoryChannelAvailabilityModeEnum, +) +from .types.criterion_category_locale_availability_mode import ( + CriterionCategoryLocaleAvailabilityModeEnum, +) +from .types.criterion_system_serving_status import ( + CriterionSystemServingStatusEnum, +) +from .types.criterion_type import CriterionTypeEnum +from .types.custom_audience_member_type import CustomAudienceMemberTypeEnum +from .types.custom_audience_status import CustomAudienceStatusEnum +from .types.custom_audience_type import CustomAudienceTypeEnum +from .types.custom_conversion_goal_status import CustomConversionGoalStatusEnum +from .types.custom_interest_member_type import CustomInterestMemberTypeEnum +from .types.custom_interest_status import CustomInterestStatusEnum +from .types.custom_interest_type import CustomInterestTypeEnum +from .types.customer_acquisition_optimization_mode import ( + CustomerAcquisitionOptimizationModeEnum, +) +from .types.customer_lifecycle_optimization_mode import ( + CustomerLifecycleOptimizationModeEnum, +) +from .types.customer_match_upload_key_type import CustomerMatchUploadKeyTypeEnum +from .types.customer_pay_per_conversion_eligibility_failure_reason import ( + CustomerPayPerConversionEligibilityFailureReasonEnum, +) +from .types.customer_status import CustomerStatusEnum +from .types.customizer_attribute_status import CustomizerAttributeStatusEnum +from .types.customizer_attribute_type import CustomizerAttributeTypeEnum +from .types.customizer_value_status import CustomizerValueStatusEnum +from .types.data_driven_model_status import DataDrivenModelStatusEnum +from .types.data_link_status import DataLinkStatusEnum +from .types.data_link_type import DataLinkTypeEnum +from .types.day_of_week import DayOfWeekEnum +from .types.demand_gen_channel_config import DemandGenChannelConfigEnum +from .types.demand_gen_channel_strategy import DemandGenChannelStrategyEnum +from .types.device import DeviceEnum +from .types.display_ad_format_setting import DisplayAdFormatSettingEnum +from .types.display_upload_product_type import DisplayUploadProductTypeEnum +from .types.distance_bucket import DistanceBucketEnum +from .types.eu_political_advertising_status import ( + EuPoliticalAdvertisingStatusEnum, +) +from .types.experiment_metric import ExperimentMetricEnum +from .types.experiment_metric_direction import ExperimentMetricDirectionEnum +from .types.experiment_status import ExperimentStatusEnum +from .types.experiment_type import ExperimentTypeEnum +from .types.external_conversion_source import ExternalConversionSourceEnum +from .types.fixed_cpm_goal import FixedCpmGoalEnum +from .types.fixed_cpm_target_frequency_time_unit import ( + FixedCpmTargetFrequencyTimeUnitEnum, +) +from .types.frequency_cap_event_type import FrequencyCapEventTypeEnum +from .types.frequency_cap_level import FrequencyCapLevelEnum +from .types.frequency_cap_time_unit import FrequencyCapTimeUnitEnum +from .types.gender_type import GenderTypeEnum +from .types.geo_target_constant_status import GeoTargetConstantStatusEnum +from .types.geo_targeting_type import GeoTargetingTypeEnum +from .types.goal_config_level import GoalConfigLevelEnum +from .types.goal_optimization_eligibility import GoalOptimizationEligibilityEnum +from .types.goal_type import GoalTypeEnum +from .types.google_ads_field_category import GoogleAdsFieldCategoryEnum +from .types.google_ads_field_data_type import GoogleAdsFieldDataTypeEnum +from .types.google_voice_call_status import GoogleVoiceCallStatusEnum +from .types.hotel_asset_suggestion_status import HotelAssetSuggestionStatusEnum +from .types.hotel_date_selection_type import HotelDateSelectionTypeEnum +from .types.hotel_price_bucket import HotelPriceBucketEnum +from .types.hotel_rate_type import HotelRateTypeEnum +from .types.hotel_reconciliation_status import HotelReconciliationStatusEnum +from .types.identity_verification_program import IdentityVerificationProgramEnum +from .types.identity_verification_program_status import ( + IdentityVerificationProgramStatusEnum, +) +from .types.incentive_state import IncentiveStateEnum +from .types.income_range_type import IncomeRangeTypeEnum +from .types.insights_knowledge_graph_entity_capabilities import ( + InsightsKnowledgeGraphEntityCapabilitiesEnum, +) +from .types.insights_trend import InsightsTrendEnum +from .types.interaction_event_type import InteractionEventTypeEnum +from .types.interaction_type import InteractionTypeEnum +from .types.invoice_type import InvoiceTypeEnum +from .types.keyword_match_type import KeywordMatchTypeEnum +from .types.keyword_plan_aggregate_metric_type import ( + KeywordPlanAggregateMetricTypeEnum, +) +from .types.keyword_plan_competition_level import ( + KeywordPlanCompetitionLevelEnum, +) +from .types.keyword_plan_concept_group_type import ( + KeywordPlanConceptGroupTypeEnum, +) +from .types.keyword_plan_forecast_interval import ( + KeywordPlanForecastIntervalEnum, +) +from .types.keyword_plan_keyword_annotation import ( + KeywordPlanKeywordAnnotationEnum, +) +from .types.keyword_plan_network import KeywordPlanNetworkEnum +from .types.label_status import LabelStatusEnum +from .types.landing_page_source import LandingPageSourceEnum +from .types.lead_form_call_to_action_type import LeadFormCallToActionTypeEnum +from .types.lead_form_desired_intent import LeadFormDesiredIntentEnum +from .types.lead_form_field_user_input_type import ( + LeadFormFieldUserInputTypeEnum, +) +from .types.lead_form_post_submit_call_to_action_type import ( + LeadFormPostSubmitCallToActionTypeEnum, +) +from .types.legacy_app_install_ad_app_store import ( + LegacyAppInstallAdAppStoreEnum, +) +from .types.linked_account_type import LinkedAccountTypeEnum +from .types.linked_product_type import LinkedProductTypeEnum +from .types.listing_group_filter_custom_attribute_index import ( + ListingGroupFilterCustomAttributeIndexEnum, +) +from .types.listing_group_filter_listing_source import ( + ListingGroupFilterListingSourceEnum, +) +from .types.listing_group_filter_product_category_level import ( + ListingGroupFilterProductCategoryLevelEnum, +) +from .types.listing_group_filter_product_channel import ( + ListingGroupFilterProductChannelEnum, +) +from .types.listing_group_filter_product_condition import ( + ListingGroupFilterProductConditionEnum, +) +from .types.listing_group_filter_product_type_level import ( + ListingGroupFilterProductTypeLevelEnum, +) +from .types.listing_group_filter_type_enum import ListingGroupFilterTypeEnum +from .types.listing_group_type import ListingGroupTypeEnum +from .types.listing_type import ListingTypeEnum +from .types.local_services_business_registration_check_rejection_reason import ( + LocalServicesBusinessRegistrationCheckRejectionReasonEnum, +) +from .types.local_services_business_registration_type import ( + LocalServicesBusinessRegistrationTypeEnum, +) +from .types.local_services_conversation_type import ( + LocalServicesLeadConversationTypeEnum, +) +from .types.local_services_employee_status import ( + LocalServicesEmployeeStatusEnum, +) +from .types.local_services_employee_type import LocalServicesEmployeeTypeEnum +from .types.local_services_insurance_rejection_reason import ( + LocalServicesInsuranceRejectionReasonEnum, +) +from .types.local_services_lead_credit_issuance_decision import ( + LocalServicesLeadCreditIssuanceDecisionEnum, +) +from .types.local_services_lead_credit_state import LocalServicesCreditStateEnum +from .types.local_services_lead_status import LocalServicesLeadStatusEnum +from .types.local_services_lead_survey_answer import ( + LocalServicesLeadSurveyAnswerEnum, +) +from .types.local_services_lead_survey_dissatisfied_reason import ( + LocalServicesLeadSurveyDissatisfiedReasonEnum, +) +from .types.local_services_lead_survey_satisfied_reason import ( + LocalServicesLeadSurveySatisfiedReasonEnum, +) +from .types.local_services_lead_type import LocalServicesLeadTypeEnum +from .types.local_services_license_rejection_reason import ( + LocalServicesLicenseRejectionReasonEnum, +) +from .types.local_services_participant_type import ( + LocalServicesParticipantTypeEnum, +) +from .types.local_services_verification_artifact_status import ( + LocalServicesVerificationArtifactStatusEnum, +) +from .types.local_services_verification_artifact_type import ( + LocalServicesVerificationArtifactTypeEnum, +) +from .types.local_services_verification_status import ( + LocalServicesVerificationStatusEnum, +) +from .types.location_group_radius_units import LocationGroupRadiusUnitsEnum +from .types.location_ownership_type import LocationOwnershipTypeEnum +from .types.location_source_type import LocationSourceTypeEnum +from .types.location_string_filter_type import LocationStringFilterTypeEnum +from .types.lookalike_expansion_level import LookalikeExpansionLevelEnum +from .types.manager_link_status import ManagerLinkStatusEnum +from .types.match_type import MatchTypeEnum +from .types.media_type import MediaTypeEnum +from .types.mime_type import MimeTypeEnum +from .types.minute_of_hour import MinuteOfHourEnum +from .types.mobile_app_vendor import MobileAppVendorEnum +from .types.mobile_device_type import MobileDeviceTypeEnum +from .types.month_of_year import MonthOfYearEnum +from .types.negative_geo_target_type import NegativeGeoTargetTypeEnum +from .types.non_skippable_max_duration import NonSkippableMaxDurationEnum +from .types.non_skippable_min_duration import NonSkippableMinDurationEnum +from .types.offline_conversion_diagnostic_status_enum import ( + OfflineConversionDiagnosticStatusEnum, +) +from .types.offline_event_upload_client_enum import OfflineEventUploadClientEnum +from .types.offline_user_data_job_failure_reason import ( + OfflineUserDataJobFailureReasonEnum, +) +from .types.offline_user_data_job_match_rate_range import ( + OfflineUserDataJobMatchRateRangeEnum, +) +from .types.offline_user_data_job_status import OfflineUserDataJobStatusEnum +from .types.offline_user_data_job_type import OfflineUserDataJobTypeEnum +from .types.operating_system_version_operator_type import ( + OperatingSystemVersionOperatorTypeEnum, +) +from .types.optimization_goal_type import OptimizationGoalTypeEnum +from .types.parental_status_type import ParentalStatusTypeEnum +from .types.payment_mode import PaymentModeEnum +from .types.performance_max_upgrade_status import ( + PerformanceMaxUpgradeStatusEnum, +) +from .types.placement_type import PlacementTypeEnum +from .types.policy_approval_status import PolicyApprovalStatusEnum +from .types.policy_review_status import PolicyReviewStatusEnum +from .types.policy_topic_entry_type import PolicyTopicEntryTypeEnum +from .types.policy_topic_evidence_destination_mismatch_url_type import ( + PolicyTopicEvidenceDestinationMismatchUrlTypeEnum, +) +from .types.policy_topic_evidence_destination_not_working_device import ( + PolicyTopicEvidenceDestinationNotWorkingDeviceEnum, +) +from .types.policy_topic_evidence_destination_not_working_dns_error_type import ( + PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum, +) +from .types.positive_geo_target_type import PositiveGeoTargetTypeEnum +from .types.price_extension_price_qualifier import ( + PriceExtensionPriceQualifierEnum, +) +from .types.price_extension_price_unit import PriceExtensionPriceUnitEnum +from .types.price_extension_type import PriceExtensionTypeEnum +from .types.product_availability import ProductAvailabilityEnum +from .types.product_category_level import ProductCategoryLevelEnum +from .types.product_category_state import ProductCategoryStateEnum +from .types.product_channel import ProductChannelEnum +from .types.product_channel_exclusivity import ProductChannelExclusivityEnum +from .types.product_condition import ProductConditionEnum +from .types.product_custom_attribute_index import ( + ProductCustomAttributeIndexEnum, +) +from .types.product_issue_severity import ProductIssueSeverityEnum +from .types.product_link_invitation_status import ( + ProductLinkInvitationStatusEnum, +) +from .types.product_status import ProductStatusEnum +from .types.product_type_level import ProductTypeLevelEnum +from .types.promotion_barcode_type import PromotionBarcodeTypeEnum +from .types.promotion_extension_discount_modifier import ( + PromotionExtensionDiscountModifierEnum, +) +from .types.promotion_extension_occasion import PromotionExtensionOccasionEnum +from .types.proximity_radius_units import ProximityRadiusUnitsEnum +from .types.quality_score_bucket import QualityScoreBucketEnum +from .types.reach_plan_age_range import ReachPlanAgeRangeEnum +from .types.reach_plan_conversion_rate_model import ( + ReachPlanConversionRateModelEnum, +) +from .types.reach_plan_network import ReachPlanNetworkEnum +from .types.reach_plan_plannable_user_list_status import ( + ReachPlanPlannableUserListStatusEnum, +) +from .types.reach_plan_surface import ReachPlanSurfaceEnum +from .types.recommendation_subscription_status import ( + RecommendationSubscriptionStatusEnum, +) +from .types.recommendation_type import RecommendationTypeEnum +from .types.regulatory_fee_type import RegulatoryFeeTypeEnum +from .types.resource_change_operation import ResourceChangeOperationEnum +from .types.resource_limit_type import ResourceLimitTypeEnum +from .types.response_content_type import ResponseContentTypeEnum +from .types.search_engine_results_page_type import ( + SearchEngineResultsPageTypeEnum, +) +from .types.search_term_match_source import SearchTermMatchSourceEnum +from .types.search_term_match_type import SearchTermMatchTypeEnum +from .types.search_term_targeting_status import SearchTermTargetingStatusEnum +from .types.seasonality_event_scope import SeasonalityEventScopeEnum +from .types.seasonality_event_status import SeasonalityEventStatusEnum +from .types.served_asset_field_type import ServedAssetFieldTypeEnum +from .types.shared_set_status import SharedSetStatusEnum +from .types.shared_set_type import SharedSetTypeEnum +from .types.shopping_add_products_to_campaign_recommendation_enum import ( + ShoppingAddProductsToCampaignRecommendationEnum, +) +from .types.simulation_modification_method import ( + SimulationModificationMethodEnum, +) +from .types.simulation_type import SimulationTypeEnum +from .types.sk_ad_network_ad_event_type import SkAdNetworkAdEventTypeEnum +from .types.sk_ad_network_attribution_credit import ( + SkAdNetworkAttributionCreditEnum, +) +from .types.sk_ad_network_coarse_conversion_value import ( + SkAdNetworkCoarseConversionValueEnum, +) +from .types.sk_ad_network_source_type import SkAdNetworkSourceTypeEnum +from .types.sk_ad_network_user_type import SkAdNetworkUserTypeEnum +from .types.slot import SlotEnum +from .types.smart_campaign_not_eligible_reason import ( + SmartCampaignNotEligibleReasonEnum, +) +from .types.smart_campaign_status import SmartCampaignStatusEnum +from .types.spending_limit_type import SpendingLimitTypeEnum +from .types.summary_row_setting import SummaryRowSettingEnum +from .types.system_managed_entity_source import SystemManagedResourceSourceEnum +from .types.target_cpa_opt_in_recommendation_goal import ( + TargetCpaOptInRecommendationGoalEnum, +) +from .types.target_frequency_time_unit import TargetFrequencyTimeUnitEnum +from .types.target_impression_share_location import ( + TargetImpressionShareLocationEnum, +) +from .types.targeting_dimension import TargetingDimensionEnum +from .types.third_party_brand_lift_integration_partner import ( + ThirdPartyBrandLiftIntegrationPartnerEnum, +) +from .types.third_party_brand_safety_integration_partner import ( + ThirdPartyBrandSafetyIntegrationPartnerEnum, +) +from .types.third_party_reach_integration_partner import ( + ThirdPartyReachIntegrationPartnerEnum, +) +from .types.third_party_viewability_integration_partner import ( + ThirdPartyViewabilityIntegrationPartnerEnum, +) +from .types.time_type import TimeTypeEnum +from .types.tracking_code_page_format import TrackingCodePageFormatEnum +from .types.tracking_code_type import TrackingCodeTypeEnum +from .types.unit_of_measure import UnitOfMeasureEnum +from .types.user_identifier_source import UserIdentifierSourceEnum +from .types.user_interest_taxonomy_type import UserInterestTaxonomyTypeEnum +from .types.user_list_access_status import UserListAccessStatusEnum +from .types.user_list_closing_reason import UserListClosingReasonEnum +from .types.user_list_crm_data_source_type import UserListCrmDataSourceTypeEnum +from .types.user_list_customer_type_category import ( + UserListCustomerTypeCategoryEnum, +) +from .types.user_list_date_rule_item_operator import ( + UserListDateRuleItemOperatorEnum, +) +from .types.user_list_flexible_rule_operator import ( + UserListFlexibleRuleOperatorEnum, +) +from .types.user_list_logical_rule_operator import ( + UserListLogicalRuleOperatorEnum, +) +from .types.user_list_membership_status import UserListMembershipStatusEnum +from .types.user_list_number_rule_item_operator import ( + UserListNumberRuleItemOperatorEnum, +) +from .types.user_list_prepopulation_status import ( + UserListPrepopulationStatusEnum, +) +from .types.user_list_rule_type import UserListRuleTypeEnum +from .types.user_list_size_range import UserListSizeRangeEnum +from .types.user_list_string_rule_item_operator import ( + UserListStringRuleItemOperatorEnum, +) +from .types.user_list_type import UserListTypeEnum +from .types.value_rule_device_type import ValueRuleDeviceTypeEnum +from .types.value_rule_geo_location_match_type import ( + ValueRuleGeoLocationMatchTypeEnum, +) +from .types.value_rule_operation import ValueRuleOperationEnum +from .types.value_rule_set_attachment_type import ValueRuleSetAttachmentTypeEnum +from .types.value_rule_set_dimension import ValueRuleSetDimensionEnum +from .types.vanity_pharma_display_url_mode import VanityPharmaDisplayUrlModeEnum +from .types.vanity_pharma_text import VanityPharmaTextEnum +from .types.vertical_ads_item_vertical_type import ( + VerticalAdsItemVerticalTypeEnum, +) +from .types.video_ad_format_restriction import VideoAdFormatRestrictionEnum +from .types.video_ad_sequence_interaction_type import ( + VideoAdSequenceInteractionTypeEnum, +) +from .types.video_ad_sequence_minimum_duration import ( + VideoAdSequenceMinimumDurationEnum, +) +from .types.video_thumbnail import VideoThumbnailEnum +from .types.webpage_condition_operand import WebpageConditionOperandEnum +from .types.webpage_condition_operator import WebpageConditionOperatorEnum +from .types.youtube_video_property import YouTubeVideoPropertyEnum + +if hasattr(api_core, "check_python_version") and hasattr( + api_core, "check_dependency_versions" +): # pragma: NO COVER + api_core.check_python_version("google.ads.googleads.v23") # type: ignore + api_core.check_dependency_versions("google.ads.googleads.v23") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.ads.googleads.v23" + if sys.version_info < (3, 9): + warnings.warn( + "You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning, + ) + if sys.version_info[:2] == (3, 9): + warnings.warn( + f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning, + ) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version( + _dependency_package + ) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn( + f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning, + ) + except Exception: + warnings.warn( + "Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/" + ) + +__all__ = ( + "AccessInvitationStatusEnum", + "AccessReasonEnum", + "AccessRoleEnum", + "AccountBudgetProposalStatusEnum", + "AccountBudgetProposalTypeEnum", + "AccountBudgetStatusEnum", + "AccountLinkStatusEnum", + "AdDestinationTypeEnum", + "AdFormatTypeEnum", + "AdGroupAdPrimaryStatusEnum", + "AdGroupAdPrimaryStatusReasonEnum", + "AdGroupAdRotationModeEnum", + "AdGroupAdStatusEnum", + "AdGroupCriterionApprovalStatusEnum", + "AdGroupCriterionPrimaryStatusEnum", + "AdGroupCriterionPrimaryStatusReasonEnum", + "AdGroupCriterionStatusEnum", + "AdGroupPrimaryStatusEnum", + "AdGroupPrimaryStatusReasonEnum", + "AdGroupStatusEnum", + "AdGroupTypeEnum", + "AdNetworkTypeEnum", + "AdServingOptimizationStatusEnum", + "AdStrengthActionItemTypeEnum", + "AdStrengthEnum", + "AdSubNetworkTypeEnum", + "AdTypeEnum", + "AdvertisingChannelSubTypeEnum", + "AdvertisingChannelTypeEnum", + "AgeRangeTypeEnum", + "AndroidPrivacyInteractionTypeEnum", + "AndroidPrivacyNetworkTypeEnum", + "AppBiddingGoalEnum", + "AppCampaignAppStoreEnum", + "AppCampaignBiddingStrategyGoalTypeEnum", + "AppPaymentModelTypeEnum", + "AppUrlOperatingSystemTypeEnum", + "ApplicationInstanceEnum", + "AssetAutomationStatusEnum", + "AssetAutomationTypeEnum", + "AssetCoverageVideoAspectRatioRequirementEnum", + "AssetFieldTypeEnum", + "AssetGroupPrimaryStatusEnum", + "AssetGroupPrimaryStatusReasonEnum", + "AssetGroupSignalApprovalStatusEnum", + "AssetGroupStatusEnum", + "AssetLinkPrimaryStatusEnum", + "AssetLinkPrimaryStatusReasonEnum", + "AssetLinkStatusEnum", + "AssetOfflineEvaluationErrorReasonsEnum", + "AssetOrientationEnum", + "AssetPerformanceLabelEnum", + "AssetSetAssetStatusEnum", + "AssetSetLinkStatusEnum", + "AssetSetStatusEnum", + "AssetSetTypeEnum", + "AssetSourceEnum", + "AssetTypeEnum", + "AsyncActionStatusEnum", + "AttributionModelEnum", + "AudienceInsightsDimensionEnum", + "AudienceInsightsMarketingObjectiveEnum", + "AudienceScopeEnum", + "AudienceStatusEnum", + "BatchJobStatusEnum", + "BenchmarksMarketingObjectiveEnum", + "BenchmarksSourceTypeEnum", + "BidModifierSourceEnum", + "BiddingSourceEnum", + "BiddingStrategyStatusEnum", + "BiddingStrategySystemStatusEnum", + "BiddingStrategyTypeEnum", + "BillingSetupStatusEnum", + "BrandRequestRejectionReasonEnum", + "BrandSafetySuitabilityEnum", + "BrandStateEnum", + "BudgetCampaignAssociationStatusEnum", + "BudgetDeliveryMethodEnum", + "BudgetPeriodEnum", + "BudgetStatusEnum", + "BudgetTypeEnum", + "BusinessMessageCallToActionTypeEnum", + "BusinessMessageProviderEnum", + "CallConversionReportingStateEnum", + "CallToActionTypeEnum", + "CallTrackingDisplayLocationEnum", + "CallTypeEnum", + "CampaignCriterionStatusEnum", + "CampaignDraftStatusEnum", + "CampaignExperimentTypeEnum", + "CampaignGroupStatusEnum", + "CampaignKeywordMatchTypeEnum", + "CampaignPrimaryStatusEnum", + "CampaignPrimaryStatusReasonEnum", + "CampaignServingStatusEnum", + "CampaignSharedSetStatusEnum", + "CampaignStatusEnum", + "ChainRelationshipTypeEnum", + "ChangeClientTypeEnum", + "ChangeEventResourceTypeEnum", + "ChangeStatusOperationEnum", + "ChangeStatusResourceTypeEnum", + "ClickTypeEnum", + "CombinedAudienceStatusEnum", + "ConsentStatusEnum", + "ContentLabelTypeEnum", + "ConversionActionCategoryEnum", + "ConversionActionCountingTypeEnum", + "ConversionActionStatusEnum", + "ConversionActionTypeEnum", + "ConversionAdjustmentTypeEnum", + "ConversionAttributionEventTypeEnum", + "ConversionCustomVariableStatusEnum", + "ConversionCustomerTypeEnum", + "ConversionEnvironmentEnum", + "ConversionLagBucketEnum", + "ConversionOrAdjustmentLagBucketEnum", + "ConversionOriginEnum", + "ConversionTrackingStatusEnum", + "ConversionValueRulePrimaryDimensionEnum", + "ConversionValueRuleSetStatusEnum", + "ConversionValueRuleStatusEnum", + "ConvertingUserPriorEngagementTypeAndLtvBucketEnum", + "CriterionCategoryChannelAvailabilityModeEnum", + "CriterionCategoryLocaleAvailabilityModeEnum", + "CriterionSystemServingStatusEnum", + "CriterionTypeEnum", + "CustomAudienceMemberTypeEnum", + "CustomAudienceStatusEnum", + "CustomAudienceTypeEnum", + "CustomConversionGoalStatusEnum", + "CustomInterestMemberTypeEnum", + "CustomInterestStatusEnum", + "CustomInterestTypeEnum", + "CustomerAcquisitionOptimizationModeEnum", + "CustomerLifecycleOptimizationModeEnum", + "CustomerMatchUploadKeyTypeEnum", + "CustomerPayPerConversionEligibilityFailureReasonEnum", + "CustomerStatusEnum", + "CustomizerAttributeStatusEnum", + "CustomizerAttributeTypeEnum", + "CustomizerValueStatusEnum", + "DataDrivenModelStatusEnum", + "DataLinkStatusEnum", + "DataLinkTypeEnum", + "DayOfWeekEnum", + "DemandGenChannelConfigEnum", + "DemandGenChannelStrategyEnum", + "DeviceEnum", + "DisplayAdFormatSettingEnum", + "DisplayUploadProductTypeEnum", + "DistanceBucketEnum", + "EuPoliticalAdvertisingStatusEnum", + "ExperimentMetricDirectionEnum", + "ExperimentMetricEnum", + "ExperimentStatusEnum", + "ExperimentTypeEnum", + "ExternalConversionSourceEnum", + "FixedCpmGoalEnum", + "FixedCpmTargetFrequencyTimeUnitEnum", + "FrequencyCapEventTypeEnum", + "FrequencyCapLevelEnum", + "FrequencyCapTimeUnitEnum", + "GenderTypeEnum", + "GeoTargetConstantStatusEnum", + "GeoTargetingTypeEnum", + "GoalConfigLevelEnum", + "GoalOptimizationEligibilityEnum", + "GoalTypeEnum", + "GoogleAdsFieldCategoryEnum", + "GoogleAdsFieldDataTypeEnum", + "GoogleVoiceCallStatusEnum", + "HotelAssetSuggestionStatusEnum", + "HotelDateSelectionTypeEnum", + "HotelPriceBucketEnum", + "HotelRateTypeEnum", + "HotelReconciliationStatusEnum", + "IdentityVerificationProgramEnum", + "IdentityVerificationProgramStatusEnum", + "IncentiveStateEnum", + "IncomeRangeTypeEnum", + "InsightsKnowledgeGraphEntityCapabilitiesEnum", + "InsightsTrendEnum", + "InteractionEventTypeEnum", + "InteractionTypeEnum", + "InvoiceTypeEnum", + "KeywordMatchTypeEnum", + "KeywordPlanAggregateMetricTypeEnum", + "KeywordPlanCompetitionLevelEnum", + "KeywordPlanConceptGroupTypeEnum", + "KeywordPlanForecastIntervalEnum", + "KeywordPlanKeywordAnnotationEnum", + "KeywordPlanNetworkEnum", + "LabelStatusEnum", + "LandingPageSourceEnum", + "LeadFormCallToActionTypeEnum", + "LeadFormDesiredIntentEnum", + "LeadFormFieldUserInputTypeEnum", + "LeadFormPostSubmitCallToActionTypeEnum", + "LegacyAppInstallAdAppStoreEnum", + "LinkedAccountTypeEnum", + "LinkedProductTypeEnum", + "ListingGroupFilterCustomAttributeIndexEnum", + "ListingGroupFilterListingSourceEnum", + "ListingGroupFilterProductCategoryLevelEnum", + "ListingGroupFilterProductChannelEnum", + "ListingGroupFilterProductConditionEnum", + "ListingGroupFilterProductTypeLevelEnum", + "ListingGroupFilterTypeEnum", + "ListingGroupTypeEnum", + "ListingTypeEnum", + "LocalServicesBusinessRegistrationCheckRejectionReasonEnum", + "LocalServicesBusinessRegistrationTypeEnum", + "LocalServicesCreditStateEnum", + "LocalServicesEmployeeStatusEnum", + "LocalServicesEmployeeTypeEnum", + "LocalServicesInsuranceRejectionReasonEnum", + "LocalServicesLeadConversationTypeEnum", + "LocalServicesLeadCreditIssuanceDecisionEnum", + "LocalServicesLeadStatusEnum", + "LocalServicesLeadSurveyAnswerEnum", + "LocalServicesLeadSurveyDissatisfiedReasonEnum", + "LocalServicesLeadSurveySatisfiedReasonEnum", + "LocalServicesLeadTypeEnum", + "LocalServicesLicenseRejectionReasonEnum", + "LocalServicesParticipantTypeEnum", + "LocalServicesVerificationArtifactStatusEnum", + "LocalServicesVerificationArtifactTypeEnum", + "LocalServicesVerificationStatusEnum", + "LocationGroupRadiusUnitsEnum", + "LocationOwnershipTypeEnum", + "LocationSourceTypeEnum", + "LocationStringFilterTypeEnum", + "LookalikeExpansionLevelEnum", + "ManagerLinkStatusEnum", + "MatchTypeEnum", + "MediaTypeEnum", + "MimeTypeEnum", + "MinuteOfHourEnum", + "MobileAppVendorEnum", + "MobileDeviceTypeEnum", + "MonthOfYearEnum", + "NegativeGeoTargetTypeEnum", + "NonSkippableMaxDurationEnum", + "NonSkippableMinDurationEnum", + "OfflineConversionDiagnosticStatusEnum", + "OfflineEventUploadClientEnum", + "OfflineUserDataJobFailureReasonEnum", + "OfflineUserDataJobMatchRateRangeEnum", + "OfflineUserDataJobStatusEnum", + "OfflineUserDataJobTypeEnum", + "OperatingSystemVersionOperatorTypeEnum", + "OptimizationGoalTypeEnum", + "ParentalStatusTypeEnum", + "PaymentModeEnum", + "PerformanceMaxUpgradeStatusEnum", + "PlacementTypeEnum", + "PolicyApprovalStatusEnum", + "PolicyReviewStatusEnum", + "PolicyTopicEntryTypeEnum", + "PolicyTopicEvidenceDestinationMismatchUrlTypeEnum", + "PolicyTopicEvidenceDestinationNotWorkingDeviceEnum", + "PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum", + "PositiveGeoTargetTypeEnum", + "PriceExtensionPriceQualifierEnum", + "PriceExtensionPriceUnitEnum", + "PriceExtensionTypeEnum", + "ProductAvailabilityEnum", + "ProductCategoryLevelEnum", + "ProductCategoryStateEnum", + "ProductChannelEnum", + "ProductChannelExclusivityEnum", + "ProductConditionEnum", + "ProductCustomAttributeIndexEnum", + "ProductIssueSeverityEnum", + "ProductLinkInvitationStatusEnum", + "ProductStatusEnum", + "ProductTypeLevelEnum", + "PromotionBarcodeTypeEnum", + "PromotionExtensionDiscountModifierEnum", + "PromotionExtensionOccasionEnum", + "ProximityRadiusUnitsEnum", + "QualityScoreBucketEnum", + "ReachPlanAgeRangeEnum", + "ReachPlanConversionRateModelEnum", + "ReachPlanNetworkEnum", + "ReachPlanPlannableUserListStatusEnum", + "ReachPlanSurfaceEnum", + "RecommendationSubscriptionStatusEnum", + "RecommendationTypeEnum", + "RegulatoryFeeTypeEnum", + "ResourceChangeOperationEnum", + "ResourceLimitTypeEnum", + "ResponseContentTypeEnum", + "SearchEngineResultsPageTypeEnum", + "SearchTermMatchSourceEnum", + "SearchTermMatchTypeEnum", + "SearchTermTargetingStatusEnum", + "SeasonalityEventScopeEnum", + "SeasonalityEventStatusEnum", + "ServedAssetFieldTypeEnum", + "SharedSetStatusEnum", + "SharedSetTypeEnum", + "ShoppingAddProductsToCampaignRecommendationEnum", + "SimulationModificationMethodEnum", + "SimulationTypeEnum", + "SkAdNetworkAdEventTypeEnum", + "SkAdNetworkAttributionCreditEnum", + "SkAdNetworkCoarseConversionValueEnum", + "SkAdNetworkSourceTypeEnum", + "SkAdNetworkUserTypeEnum", + "SlotEnum", + "SmartCampaignNotEligibleReasonEnum", + "SmartCampaignStatusEnum", + "SpendingLimitTypeEnum", + "SummaryRowSettingEnum", + "SystemManagedResourceSourceEnum", + "TargetCpaOptInRecommendationGoalEnum", + "TargetFrequencyTimeUnitEnum", + "TargetImpressionShareLocationEnum", + "TargetingDimensionEnum", + "ThirdPartyBrandLiftIntegrationPartnerEnum", + "ThirdPartyBrandSafetyIntegrationPartnerEnum", + "ThirdPartyReachIntegrationPartnerEnum", + "ThirdPartyViewabilityIntegrationPartnerEnum", + "TimeTypeEnum", + "TrackingCodePageFormatEnum", + "TrackingCodeTypeEnum", + "UnitOfMeasureEnum", + "UserIdentifierSourceEnum", + "UserInterestTaxonomyTypeEnum", + "UserListAccessStatusEnum", + "UserListClosingReasonEnum", + "UserListCrmDataSourceTypeEnum", + "UserListCustomerTypeCategoryEnum", + "UserListDateRuleItemOperatorEnum", + "UserListFlexibleRuleOperatorEnum", + "UserListLogicalRuleOperatorEnum", + "UserListMembershipStatusEnum", + "UserListNumberRuleItemOperatorEnum", + "UserListPrepopulationStatusEnum", + "UserListRuleTypeEnum", + "UserListSizeRangeEnum", + "UserListStringRuleItemOperatorEnum", + "UserListTypeEnum", + "ValueRuleDeviceTypeEnum", + "ValueRuleGeoLocationMatchTypeEnum", + "ValueRuleOperationEnum", + "ValueRuleSetAttachmentTypeEnum", + "ValueRuleSetDimensionEnum", + "VanityPharmaDisplayUrlModeEnum", + "VanityPharmaTextEnum", + "VerticalAdsItemVerticalTypeEnum", + "VideoAdFormatRestrictionEnum", + "VideoAdSequenceInteractionTypeEnum", + "VideoAdSequenceMinimumDurationEnum", + "VideoThumbnailEnum", + "WebpageConditionOperandEnum", + "WebpageConditionOperatorEnum", + "YouTubeVideoPropertyEnum", +) diff --git a/google/ads/googleads/v19/enums/services/__init__.py b/google/ads/googleads/v23/enums/services/__init__.py similarity index 100% rename from google/ads/googleads/v19/enums/services/__init__.py rename to google/ads/googleads/v23/enums/services/__init__.py diff --git a/google/ads/googleads/v23/enums/types/__init__.py b/google/ads/googleads/v23/enums/types/__init__.py new file mode 100644 index 000000000..2053d0700 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/__init__.py @@ -0,0 +1,1458 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .access_invitation_status import ( + AccessInvitationStatusEnum, +) +from .access_reason import ( + AccessReasonEnum, +) +from .access_role import ( + AccessRoleEnum, +) +from .account_budget_proposal_status import ( + AccountBudgetProposalStatusEnum, +) +from .account_budget_proposal_type import ( + AccountBudgetProposalTypeEnum, +) +from .account_budget_status import ( + AccountBudgetStatusEnum, +) +from .account_link_status import ( + AccountLinkStatusEnum, +) +from .ad_destination_type import ( + AdDestinationTypeEnum, +) +from .ad_format_type import ( + AdFormatTypeEnum, +) +from .ad_group_ad_primary_status import ( + AdGroupAdPrimaryStatusEnum, +) +from .ad_group_ad_primary_status_reason import ( + AdGroupAdPrimaryStatusReasonEnum, +) +from .ad_group_ad_rotation_mode import ( + AdGroupAdRotationModeEnum, +) +from .ad_group_ad_status import ( + AdGroupAdStatusEnum, +) +from .ad_group_criterion_approval_status import ( + AdGroupCriterionApprovalStatusEnum, +) +from .ad_group_criterion_primary_status import ( + AdGroupCriterionPrimaryStatusEnum, +) +from .ad_group_criterion_primary_status_reason import ( + AdGroupCriterionPrimaryStatusReasonEnum, +) +from .ad_group_criterion_status import ( + AdGroupCriterionStatusEnum, +) +from .ad_group_primary_status import ( + AdGroupPrimaryStatusEnum, +) +from .ad_group_primary_status_reason import ( + AdGroupPrimaryStatusReasonEnum, +) +from .ad_group_status import ( + AdGroupStatusEnum, +) +from .ad_group_type import ( + AdGroupTypeEnum, +) +from .ad_network_type import ( + AdNetworkTypeEnum, +) +from .ad_serving_optimization_status import ( + AdServingOptimizationStatusEnum, +) +from .ad_strength import ( + AdStrengthEnum, +) +from .ad_strength_action_item_type import ( + AdStrengthActionItemTypeEnum, +) +from .ad_sub_network_type import ( + AdSubNetworkTypeEnum, +) +from .ad_type import ( + AdTypeEnum, +) +from .advertising_channel_sub_type import ( + AdvertisingChannelSubTypeEnum, +) +from .advertising_channel_type import ( + AdvertisingChannelTypeEnum, +) +from .age_range_type import ( + AgeRangeTypeEnum, +) +from .android_privacy_interaction_type import ( + AndroidPrivacyInteractionTypeEnum, +) +from .android_privacy_network_type import ( + AndroidPrivacyNetworkTypeEnum, +) +from .app_bidding_goal import ( + AppBiddingGoalEnum, +) +from .app_campaign_app_store import ( + AppCampaignAppStoreEnum, +) +from .app_campaign_bidding_strategy_goal_type import ( + AppCampaignBiddingStrategyGoalTypeEnum, +) +from .app_payment_model_type import ( + AppPaymentModelTypeEnum, +) +from .app_url_operating_system_type import ( + AppUrlOperatingSystemTypeEnum, +) +from .application_instance import ( + ApplicationInstanceEnum, +) +from .asset_automation_status import ( + AssetAutomationStatusEnum, +) +from .asset_automation_type import ( + AssetAutomationTypeEnum, +) +from .asset_coverage_video_aspect_ratio_requirement import ( + AssetCoverageVideoAspectRatioRequirementEnum, +) +from .asset_field_type import ( + AssetFieldTypeEnum, +) +from .asset_group_primary_status import ( + AssetGroupPrimaryStatusEnum, +) +from .asset_group_primary_status_reason import ( + AssetGroupPrimaryStatusReasonEnum, +) +from .asset_group_signal_approval_status import ( + AssetGroupSignalApprovalStatusEnum, +) +from .asset_group_status import ( + AssetGroupStatusEnum, +) +from .asset_link_primary_status import ( + AssetLinkPrimaryStatusEnum, +) +from .asset_link_primary_status_reason import ( + AssetLinkPrimaryStatusReasonEnum, +) +from .asset_link_status import ( + AssetLinkStatusEnum, +) +from .asset_offline_evaluation_error_reasons import ( + AssetOfflineEvaluationErrorReasonsEnum, +) +from .asset_orientation import ( + AssetOrientationEnum, +) +from .asset_performance_label import ( + AssetPerformanceLabelEnum, +) +from .asset_set_asset_status import ( + AssetSetAssetStatusEnum, +) +from .asset_set_link_status import ( + AssetSetLinkStatusEnum, +) +from .asset_set_status import ( + AssetSetStatusEnum, +) +from .asset_set_type import ( + AssetSetTypeEnum, +) +from .asset_source import ( + AssetSourceEnum, +) +from .asset_type import ( + AssetTypeEnum, +) +from .async_action_status import ( + AsyncActionStatusEnum, +) +from .attribution_model import ( + AttributionModelEnum, +) +from .audience_insights_dimension import ( + AudienceInsightsDimensionEnum, +) +from .audience_insights_marketing_objective import ( + AudienceInsightsMarketingObjectiveEnum, +) +from .audience_scope import ( + AudienceScopeEnum, +) +from .audience_status import ( + AudienceStatusEnum, +) +from .batch_job_status import ( + BatchJobStatusEnum, +) +from .benchmarks_marketing_objective import ( + BenchmarksMarketingObjectiveEnum, +) +from .benchmarks_source_type import ( + BenchmarksSourceTypeEnum, +) +from .bid_modifier_source import ( + BidModifierSourceEnum, +) +from .bidding_source import ( + BiddingSourceEnum, +) +from .bidding_strategy_status import ( + BiddingStrategyStatusEnum, +) +from .bidding_strategy_system_status import ( + BiddingStrategySystemStatusEnum, +) +from .bidding_strategy_type import ( + BiddingStrategyTypeEnum, +) +from .billing_setup_status import ( + BillingSetupStatusEnum, +) +from .brand_request_rejection_reason import ( + BrandRequestRejectionReasonEnum, +) +from .brand_safety_suitability import ( + BrandSafetySuitabilityEnum, +) +from .brand_state import ( + BrandStateEnum, +) +from .budget_campaign_association_status import ( + BudgetCampaignAssociationStatusEnum, +) +from .budget_delivery_method import ( + BudgetDeliveryMethodEnum, +) +from .budget_period import ( + BudgetPeriodEnum, +) +from .budget_status import ( + BudgetStatusEnum, +) +from .budget_type import ( + BudgetTypeEnum, +) +from .business_message_call_to_action_type import ( + BusinessMessageCallToActionTypeEnum, +) +from .business_message_provider import ( + BusinessMessageProviderEnum, +) +from .call_conversion_reporting_state import ( + CallConversionReportingStateEnum, +) +from .call_to_action_type import ( + CallToActionTypeEnum, +) +from .call_tracking_display_location import ( + CallTrackingDisplayLocationEnum, +) +from .call_type import ( + CallTypeEnum, +) +from .campaign_criterion_status import ( + CampaignCriterionStatusEnum, +) +from .campaign_draft_status import ( + CampaignDraftStatusEnum, +) +from .campaign_experiment_type import ( + CampaignExperimentTypeEnum, +) +from .campaign_group_status import ( + CampaignGroupStatusEnum, +) +from .campaign_keyword_match_type import ( + CampaignKeywordMatchTypeEnum, +) +from .campaign_primary_status import ( + CampaignPrimaryStatusEnum, +) +from .campaign_primary_status_reason import ( + CampaignPrimaryStatusReasonEnum, +) +from .campaign_serving_status import ( + CampaignServingStatusEnum, +) +from .campaign_shared_set_status import ( + CampaignSharedSetStatusEnum, +) +from .campaign_status import ( + CampaignStatusEnum, +) +from .chain_relationship_type import ( + ChainRelationshipTypeEnum, +) +from .change_client_type import ( + ChangeClientTypeEnum, +) +from .change_event_resource_type import ( + ChangeEventResourceTypeEnum, +) +from .change_status_operation import ( + ChangeStatusOperationEnum, +) +from .change_status_resource_type import ( + ChangeStatusResourceTypeEnum, +) +from .click_type import ( + ClickTypeEnum, +) +from .combined_audience_status import ( + CombinedAudienceStatusEnum, +) +from .consent_status import ( + ConsentStatusEnum, +) +from .content_label_type import ( + ContentLabelTypeEnum, +) +from .conversion_action_category import ( + ConversionActionCategoryEnum, +) +from .conversion_action_counting_type import ( + ConversionActionCountingTypeEnum, +) +from .conversion_action_status import ( + ConversionActionStatusEnum, +) +from .conversion_action_type import ( + ConversionActionTypeEnum, +) +from .conversion_adjustment_type import ( + ConversionAdjustmentTypeEnum, +) +from .conversion_attribution_event_type import ( + ConversionAttributionEventTypeEnum, +) +from .conversion_custom_variable_status import ( + ConversionCustomVariableStatusEnum, +) +from .conversion_customer_type import ( + ConversionCustomerTypeEnum, +) +from .conversion_environment_enum import ( + ConversionEnvironmentEnum, +) +from .conversion_lag_bucket import ( + ConversionLagBucketEnum, +) +from .conversion_or_adjustment_lag_bucket import ( + ConversionOrAdjustmentLagBucketEnum, +) +from .conversion_origin import ( + ConversionOriginEnum, +) +from .conversion_tracking_status_enum import ( + ConversionTrackingStatusEnum, +) +from .conversion_value_rule_primary_dimension import ( + ConversionValueRulePrimaryDimensionEnum, +) +from .conversion_value_rule_set_status import ( + ConversionValueRuleSetStatusEnum, +) +from .conversion_value_rule_status import ( + ConversionValueRuleStatusEnum, +) +from .converting_user_prior_engagement_type_and_ltv_bucket import ( + ConvertingUserPriorEngagementTypeAndLtvBucketEnum, +) +from .criterion_category_channel_availability_mode import ( + CriterionCategoryChannelAvailabilityModeEnum, +) +from .criterion_category_locale_availability_mode import ( + CriterionCategoryLocaleAvailabilityModeEnum, +) +from .criterion_system_serving_status import ( + CriterionSystemServingStatusEnum, +) +from .criterion_type import ( + CriterionTypeEnum, +) +from .custom_audience_member_type import ( + CustomAudienceMemberTypeEnum, +) +from .custom_audience_status import ( + CustomAudienceStatusEnum, +) +from .custom_audience_type import ( + CustomAudienceTypeEnum, +) +from .custom_conversion_goal_status import ( + CustomConversionGoalStatusEnum, +) +from .custom_interest_member_type import ( + CustomInterestMemberTypeEnum, +) +from .custom_interest_status import ( + CustomInterestStatusEnum, +) +from .custom_interest_type import ( + CustomInterestTypeEnum, +) +from .customer_acquisition_optimization_mode import ( + CustomerAcquisitionOptimizationModeEnum, +) +from .customer_lifecycle_optimization_mode import ( + CustomerLifecycleOptimizationModeEnum, +) +from .customer_match_upload_key_type import ( + CustomerMatchUploadKeyTypeEnum, +) +from .customer_pay_per_conversion_eligibility_failure_reason import ( + CustomerPayPerConversionEligibilityFailureReasonEnum, +) +from .customer_status import ( + CustomerStatusEnum, +) +from .customizer_attribute_status import ( + CustomizerAttributeStatusEnum, +) +from .customizer_attribute_type import ( + CustomizerAttributeTypeEnum, +) +from .customizer_value_status import ( + CustomizerValueStatusEnum, +) +from .data_driven_model_status import ( + DataDrivenModelStatusEnum, +) +from .data_link_status import ( + DataLinkStatusEnum, +) +from .data_link_type import ( + DataLinkTypeEnum, +) +from .day_of_week import ( + DayOfWeekEnum, +) +from .demand_gen_channel_config import ( + DemandGenChannelConfigEnum, +) +from .demand_gen_channel_strategy import ( + DemandGenChannelStrategyEnum, +) +from .device import ( + DeviceEnum, +) +from .display_ad_format_setting import ( + DisplayAdFormatSettingEnum, +) +from .display_upload_product_type import ( + DisplayUploadProductTypeEnum, +) +from .distance_bucket import ( + DistanceBucketEnum, +) +from .eu_political_advertising_status import ( + EuPoliticalAdvertisingStatusEnum, +) +from .experiment_metric import ( + ExperimentMetricEnum, +) +from .experiment_metric_direction import ( + ExperimentMetricDirectionEnum, +) +from .experiment_status import ( + ExperimentStatusEnum, +) +from .experiment_type import ( + ExperimentTypeEnum, +) +from .external_conversion_source import ( + ExternalConversionSourceEnum, +) +from .fixed_cpm_goal import ( + FixedCpmGoalEnum, +) +from .fixed_cpm_target_frequency_time_unit import ( + FixedCpmTargetFrequencyTimeUnitEnum, +) +from .frequency_cap_event_type import ( + FrequencyCapEventTypeEnum, +) +from .frequency_cap_level import ( + FrequencyCapLevelEnum, +) +from .frequency_cap_time_unit import ( + FrequencyCapTimeUnitEnum, +) +from .gender_type import ( + GenderTypeEnum, +) +from .geo_target_constant_status import ( + GeoTargetConstantStatusEnum, +) +from .geo_targeting_type import ( + GeoTargetingTypeEnum, +) +from .goal_config_level import ( + GoalConfigLevelEnum, +) +from .goal_optimization_eligibility import ( + GoalOptimizationEligibilityEnum, +) +from .goal_type import ( + GoalTypeEnum, +) +from .google_ads_field_category import ( + GoogleAdsFieldCategoryEnum, +) +from .google_ads_field_data_type import ( + GoogleAdsFieldDataTypeEnum, +) +from .google_voice_call_status import ( + GoogleVoiceCallStatusEnum, +) +from .hotel_asset_suggestion_status import ( + HotelAssetSuggestionStatusEnum, +) +from .hotel_date_selection_type import ( + HotelDateSelectionTypeEnum, +) +from .hotel_price_bucket import ( + HotelPriceBucketEnum, +) +from .hotel_rate_type import ( + HotelRateTypeEnum, +) +from .hotel_reconciliation_status import ( + HotelReconciliationStatusEnum, +) +from .identity_verification_program import ( + IdentityVerificationProgramEnum, +) +from .identity_verification_program_status import ( + IdentityVerificationProgramStatusEnum, +) +from .incentive_state import ( + IncentiveStateEnum, +) +from .income_range_type import ( + IncomeRangeTypeEnum, +) +from .insights_knowledge_graph_entity_capabilities import ( + InsightsKnowledgeGraphEntityCapabilitiesEnum, +) +from .insights_trend import ( + InsightsTrendEnum, +) +from .interaction_event_type import ( + InteractionEventTypeEnum, +) +from .interaction_type import ( + InteractionTypeEnum, +) +from .invoice_type import ( + InvoiceTypeEnum, +) +from .keyword_match_type import ( + KeywordMatchTypeEnum, +) +from .keyword_plan_aggregate_metric_type import ( + KeywordPlanAggregateMetricTypeEnum, +) +from .keyword_plan_competition_level import ( + KeywordPlanCompetitionLevelEnum, +) +from .keyword_plan_concept_group_type import ( + KeywordPlanConceptGroupTypeEnum, +) +from .keyword_plan_forecast_interval import ( + KeywordPlanForecastIntervalEnum, +) +from .keyword_plan_keyword_annotation import ( + KeywordPlanKeywordAnnotationEnum, +) +from .keyword_plan_network import ( + KeywordPlanNetworkEnum, +) +from .label_status import ( + LabelStatusEnum, +) +from .landing_page_source import ( + LandingPageSourceEnum, +) +from .lead_form_call_to_action_type import ( + LeadFormCallToActionTypeEnum, +) +from .lead_form_desired_intent import ( + LeadFormDesiredIntentEnum, +) +from .lead_form_field_user_input_type import ( + LeadFormFieldUserInputTypeEnum, +) +from .lead_form_post_submit_call_to_action_type import ( + LeadFormPostSubmitCallToActionTypeEnum, +) +from .legacy_app_install_ad_app_store import ( + LegacyAppInstallAdAppStoreEnum, +) +from .linked_account_type import ( + LinkedAccountTypeEnum, +) +from .linked_product_type import ( + LinkedProductTypeEnum, +) +from .listing_group_filter_custom_attribute_index import ( + ListingGroupFilterCustomAttributeIndexEnum, +) +from .listing_group_filter_listing_source import ( + ListingGroupFilterListingSourceEnum, +) +from .listing_group_filter_product_category_level import ( + ListingGroupFilterProductCategoryLevelEnum, +) +from .listing_group_filter_product_channel import ( + ListingGroupFilterProductChannelEnum, +) +from .listing_group_filter_product_condition import ( + ListingGroupFilterProductConditionEnum, +) +from .listing_group_filter_product_type_level import ( + ListingGroupFilterProductTypeLevelEnum, +) +from .listing_group_filter_type_enum import ( + ListingGroupFilterTypeEnum, +) +from .listing_group_type import ( + ListingGroupTypeEnum, +) +from .listing_type import ( + ListingTypeEnum, +) +from .local_services_business_registration_check_rejection_reason import ( + LocalServicesBusinessRegistrationCheckRejectionReasonEnum, +) +from .local_services_business_registration_type import ( + LocalServicesBusinessRegistrationTypeEnum, +) +from .local_services_conversation_type import ( + LocalServicesLeadConversationTypeEnum, +) +from .local_services_employee_status import ( + LocalServicesEmployeeStatusEnum, +) +from .local_services_employee_type import ( + LocalServicesEmployeeTypeEnum, +) +from .local_services_insurance_rejection_reason import ( + LocalServicesInsuranceRejectionReasonEnum, +) +from .local_services_lead_credit_issuance_decision import ( + LocalServicesLeadCreditIssuanceDecisionEnum, +) +from .local_services_lead_credit_state import ( + LocalServicesCreditStateEnum, +) +from .local_services_lead_status import ( + LocalServicesLeadStatusEnum, +) +from .local_services_lead_survey_answer import ( + LocalServicesLeadSurveyAnswerEnum, +) +from .local_services_lead_survey_dissatisfied_reason import ( + LocalServicesLeadSurveyDissatisfiedReasonEnum, +) +from .local_services_lead_survey_satisfied_reason import ( + LocalServicesLeadSurveySatisfiedReasonEnum, +) +from .local_services_lead_type import ( + LocalServicesLeadTypeEnum, +) +from .local_services_license_rejection_reason import ( + LocalServicesLicenseRejectionReasonEnum, +) +from .local_services_participant_type import ( + LocalServicesParticipantTypeEnum, +) +from .local_services_verification_artifact_status import ( + LocalServicesVerificationArtifactStatusEnum, +) +from .local_services_verification_artifact_type import ( + LocalServicesVerificationArtifactTypeEnum, +) +from .local_services_verification_status import ( + LocalServicesVerificationStatusEnum, +) +from .location_group_radius_units import ( + LocationGroupRadiusUnitsEnum, +) +from .location_ownership_type import ( + LocationOwnershipTypeEnum, +) +from .location_source_type import ( + LocationSourceTypeEnum, +) +from .location_string_filter_type import ( + LocationStringFilterTypeEnum, +) +from .lookalike_expansion_level import ( + LookalikeExpansionLevelEnum, +) +from .manager_link_status import ( + ManagerLinkStatusEnum, +) +from .match_type import ( + MatchTypeEnum, +) +from .media_type import ( + MediaTypeEnum, +) +from .mime_type import ( + MimeTypeEnum, +) +from .minute_of_hour import ( + MinuteOfHourEnum, +) +from .mobile_app_vendor import ( + MobileAppVendorEnum, +) +from .mobile_device_type import ( + MobileDeviceTypeEnum, +) +from .month_of_year import ( + MonthOfYearEnum, +) +from .negative_geo_target_type import ( + NegativeGeoTargetTypeEnum, +) +from .non_skippable_max_duration import ( + NonSkippableMaxDurationEnum, +) +from .non_skippable_min_duration import ( + NonSkippableMinDurationEnum, +) +from .offline_conversion_diagnostic_status_enum import ( + OfflineConversionDiagnosticStatusEnum, +) +from .offline_event_upload_client_enum import ( + OfflineEventUploadClientEnum, +) +from .offline_user_data_job_failure_reason import ( + OfflineUserDataJobFailureReasonEnum, +) +from .offline_user_data_job_match_rate_range import ( + OfflineUserDataJobMatchRateRangeEnum, +) +from .offline_user_data_job_status import ( + OfflineUserDataJobStatusEnum, +) +from .offline_user_data_job_type import ( + OfflineUserDataJobTypeEnum, +) +from .operating_system_version_operator_type import ( + OperatingSystemVersionOperatorTypeEnum, +) +from .optimization_goal_type import ( + OptimizationGoalTypeEnum, +) +from .parental_status_type import ( + ParentalStatusTypeEnum, +) +from .payment_mode import ( + PaymentModeEnum, +) +from .performance_max_upgrade_status import ( + PerformanceMaxUpgradeStatusEnum, +) +from .placement_type import ( + PlacementTypeEnum, +) +from .policy_approval_status import ( + PolicyApprovalStatusEnum, +) +from .policy_review_status import ( + PolicyReviewStatusEnum, +) +from .policy_topic_entry_type import ( + PolicyTopicEntryTypeEnum, +) +from .policy_topic_evidence_destination_mismatch_url_type import ( + PolicyTopicEvidenceDestinationMismatchUrlTypeEnum, +) +from .policy_topic_evidence_destination_not_working_device import ( + PolicyTopicEvidenceDestinationNotWorkingDeviceEnum, +) +from .policy_topic_evidence_destination_not_working_dns_error_type import ( + PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum, +) +from .positive_geo_target_type import ( + PositiveGeoTargetTypeEnum, +) +from .price_extension_price_qualifier import ( + PriceExtensionPriceQualifierEnum, +) +from .price_extension_price_unit import ( + PriceExtensionPriceUnitEnum, +) +from .price_extension_type import ( + PriceExtensionTypeEnum, +) +from .product_availability import ( + ProductAvailabilityEnum, +) +from .product_category_level import ( + ProductCategoryLevelEnum, +) +from .product_category_state import ( + ProductCategoryStateEnum, +) +from .product_channel import ( + ProductChannelEnum, +) +from .product_channel_exclusivity import ( + ProductChannelExclusivityEnum, +) +from .product_condition import ( + ProductConditionEnum, +) +from .product_custom_attribute_index import ( + ProductCustomAttributeIndexEnum, +) +from .product_issue_severity import ( + ProductIssueSeverityEnum, +) +from .product_link_invitation_status import ( + ProductLinkInvitationStatusEnum, +) +from .product_status import ( + ProductStatusEnum, +) +from .product_type_level import ( + ProductTypeLevelEnum, +) +from .promotion_barcode_type import ( + PromotionBarcodeTypeEnum, +) +from .promotion_extension_discount_modifier import ( + PromotionExtensionDiscountModifierEnum, +) +from .promotion_extension_occasion import ( + PromotionExtensionOccasionEnum, +) +from .proximity_radius_units import ( + ProximityRadiusUnitsEnum, +) +from .quality_score_bucket import ( + QualityScoreBucketEnum, +) +from .reach_plan_age_range import ( + ReachPlanAgeRangeEnum, +) +from .reach_plan_conversion_rate_model import ( + ReachPlanConversionRateModelEnum, +) +from .reach_plan_network import ( + ReachPlanNetworkEnum, +) +from .reach_plan_plannable_user_list_status import ( + ReachPlanPlannableUserListStatusEnum, +) +from .reach_plan_surface import ( + ReachPlanSurfaceEnum, +) +from .recommendation_subscription_status import ( + RecommendationSubscriptionStatusEnum, +) +from .recommendation_type import ( + RecommendationTypeEnum, +) +from .regulatory_fee_type import ( + RegulatoryFeeTypeEnum, +) +from .resource_change_operation import ( + ResourceChangeOperationEnum, +) +from .resource_limit_type import ( + ResourceLimitTypeEnum, +) +from .response_content_type import ( + ResponseContentTypeEnum, +) +from .search_engine_results_page_type import ( + SearchEngineResultsPageTypeEnum, +) +from .search_term_match_source import ( + SearchTermMatchSourceEnum, +) +from .search_term_match_type import ( + SearchTermMatchTypeEnum, +) +from .search_term_targeting_status import ( + SearchTermTargetingStatusEnum, +) +from .seasonality_event_scope import ( + SeasonalityEventScopeEnum, +) +from .seasonality_event_status import ( + SeasonalityEventStatusEnum, +) +from .served_asset_field_type import ( + ServedAssetFieldTypeEnum, +) +from .shared_set_status import ( + SharedSetStatusEnum, +) +from .shared_set_type import ( + SharedSetTypeEnum, +) +from .shopping_add_products_to_campaign_recommendation_enum import ( + ShoppingAddProductsToCampaignRecommendationEnum, +) +from .simulation_modification_method import ( + SimulationModificationMethodEnum, +) +from .simulation_type import ( + SimulationTypeEnum, +) +from .sk_ad_network_ad_event_type import ( + SkAdNetworkAdEventTypeEnum, +) +from .sk_ad_network_attribution_credit import ( + SkAdNetworkAttributionCreditEnum, +) +from .sk_ad_network_coarse_conversion_value import ( + SkAdNetworkCoarseConversionValueEnum, +) +from .sk_ad_network_source_type import ( + SkAdNetworkSourceTypeEnum, +) +from .sk_ad_network_user_type import ( + SkAdNetworkUserTypeEnum, +) +from .slot import ( + SlotEnum, +) +from .smart_campaign_not_eligible_reason import ( + SmartCampaignNotEligibleReasonEnum, +) +from .smart_campaign_status import ( + SmartCampaignStatusEnum, +) +from .spending_limit_type import ( + SpendingLimitTypeEnum, +) +from .summary_row_setting import ( + SummaryRowSettingEnum, +) +from .system_managed_entity_source import ( + SystemManagedResourceSourceEnum, +) +from .target_cpa_opt_in_recommendation_goal import ( + TargetCpaOptInRecommendationGoalEnum, +) +from .target_frequency_time_unit import ( + TargetFrequencyTimeUnitEnum, +) +from .target_impression_share_location import ( + TargetImpressionShareLocationEnum, +) +from .targeting_dimension import ( + TargetingDimensionEnum, +) +from .third_party_brand_lift_integration_partner import ( + ThirdPartyBrandLiftIntegrationPartnerEnum, +) +from .third_party_brand_safety_integration_partner import ( + ThirdPartyBrandSafetyIntegrationPartnerEnum, +) +from .third_party_reach_integration_partner import ( + ThirdPartyReachIntegrationPartnerEnum, +) +from .third_party_viewability_integration_partner import ( + ThirdPartyViewabilityIntegrationPartnerEnum, +) +from .time_type import ( + TimeTypeEnum, +) +from .tracking_code_page_format import ( + TrackingCodePageFormatEnum, +) +from .tracking_code_type import ( + TrackingCodeTypeEnum, +) +from .unit_of_measure import ( + UnitOfMeasureEnum, +) +from .user_identifier_source import ( + UserIdentifierSourceEnum, +) +from .user_interest_taxonomy_type import ( + UserInterestTaxonomyTypeEnum, +) +from .user_list_access_status import ( + UserListAccessStatusEnum, +) +from .user_list_closing_reason import ( + UserListClosingReasonEnum, +) +from .user_list_crm_data_source_type import ( + UserListCrmDataSourceTypeEnum, +) +from .user_list_customer_type_category import ( + UserListCustomerTypeCategoryEnum, +) +from .user_list_date_rule_item_operator import ( + UserListDateRuleItemOperatorEnum, +) +from .user_list_flexible_rule_operator import ( + UserListFlexibleRuleOperatorEnum, +) +from .user_list_logical_rule_operator import ( + UserListLogicalRuleOperatorEnum, +) +from .user_list_membership_status import ( + UserListMembershipStatusEnum, +) +from .user_list_number_rule_item_operator import ( + UserListNumberRuleItemOperatorEnum, +) +from .user_list_prepopulation_status import ( + UserListPrepopulationStatusEnum, +) +from .user_list_rule_type import ( + UserListRuleTypeEnum, +) +from .user_list_size_range import ( + UserListSizeRangeEnum, +) +from .user_list_string_rule_item_operator import ( + UserListStringRuleItemOperatorEnum, +) +from .user_list_type import ( + UserListTypeEnum, +) +from .value_rule_device_type import ( + ValueRuleDeviceTypeEnum, +) +from .value_rule_geo_location_match_type import ( + ValueRuleGeoLocationMatchTypeEnum, +) +from .value_rule_operation import ( + ValueRuleOperationEnum, +) +from .value_rule_set_attachment_type import ( + ValueRuleSetAttachmentTypeEnum, +) +from .value_rule_set_dimension import ( + ValueRuleSetDimensionEnum, +) +from .vanity_pharma_display_url_mode import ( + VanityPharmaDisplayUrlModeEnum, +) +from .vanity_pharma_text import ( + VanityPharmaTextEnum, +) +from .vertical_ads_item_vertical_type import ( + VerticalAdsItemVerticalTypeEnum, +) +from .video_ad_format_restriction import ( + VideoAdFormatRestrictionEnum, +) +from .video_ad_sequence_interaction_type import ( + VideoAdSequenceInteractionTypeEnum, +) +from .video_ad_sequence_minimum_duration import ( + VideoAdSequenceMinimumDurationEnum, +) +from .video_thumbnail import ( + VideoThumbnailEnum, +) +from .webpage_condition_operand import ( + WebpageConditionOperandEnum, +) +from .webpage_condition_operator import ( + WebpageConditionOperatorEnum, +) +from .youtube_video_property import ( + YouTubeVideoPropertyEnum, +) + +__all__ = ( + "AccessInvitationStatusEnum", + "AccessReasonEnum", + "AccessRoleEnum", + "AccountBudgetProposalStatusEnum", + "AccountBudgetProposalTypeEnum", + "AccountBudgetStatusEnum", + "AccountLinkStatusEnum", + "AdDestinationTypeEnum", + "AdFormatTypeEnum", + "AdGroupAdPrimaryStatusEnum", + "AdGroupAdPrimaryStatusReasonEnum", + "AdGroupAdRotationModeEnum", + "AdGroupAdStatusEnum", + "AdGroupCriterionApprovalStatusEnum", + "AdGroupCriterionPrimaryStatusEnum", + "AdGroupCriterionPrimaryStatusReasonEnum", + "AdGroupCriterionStatusEnum", + "AdGroupPrimaryStatusEnum", + "AdGroupPrimaryStatusReasonEnum", + "AdGroupStatusEnum", + "AdGroupTypeEnum", + "AdNetworkTypeEnum", + "AdServingOptimizationStatusEnum", + "AdStrengthEnum", + "AdStrengthActionItemTypeEnum", + "AdSubNetworkTypeEnum", + "AdTypeEnum", + "AdvertisingChannelSubTypeEnum", + "AdvertisingChannelTypeEnum", + "AgeRangeTypeEnum", + "AndroidPrivacyInteractionTypeEnum", + "AndroidPrivacyNetworkTypeEnum", + "AppBiddingGoalEnum", + "AppCampaignAppStoreEnum", + "AppCampaignBiddingStrategyGoalTypeEnum", + "AppPaymentModelTypeEnum", + "AppUrlOperatingSystemTypeEnum", + "ApplicationInstanceEnum", + "AssetAutomationStatusEnum", + "AssetAutomationTypeEnum", + "AssetCoverageVideoAspectRatioRequirementEnum", + "AssetFieldTypeEnum", + "AssetGroupPrimaryStatusEnum", + "AssetGroupPrimaryStatusReasonEnum", + "AssetGroupSignalApprovalStatusEnum", + "AssetGroupStatusEnum", + "AssetLinkPrimaryStatusEnum", + "AssetLinkPrimaryStatusReasonEnum", + "AssetLinkStatusEnum", + "AssetOfflineEvaluationErrorReasonsEnum", + "AssetOrientationEnum", + "AssetPerformanceLabelEnum", + "AssetSetAssetStatusEnum", + "AssetSetLinkStatusEnum", + "AssetSetStatusEnum", + "AssetSetTypeEnum", + "AssetSourceEnum", + "AssetTypeEnum", + "AsyncActionStatusEnum", + "AttributionModelEnum", + "AudienceInsightsDimensionEnum", + "AudienceInsightsMarketingObjectiveEnum", + "AudienceScopeEnum", + "AudienceStatusEnum", + "BatchJobStatusEnum", + "BenchmarksMarketingObjectiveEnum", + "BenchmarksSourceTypeEnum", + "BidModifierSourceEnum", + "BiddingSourceEnum", + "BiddingStrategyStatusEnum", + "BiddingStrategySystemStatusEnum", + "BiddingStrategyTypeEnum", + "BillingSetupStatusEnum", + "BrandRequestRejectionReasonEnum", + "BrandSafetySuitabilityEnum", + "BrandStateEnum", + "BudgetCampaignAssociationStatusEnum", + "BudgetDeliveryMethodEnum", + "BudgetPeriodEnum", + "BudgetStatusEnum", + "BudgetTypeEnum", + "BusinessMessageCallToActionTypeEnum", + "BusinessMessageProviderEnum", + "CallConversionReportingStateEnum", + "CallToActionTypeEnum", + "CallTrackingDisplayLocationEnum", + "CallTypeEnum", + "CampaignCriterionStatusEnum", + "CampaignDraftStatusEnum", + "CampaignExperimentTypeEnum", + "CampaignGroupStatusEnum", + "CampaignKeywordMatchTypeEnum", + "CampaignPrimaryStatusEnum", + "CampaignPrimaryStatusReasonEnum", + "CampaignServingStatusEnum", + "CampaignSharedSetStatusEnum", + "CampaignStatusEnum", + "ChainRelationshipTypeEnum", + "ChangeClientTypeEnum", + "ChangeEventResourceTypeEnum", + "ChangeStatusOperationEnum", + "ChangeStatusResourceTypeEnum", + "ClickTypeEnum", + "CombinedAudienceStatusEnum", + "ConsentStatusEnum", + "ContentLabelTypeEnum", + "ConversionActionCategoryEnum", + "ConversionActionCountingTypeEnum", + "ConversionActionStatusEnum", + "ConversionActionTypeEnum", + "ConversionAdjustmentTypeEnum", + "ConversionAttributionEventTypeEnum", + "ConversionCustomVariableStatusEnum", + "ConversionCustomerTypeEnum", + "ConversionEnvironmentEnum", + "ConversionLagBucketEnum", + "ConversionOrAdjustmentLagBucketEnum", + "ConversionOriginEnum", + "ConversionTrackingStatusEnum", + "ConversionValueRulePrimaryDimensionEnum", + "ConversionValueRuleSetStatusEnum", + "ConversionValueRuleStatusEnum", + "ConvertingUserPriorEngagementTypeAndLtvBucketEnum", + "CriterionCategoryChannelAvailabilityModeEnum", + "CriterionCategoryLocaleAvailabilityModeEnum", + "CriterionSystemServingStatusEnum", + "CriterionTypeEnum", + "CustomAudienceMemberTypeEnum", + "CustomAudienceStatusEnum", + "CustomAudienceTypeEnum", + "CustomConversionGoalStatusEnum", + "CustomInterestMemberTypeEnum", + "CustomInterestStatusEnum", + "CustomInterestTypeEnum", + "CustomerAcquisitionOptimizationModeEnum", + "CustomerLifecycleOptimizationModeEnum", + "CustomerMatchUploadKeyTypeEnum", + "CustomerPayPerConversionEligibilityFailureReasonEnum", + "CustomerStatusEnum", + "CustomizerAttributeStatusEnum", + "CustomizerAttributeTypeEnum", + "CustomizerValueStatusEnum", + "DataDrivenModelStatusEnum", + "DataLinkStatusEnum", + "DataLinkTypeEnum", + "DayOfWeekEnum", + "DemandGenChannelConfigEnum", + "DemandGenChannelStrategyEnum", + "DeviceEnum", + "DisplayAdFormatSettingEnum", + "DisplayUploadProductTypeEnum", + "DistanceBucketEnum", + "EuPoliticalAdvertisingStatusEnum", + "ExperimentMetricEnum", + "ExperimentMetricDirectionEnum", + "ExperimentStatusEnum", + "ExperimentTypeEnum", + "ExternalConversionSourceEnum", + "FixedCpmGoalEnum", + "FixedCpmTargetFrequencyTimeUnitEnum", + "FrequencyCapEventTypeEnum", + "FrequencyCapLevelEnum", + "FrequencyCapTimeUnitEnum", + "GenderTypeEnum", + "GeoTargetConstantStatusEnum", + "GeoTargetingTypeEnum", + "GoalConfigLevelEnum", + "GoalOptimizationEligibilityEnum", + "GoalTypeEnum", + "GoogleAdsFieldCategoryEnum", + "GoogleAdsFieldDataTypeEnum", + "GoogleVoiceCallStatusEnum", + "HotelAssetSuggestionStatusEnum", + "HotelDateSelectionTypeEnum", + "HotelPriceBucketEnum", + "HotelRateTypeEnum", + "HotelReconciliationStatusEnum", + "IdentityVerificationProgramEnum", + "IdentityVerificationProgramStatusEnum", + "IncentiveStateEnum", + "IncomeRangeTypeEnum", + "InsightsKnowledgeGraphEntityCapabilitiesEnum", + "InsightsTrendEnum", + "InteractionEventTypeEnum", + "InteractionTypeEnum", + "InvoiceTypeEnum", + "KeywordMatchTypeEnum", + "KeywordPlanAggregateMetricTypeEnum", + "KeywordPlanCompetitionLevelEnum", + "KeywordPlanConceptGroupTypeEnum", + "KeywordPlanForecastIntervalEnum", + "KeywordPlanKeywordAnnotationEnum", + "KeywordPlanNetworkEnum", + "LabelStatusEnum", + "LandingPageSourceEnum", + "LeadFormCallToActionTypeEnum", + "LeadFormDesiredIntentEnum", + "LeadFormFieldUserInputTypeEnum", + "LeadFormPostSubmitCallToActionTypeEnum", + "LegacyAppInstallAdAppStoreEnum", + "LinkedAccountTypeEnum", + "LinkedProductTypeEnum", + "ListingGroupFilterCustomAttributeIndexEnum", + "ListingGroupFilterListingSourceEnum", + "ListingGroupFilterProductCategoryLevelEnum", + "ListingGroupFilterProductChannelEnum", + "ListingGroupFilterProductConditionEnum", + "ListingGroupFilterProductTypeLevelEnum", + "ListingGroupFilterTypeEnum", + "ListingGroupTypeEnum", + "ListingTypeEnum", + "LocalServicesBusinessRegistrationCheckRejectionReasonEnum", + "LocalServicesBusinessRegistrationTypeEnum", + "LocalServicesLeadConversationTypeEnum", + "LocalServicesEmployeeStatusEnum", + "LocalServicesEmployeeTypeEnum", + "LocalServicesInsuranceRejectionReasonEnum", + "LocalServicesLeadCreditIssuanceDecisionEnum", + "LocalServicesCreditStateEnum", + "LocalServicesLeadStatusEnum", + "LocalServicesLeadSurveyAnswerEnum", + "LocalServicesLeadSurveyDissatisfiedReasonEnum", + "LocalServicesLeadSurveySatisfiedReasonEnum", + "LocalServicesLeadTypeEnum", + "LocalServicesLicenseRejectionReasonEnum", + "LocalServicesParticipantTypeEnum", + "LocalServicesVerificationArtifactStatusEnum", + "LocalServicesVerificationArtifactTypeEnum", + "LocalServicesVerificationStatusEnum", + "LocationGroupRadiusUnitsEnum", + "LocationOwnershipTypeEnum", + "LocationSourceTypeEnum", + "LocationStringFilterTypeEnum", + "LookalikeExpansionLevelEnum", + "ManagerLinkStatusEnum", + "MatchTypeEnum", + "MediaTypeEnum", + "MimeTypeEnum", + "MinuteOfHourEnum", + "MobileAppVendorEnum", + "MobileDeviceTypeEnum", + "MonthOfYearEnum", + "NegativeGeoTargetTypeEnum", + "NonSkippableMaxDurationEnum", + "NonSkippableMinDurationEnum", + "OfflineConversionDiagnosticStatusEnum", + "OfflineEventUploadClientEnum", + "OfflineUserDataJobFailureReasonEnum", + "OfflineUserDataJobMatchRateRangeEnum", + "OfflineUserDataJobStatusEnum", + "OfflineUserDataJobTypeEnum", + "OperatingSystemVersionOperatorTypeEnum", + "OptimizationGoalTypeEnum", + "ParentalStatusTypeEnum", + "PaymentModeEnum", + "PerformanceMaxUpgradeStatusEnum", + "PlacementTypeEnum", + "PolicyApprovalStatusEnum", + "PolicyReviewStatusEnum", + "PolicyTopicEntryTypeEnum", + "PolicyTopicEvidenceDestinationMismatchUrlTypeEnum", + "PolicyTopicEvidenceDestinationNotWorkingDeviceEnum", + "PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum", + "PositiveGeoTargetTypeEnum", + "PriceExtensionPriceQualifierEnum", + "PriceExtensionPriceUnitEnum", + "PriceExtensionTypeEnum", + "ProductAvailabilityEnum", + "ProductCategoryLevelEnum", + "ProductCategoryStateEnum", + "ProductChannelEnum", + "ProductChannelExclusivityEnum", + "ProductConditionEnum", + "ProductCustomAttributeIndexEnum", + "ProductIssueSeverityEnum", + "ProductLinkInvitationStatusEnum", + "ProductStatusEnum", + "ProductTypeLevelEnum", + "PromotionBarcodeTypeEnum", + "PromotionExtensionDiscountModifierEnum", + "PromotionExtensionOccasionEnum", + "ProximityRadiusUnitsEnum", + "QualityScoreBucketEnum", + "ReachPlanAgeRangeEnum", + "ReachPlanConversionRateModelEnum", + "ReachPlanNetworkEnum", + "ReachPlanPlannableUserListStatusEnum", + "ReachPlanSurfaceEnum", + "RecommendationSubscriptionStatusEnum", + "RecommendationTypeEnum", + "RegulatoryFeeTypeEnum", + "ResourceChangeOperationEnum", + "ResourceLimitTypeEnum", + "ResponseContentTypeEnum", + "SearchEngineResultsPageTypeEnum", + "SearchTermMatchSourceEnum", + "SearchTermMatchTypeEnum", + "SearchTermTargetingStatusEnum", + "SeasonalityEventScopeEnum", + "SeasonalityEventStatusEnum", + "ServedAssetFieldTypeEnum", + "SharedSetStatusEnum", + "SharedSetTypeEnum", + "ShoppingAddProductsToCampaignRecommendationEnum", + "SimulationModificationMethodEnum", + "SimulationTypeEnum", + "SkAdNetworkAdEventTypeEnum", + "SkAdNetworkAttributionCreditEnum", + "SkAdNetworkCoarseConversionValueEnum", + "SkAdNetworkSourceTypeEnum", + "SkAdNetworkUserTypeEnum", + "SlotEnum", + "SmartCampaignNotEligibleReasonEnum", + "SmartCampaignStatusEnum", + "SpendingLimitTypeEnum", + "SummaryRowSettingEnum", + "SystemManagedResourceSourceEnum", + "TargetCpaOptInRecommendationGoalEnum", + "TargetFrequencyTimeUnitEnum", + "TargetImpressionShareLocationEnum", + "TargetingDimensionEnum", + "ThirdPartyBrandLiftIntegrationPartnerEnum", + "ThirdPartyBrandSafetyIntegrationPartnerEnum", + "ThirdPartyReachIntegrationPartnerEnum", + "ThirdPartyViewabilityIntegrationPartnerEnum", + "TimeTypeEnum", + "TrackingCodePageFormatEnum", + "TrackingCodeTypeEnum", + "UnitOfMeasureEnum", + "UserIdentifierSourceEnum", + "UserInterestTaxonomyTypeEnum", + "UserListAccessStatusEnum", + "UserListClosingReasonEnum", + "UserListCrmDataSourceTypeEnum", + "UserListCustomerTypeCategoryEnum", + "UserListDateRuleItemOperatorEnum", + "UserListFlexibleRuleOperatorEnum", + "UserListLogicalRuleOperatorEnum", + "UserListMembershipStatusEnum", + "UserListNumberRuleItemOperatorEnum", + "UserListPrepopulationStatusEnum", + "UserListRuleTypeEnum", + "UserListSizeRangeEnum", + "UserListStringRuleItemOperatorEnum", + "UserListTypeEnum", + "ValueRuleDeviceTypeEnum", + "ValueRuleGeoLocationMatchTypeEnum", + "ValueRuleOperationEnum", + "ValueRuleSetAttachmentTypeEnum", + "ValueRuleSetDimensionEnum", + "VanityPharmaDisplayUrlModeEnum", + "VanityPharmaTextEnum", + "VerticalAdsItemVerticalTypeEnum", + "VideoAdFormatRestrictionEnum", + "VideoAdSequenceInteractionTypeEnum", + "VideoAdSequenceMinimumDurationEnum", + "VideoThumbnailEnum", + "WebpageConditionOperandEnum", + "WebpageConditionOperatorEnum", + "YouTubeVideoPropertyEnum", +) diff --git a/google/ads/googleads/v19/enums/types/access_invitation_status.py b/google/ads/googleads/v23/enums/types/access_invitation_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/access_invitation_status.py rename to google/ads/googleads/v23/enums/types/access_invitation_status.py index c6a657650..283d02a91 100644 --- a/google/ads/googleads/v19/enums/types/access_invitation_status.py +++ b/google/ads/googleads/v23/enums/types/access_invitation_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AccessInvitationStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/access_reason.py b/google/ads/googleads/v23/enums/types/access_reason.py similarity index 95% rename from google/ads/googleads/v19/enums/types/access_reason.py rename to google/ads/googleads/v23/enums/types/access_reason.py index b95897902..cf4b51191 100644 --- a/google/ads/googleads/v19/enums/types/access_reason.py +++ b/google/ads/googleads/v23/enums/types/access_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AccessReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/access_role.py b/google/ads/googleads/v23/enums/types/access_role.py similarity index 95% rename from google/ads/googleads/v19/enums/types/access_role.py rename to google/ads/googleads/v23/enums/types/access_role.py index 964637721..f832475dc 100644 --- a/google/ads/googleads/v19/enums/types/access_role.py +++ b/google/ads/googleads/v23/enums/types/access_role.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AccessRoleEnum", }, diff --git a/google/ads/googleads/v19/enums/types/account_budget_proposal_status.py b/google/ads/googleads/v23/enums/types/account_budget_proposal_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/account_budget_proposal_status.py rename to google/ads/googleads/v23/enums/types/account_budget_proposal_status.py index 954c13675..11f8c04c7 100644 --- a/google/ads/googleads/v19/enums/types/account_budget_proposal_status.py +++ b/google/ads/googleads/v23/enums/types/account_budget_proposal_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AccountBudgetProposalStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/account_budget_proposal_type.py b/google/ads/googleads/v23/enums/types/account_budget_proposal_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/account_budget_proposal_type.py rename to google/ads/googleads/v23/enums/types/account_budget_proposal_type.py index b86f98704..f16a55007 100644 --- a/google/ads/googleads/v19/enums/types/account_budget_proposal_type.py +++ b/google/ads/googleads/v23/enums/types/account_budget_proposal_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AccountBudgetProposalTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/account_budget_status.py b/google/ads/googleads/v23/enums/types/account_budget_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/account_budget_status.py rename to google/ads/googleads/v23/enums/types/account_budget_status.py index 157e9fd7a..963127e6b 100644 --- a/google/ads/googleads/v19/enums/types/account_budget_status.py +++ b/google/ads/googleads/v23/enums/types/account_budget_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AccountBudgetStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/account_link_status.py b/google/ads/googleads/v23/enums/types/account_link_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/account_link_status.py rename to google/ads/googleads/v23/enums/types/account_link_status.py index 571bc1796..510dcb664 100644 --- a/google/ads/googleads/v19/enums/types/account_link_status.py +++ b/google/ads/googleads/v23/enums/types/account_link_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AccountLinkStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_destination_type.py b/google/ads/googleads/v23/enums/types/ad_destination_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/ad_destination_type.py rename to google/ads/googleads/v23/enums/types/ad_destination_type.py index 7003a6e46..1238f0ae7 100644 --- a/google/ads/googleads/v19/enums/types/ad_destination_type.py +++ b/google/ads/googleads/v23/enums/types/ad_destination_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdDestinationTypeEnum", }, diff --git a/google/ads/googleads/v23/enums/types/ad_format_type.py b/google/ads/googleads/v23/enums/types/ad_format_type.py new file mode 100644 index 000000000..d9f86b648 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/ad_format_type.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "AdFormatTypeEnum", + }, +) + + +class AdFormatTypeEnum(proto.Message): + r"""Container for enumeration of Google Ads format types.""" + + class AdFormatType(proto.Enum): + r"""Enumerates Google Ads format types. + + Note that this segmentation is available only for Video and + Demand Gen campaigns. For assets, only video assets are + supported. + + Values: + UNSPECIFIED (0): + No value has been specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + OTHER (2): + Value assigned to formats (such as + experimental formats) which don't support format + segmentation in Video and Demand Gen campaigns. + + Note that these formats may change categories in + the future, for example if an experimental + format is exposed or a new format is added. We + strongly recommend to not rely on this field for + long term decisions. + UNSEGMENTED (3): + Value assigned for Video TrueView for Action + campaigns statistics. + Note that statistics with this value may change + categories in the future, for example if format + segmentation support is added for new campaign + types. We strongly recommend to not rely on this + field for long term decisions. + INSTREAM_SKIPPABLE (4): + Skippable in-stream ads. + INSTREAM_NON_SKIPPABLE (5): + Non-skippable in-stream ads. + INFEED (6): + In-feed YouTube or image ads served on feed + surfaces (e.g. Discover Feed, YouTube Home, + etc.). + BUMPER (7): + Short (<7 secs) in-stream non-skippable + YouTube ads. + OUTSTREAM (8): + Outstream ads. + MASTHEAD (9): + Masthead ads. + AUDIO (10): + Audio ads. + SHORTS (11): + Vertical full-screen video or image ads + served on YouTube Shorts or BrandConnect ads + served as organic YouTube Shorts. + PAUSE (12): + Image ads served when a user pauses an + organic YouTube video on a TV screen. These ads + are displayed directly next to the static video + frame on the pause screen itself. Note that this + does not include Demand Gen image ads served on + the ad panel below or on top of a paused organic + video. Those are reported under INFEED. + VERTICAL_ADS_PROMOTION (13): + An ad format that promotes a specific entity + within a vertical, for example, a hotel ad in + the Travel vertical on Search. + VERTICAL_ADS_BOOKING_LINK (14): + An ad format for a booking link + call-to-action within a vertical ad, for example + a 'Book Now' link for a hotel ad. + TEXT (15): + A standard text ad format. This is currently + only used for ads on the Search network. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + OTHER = 2 + UNSEGMENTED = 3 + INSTREAM_SKIPPABLE = 4 + INSTREAM_NON_SKIPPABLE = 5 + INFEED = 6 + BUMPER = 7 + OUTSTREAM = 8 + MASTHEAD = 9 + AUDIO = 10 + SHORTS = 11 + PAUSE = 12 + VERTICAL_ADS_PROMOTION = 13 + VERTICAL_ADS_BOOKING_LINK = 14 + TEXT = 15 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/ad_group_ad_primary_status.py b/google/ads/googleads/v23/enums/types/ad_group_ad_primary_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/ad_group_ad_primary_status.py rename to google/ads/googleads/v23/enums/types/ad_group_ad_primary_status.py index b02ff6961..0de0708f7 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_ad_primary_status.py +++ b/google/ads/googleads/v23/enums/types/ad_group_ad_primary_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAdPrimaryStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_group_ad_primary_status_reason.py b/google/ads/googleads/v23/enums/types/ad_group_ad_primary_status_reason.py similarity index 98% rename from google/ads/googleads/v19/enums/types/ad_group_ad_primary_status_reason.py rename to google/ads/googleads/v23/enums/types/ad_group_ad_primary_status_reason.py index 3f0a9e797..6154cc191 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_ad_primary_status_reason.py +++ b/google/ads/googleads/v23/enums/types/ad_group_ad_primary_status_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAdPrimaryStatusReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_group_ad_rotation_mode.py b/google/ads/googleads/v23/enums/types/ad_group_ad_rotation_mode.py similarity index 94% rename from google/ads/googleads/v19/enums/types/ad_group_ad_rotation_mode.py rename to google/ads/googleads/v23/enums/types/ad_group_ad_rotation_mode.py index 91fbab537..ac6c16753 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_ad_rotation_mode.py +++ b/google/ads/googleads/v23/enums/types/ad_group_ad_rotation_mode.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAdRotationModeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_group_ad_status.py b/google/ads/googleads/v23/enums/types/ad_group_ad_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/ad_group_ad_status.py rename to google/ads/googleads/v23/enums/types/ad_group_ad_status.py index e269b6a19..d11e58667 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_ad_status.py +++ b/google/ads/googleads/v23/enums/types/ad_group_ad_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAdStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_group_criterion_approval_status.py b/google/ads/googleads/v23/enums/types/ad_group_criterion_approval_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/ad_group_criterion_approval_status.py rename to google/ads/googleads/v23/enums/types/ad_group_criterion_approval_status.py index d0aea7db2..c561a5bb7 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_criterion_approval_status.py +++ b/google/ads/googleads/v23/enums/types/ad_group_criterion_approval_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCriterionApprovalStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_group_criterion_primary_status.py b/google/ads/googleads/v23/enums/types/ad_group_criterion_primary_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/ad_group_criterion_primary_status.py rename to google/ads/googleads/v23/enums/types/ad_group_criterion_primary_status.py index ee36756ba..97e7c8e94 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_criterion_primary_status.py +++ b/google/ads/googleads/v23/enums/types/ad_group_criterion_primary_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCriterionPrimaryStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_group_criterion_primary_status_reason.py b/google/ads/googleads/v23/enums/types/ad_group_criterion_primary_status_reason.py similarity index 98% rename from google/ads/googleads/v19/enums/types/ad_group_criterion_primary_status_reason.py rename to google/ads/googleads/v23/enums/types/ad_group_criterion_primary_status_reason.py index 3b9d15401..5abfe177e 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_criterion_primary_status_reason.py +++ b/google/ads/googleads/v23/enums/types/ad_group_criterion_primary_status_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCriterionPrimaryStatusReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_group_criterion_status.py b/google/ads/googleads/v23/enums/types/ad_group_criterion_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/ad_group_criterion_status.py rename to google/ads/googleads/v23/enums/types/ad_group_criterion_status.py index 9a9a1a14c..77acc6280 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_criterion_status.py +++ b/google/ads/googleads/v23/enums/types/ad_group_criterion_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCriterionStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_group_primary_status.py b/google/ads/googleads/v23/enums/types/ad_group_primary_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/ad_group_primary_status.py rename to google/ads/googleads/v23/enums/types/ad_group_primary_status.py index 17fadc33e..b091133d3 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_primary_status.py +++ b/google/ads/googleads/v23/enums/types/ad_group_primary_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupPrimaryStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_group_primary_status_reason.py b/google/ads/googleads/v23/enums/types/ad_group_primary_status_reason.py similarity index 98% rename from google/ads/googleads/v19/enums/types/ad_group_primary_status_reason.py rename to google/ads/googleads/v23/enums/types/ad_group_primary_status_reason.py index 78dcb8d8d..0fe93cdc3 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_primary_status_reason.py +++ b/google/ads/googleads/v23/enums/types/ad_group_primary_status_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupPrimaryStatusReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_group_status.py b/google/ads/googleads/v23/enums/types/ad_group_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/ad_group_status.py rename to google/ads/googleads/v23/enums/types/ad_group_status.py index 8fd89e34a..7bcc93cd3 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_status.py +++ b/google/ads/googleads/v23/enums/types/ad_group_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_group_type.py b/google/ads/googleads/v23/enums/types/ad_group_type.py similarity index 97% rename from google/ads/googleads/v19/enums/types/ad_group_type.py rename to google/ads/googleads/v23/enums/types/ad_group_type.py index 9ad9bda59..3ca0367e9 100644 --- a/google/ads/googleads/v19/enums/types/ad_group_type.py +++ b/google/ads/googleads/v23/enums/types/ad_group_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdGroupTypeEnum", }, diff --git a/google/ads/googleads/v23/enums/types/ad_network_type.py b/google/ads/googleads/v23/enums/types/ad_network_type.py new file mode 100644 index 000000000..713f1df6b --- /dev/null +++ b/google/ads/googleads/v23/enums/types/ad_network_type.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "AdNetworkTypeEnum", + }, +) + + +class AdNetworkTypeEnum(proto.Message): + r"""Container for enumeration of Google Ads network types.""" + + class AdNetworkType(proto.Enum): + r"""Enumerates Google Ads network types. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + The value is unknown in this version. + SEARCH (2): + Google search. + SEARCH_PARTNERS (3): + Search partners. + CONTENT (4): + Display Network. + MIXED (7): + Cross-network. + YOUTUBE (8): + YouTube + GOOGLE_TV (9): + Google TV + GOOGLE_OWNED_CHANNELS (10): + This network is used for Google Owned + channels such as Discover feed, Gmail, YouTube. + Starting with V20, Demand Gen Stats will be + attributed to more granular network types such + as GMAIL, DISCOVER, MAPS, YOUTUBE; this value + will only be used for historical data. + GMAIL (11): + Gmail + DISCOVER (12): + Discover Feed + MAPS (13): + Maps + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + SEARCH = 2 + SEARCH_PARTNERS = 3 + CONTENT = 4 + MIXED = 7 + YOUTUBE = 8 + GOOGLE_TV = 9 + GOOGLE_OWNED_CHANNELS = 10 + GMAIL = 11 + DISCOVER = 12 + MAPS = 13 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/ad_serving_optimization_status.py b/google/ads/googleads/v23/enums/types/ad_serving_optimization_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/ad_serving_optimization_status.py rename to google/ads/googleads/v23/enums/types/ad_serving_optimization_status.py index db1a997e2..e3cbae680 100644 --- a/google/ads/googleads/v19/enums/types/ad_serving_optimization_status.py +++ b/google/ads/googleads/v23/enums/types/ad_serving_optimization_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdServingOptimizationStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_strength.py b/google/ads/googleads/v23/enums/types/ad_strength.py similarity index 95% rename from google/ads/googleads/v19/enums/types/ad_strength.py rename to google/ads/googleads/v23/enums/types/ad_strength.py index 982ad55c2..bc0b4d962 100644 --- a/google/ads/googleads/v19/enums/types/ad_strength.py +++ b/google/ads/googleads/v23/enums/types/ad_strength.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdStrengthEnum", }, diff --git a/google/ads/googleads/v19/enums/types/ad_strength_action_item_type.py b/google/ads/googleads/v23/enums/types/ad_strength_action_item_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/ad_strength_action_item_type.py rename to google/ads/googleads/v23/enums/types/ad_strength_action_item_type.py index 45bb3e7e4..22a59d3c1 100644 --- a/google/ads/googleads/v19/enums/types/ad_strength_action_item_type.py +++ b/google/ads/googleads/v23/enums/types/ad_strength_action_item_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdStrengthActionItemTypeEnum", }, diff --git a/google/ads/googleads/v23/enums/types/ad_sub_network_type.py b/google/ads/googleads/v23/enums/types/ad_sub_network_type.py new file mode 100644 index 000000000..de2a8f3bd --- /dev/null +++ b/google/ads/googleads/v23/enums/types/ad_sub_network_type.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "AdSubNetworkTypeEnum", + }, +) + + +class AdSubNetworkTypeEnum(proto.Message): + r"""Container for enumeration of Google Ads sub network types.""" + + class AdSubNetworkType(proto.Enum): + r"""Enumerates Google Ads sub network types. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Unknown. + UNSEGMENTED (2): + The whole network without any sub network + type segmentation. + YOUTUBE_INSTREAM (3): + Ads served in-stream of YouTube organic + videos. + YOUTUBE_INFEED (4): + Ads served on YouTube feed surfaces, such as + YouTube Home or Watch Next. + YOUTUBE_SHORTS (5): + Ads served on the YouTube Shorts feed. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + UNSEGMENTED = 2 + YOUTUBE_INSTREAM = 3 + YOUTUBE_INFEED = 4 + YOUTUBE_SHORTS = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/ad_type.py b/google/ads/googleads/v23/enums/types/ad_type.py similarity index 97% rename from google/ads/googleads/v19/enums/types/ad_type.py rename to google/ads/googleads/v23/enums/types/ad_type.py index 18a0cf21d..9e89778e5 100644 --- a/google/ads/googleads/v19/enums/types/ad_type.py +++ b/google/ads/googleads/v23/enums/types/ad_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdTypeEnum", }, @@ -74,7 +74,7 @@ class AdType(proto.Enum): product type. DYNAMIC_HTML5_AD (22): The ad is a display upload ad with one of the - DYNAMIC_HTML5_\* product types. + DYNAMIC_HTML5\_\* product types. APP_ENGAGEMENT_AD (23): The ad is an app engagement ad. SHOPPING_COMPARISON_LISTING_AD (24): diff --git a/google/ads/googleads/v19/enums/types/advertising_channel_sub_type.py b/google/ads/googleads/v23/enums/types/advertising_channel_sub_type.py similarity index 98% rename from google/ads/googleads/v19/enums/types/advertising_channel_sub_type.py rename to google/ads/googleads/v23/enums/types/advertising_channel_sub_type.py index 403d59698..71267661a 100644 --- a/google/ads/googleads/v19/enums/types/advertising_channel_sub_type.py +++ b/google/ads/googleads/v23/enums/types/advertising_channel_sub_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdvertisingChannelSubTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/advertising_channel_type.py b/google/ads/googleads/v23/enums/types/advertising_channel_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/advertising_channel_type.py rename to google/ads/googleads/v23/enums/types/advertising_channel_type.py index 672de97fe..c26aa523c 100644 --- a/google/ads/googleads/v19/enums/types/advertising_channel_type.py +++ b/google/ads/googleads/v23/enums/types/advertising_channel_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AdvertisingChannelTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/age_range_type.py b/google/ads/googleads/v23/enums/types/age_range_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/age_range_type.py rename to google/ads/googleads/v23/enums/types/age_range_type.py index 5bdb227e5..5bb764068 100644 --- a/google/ads/googleads/v19/enums/types/age_range_type.py +++ b/google/ads/googleads/v23/enums/types/age_range_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AgeRangeTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/android_privacy_interaction_type.py b/google/ads/googleads/v23/enums/types/android_privacy_interaction_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/android_privacy_interaction_type.py rename to google/ads/googleads/v23/enums/types/android_privacy_interaction_type.py index b1e8a7632..75537d55b 100644 --- a/google/ads/googleads/v19/enums/types/android_privacy_interaction_type.py +++ b/google/ads/googleads/v23/enums/types/android_privacy_interaction_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AndroidPrivacyInteractionTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/android_privacy_network_type.py b/google/ads/googleads/v23/enums/types/android_privacy_network_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/android_privacy_network_type.py rename to google/ads/googleads/v23/enums/types/android_privacy_network_type.py index f0d15f4ba..4585acbde 100644 --- a/google/ads/googleads/v19/enums/types/android_privacy_network_type.py +++ b/google/ads/googleads/v23/enums/types/android_privacy_network_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AndroidPrivacyNetworkTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/app_bidding_goal.py b/google/ads/googleads/v23/enums/types/app_bidding_goal.py similarity index 97% rename from google/ads/googleads/v19/enums/types/app_bidding_goal.py rename to google/ads/googleads/v23/enums/types/app_bidding_goal.py index 7fe9bd8bd..da8cfd700 100644 --- a/google/ads/googleads/v19/enums/types/app_bidding_goal.py +++ b/google/ads/googleads/v23/enums/types/app_bidding_goal.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AppBiddingGoalEnum", }, diff --git a/google/ads/googleads/v19/enums/types/app_campaign_app_store.py b/google/ads/googleads/v23/enums/types/app_campaign_app_store.py similarity index 94% rename from google/ads/googleads/v19/enums/types/app_campaign_app_store.py rename to google/ads/googleads/v23/enums/types/app_campaign_app_store.py index 96340cd38..4d0b0aa45 100644 --- a/google/ads/googleads/v19/enums/types/app_campaign_app_store.py +++ b/google/ads/googleads/v23/enums/types/app_campaign_app_store.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AppCampaignAppStoreEnum", }, diff --git a/google/ads/googleads/v19/enums/types/app_campaign_bidding_strategy_goal_type.py b/google/ads/googleads/v23/enums/types/app_campaign_bidding_strategy_goal_type.py similarity index 81% rename from google/ads/googleads/v19/enums/types/app_campaign_bidding_strategy_goal_type.py rename to google/ads/googleads/v23/enums/types/app_campaign_bidding_strategy_goal_type.py index cb1178d88..08e4f7302 100644 --- a/google/ads/googleads/v19/enums/types/app_campaign_bidding_strategy_goal_type.py +++ b/google/ads/googleads/v23/enums/types/app_campaign_bidding_strategy_goal_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AppCampaignBiddingStrategyGoalTypeEnum", }, @@ -68,6 +68,15 @@ class AppCampaignBiddingStrategyGoalType(proto.Enum): OPTIMIZE_INSTALLS_WITHOUT_TARGET_INSTALL_COST (7): Aim to maximize installation of the app without target cost-per-install. + OPTIMIZE_IN_APP_CONVERSIONS_WITHOUT_TARGET_CPA (8): + Aim to maximize the selected in-app + conversion's volume while spending the full + budget. No advertiser-specific target CPA. + OPTIMIZE_TOTAL_VALUE_WITHOUT_TARGET_ROAS (9): + Aim to maximize total conversion value, such + as install and selected in-app conversions, + while spending the full budget. No + advertiser-specified target ROAS. """ UNSPECIFIED = 0 @@ -78,6 +87,8 @@ class AppCampaignBiddingStrategyGoalType(proto.Enum): OPTIMIZE_RETURN_ON_ADVERTISING_SPEND = 5 OPTIMIZE_PRE_REGISTRATION_CONVERSION_VOLUME = 6 OPTIMIZE_INSTALLS_WITHOUT_TARGET_INSTALL_COST = 7 + OPTIMIZE_IN_APP_CONVERSIONS_WITHOUT_TARGET_CPA = 8 + OPTIMIZE_TOTAL_VALUE_WITHOUT_TARGET_ROAS = 9 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/app_payment_model_type.py b/google/ads/googleads/v23/enums/types/app_payment_model_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/app_payment_model_type.py rename to google/ads/googleads/v23/enums/types/app_payment_model_type.py index 0f8a4ad56..8316165f2 100644 --- a/google/ads/googleads/v19/enums/types/app_payment_model_type.py +++ b/google/ads/googleads/v23/enums/types/app_payment_model_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AppPaymentModelTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/app_url_operating_system_type.py b/google/ads/googleads/v23/enums/types/app_url_operating_system_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/app_url_operating_system_type.py rename to google/ads/googleads/v23/enums/types/app_url_operating_system_type.py index 2f944e651..333bbce73 100644 --- a/google/ads/googleads/v19/enums/types/app_url_operating_system_type.py +++ b/google/ads/googleads/v23/enums/types/app_url_operating_system_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AppUrlOperatingSystemTypeEnum", }, diff --git a/google/ads/googleads/v23/enums/types/application_instance.py b/google/ads/googleads/v23/enums/types/application_instance.py new file mode 100644 index 000000000..edacdd020 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/application_instance.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "ApplicationInstanceEnum", + }, +) + + +class ApplicationInstanceEnum(proto.Message): + r"""Container for enum describing application instance types.""" + + class ApplicationInstance(proto.Enum): + r"""Possible application instances sending the request. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + The value is unknown in this version. + DEVELOPMENT_AND_TESTING (2): + The instance is for development and testing + purposes. + PRODUCTION (3): + The instance is for production purposes. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + DEVELOPMENT_AND_TESTING = 2 + PRODUCTION = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/asset_automation_status.py b/google/ads/googleads/v23/enums/types/asset_automation_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/asset_automation_status.py rename to google/ads/googleads/v23/enums/types/asset_automation_status.py index 7b49958de..c95b95798 100644 --- a/google/ads/googleads/v19/enums/types/asset_automation_status.py +++ b/google/ads/googleads/v23/enums/types/asset_automation_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetAutomationStatusEnum", }, diff --git a/google/ads/googleads/v23/enums/types/asset_automation_type.py b/google/ads/googleads/v23/enums/types/asset_automation_type.py new file mode 100644 index 000000000..952fa66e4 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/asset_automation_type.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "AssetAutomationTypeEnum", + }, +) + + +class AssetAutomationTypeEnum(proto.Message): + r"""Container for enum describing the type of asset automation.""" + + class AssetAutomationType(proto.Enum): + r"""The type of asset automation. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used as a return value only. Represents value + unknown in this version. + TEXT_ASSET_AUTOMATION (2): + Text asset automation includes headlines and + descriptions. By default, advertisers are + opted-in for Performance Max and opted-out for + Search. + GENERATE_VERTICAL_YOUTUBE_VIDEOS (3): + Converts horizontal video assets to vertical + orientation using content-aware technology. By + default, advertisers are opted in for + DemandGenVideoResponsiveAd. + GENERATE_SHORTER_YOUTUBE_VIDEOS (4): + Shortens video assets to better capture user + attention using content-aware technology. By + default, advertisers are opted in for + DemandGenVideoResponsiveAd. + GENERATE_LANDING_PAGE_PREVIEW (5): + Generates a preview of the landing page shown + in the engagement panel. + By using this feature, you confirm that you own + all legal rights to the images on the landing + page used by this account (or you have + permission to share the images with Google). You + hereby instruct Google to publish these images + on your behalf for advertising or other + commercial purposes. + GENERATE_ENHANCED_YOUTUBE_VIDEOS (6): + Generates video enhancements (vertical and + shorter videos) for PMax campaigns. Opted in by + default. + GENERATE_IMAGE_ENHANCEMENT (7): + Generates image enhancements (AutoCrop and + AutoEnhance). Opted in by default for pmax. + GENERATE_IMAGE_EXTRACTION (9): + Generates image extraction. It defaults to + account level Dynamic Image Extension control + value. + GENERATE_DESIGN_VERSIONS_FOR_IMAGES (10): + Adds design elements and embeds text assets + into image assets to create images with + different aspect ratios. By default, advertisers + are opted in for DemandGenMultiAssetAd. + FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION (11): + Controls automation for text assets related + to Final URL expansion. This includes + automatically creating dynamic landing pages + from the final URL and generating text assets + from the content of those landing pages. This + setting is turned OFF by default for Search + campaigns, but it is turned ON by default for + Performance Max campaigns. + GENERATE_VIDEOS_FROM_OTHER_ASSETS (12): + Generates videos using other Assets as input, + such as images and text. By default, advertisers + are opted in for DemandGenMultiAssetAd. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + TEXT_ASSET_AUTOMATION = 2 + GENERATE_VERTICAL_YOUTUBE_VIDEOS = 3 + GENERATE_SHORTER_YOUTUBE_VIDEOS = 4 + GENERATE_LANDING_PAGE_PREVIEW = 5 + GENERATE_ENHANCED_YOUTUBE_VIDEOS = 6 + GENERATE_IMAGE_ENHANCEMENT = 7 + GENERATE_IMAGE_EXTRACTION = 9 + GENERATE_DESIGN_VERSIONS_FOR_IMAGES = 10 + FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION = 11 + GENERATE_VIDEOS_FROM_OTHER_ASSETS = 12 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/asset_coverage_video_aspect_ratio_requirement.py b/google/ads/googleads/v23/enums/types/asset_coverage_video_aspect_ratio_requirement.py similarity index 95% rename from google/ads/googleads/v19/enums/types/asset_coverage_video_aspect_ratio_requirement.py rename to google/ads/googleads/v23/enums/types/asset_coverage_video_aspect_ratio_requirement.py index 7257ad37e..29b47d593 100644 --- a/google/ads/googleads/v19/enums/types/asset_coverage_video_aspect_ratio_requirement.py +++ b/google/ads/googleads/v23/enums/types/asset_coverage_video_aspect_ratio_requirement.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetCoverageVideoAspectRatioRequirementEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_field_type.py b/google/ads/googleads/v23/enums/types/asset_field_type.py similarity index 88% rename from google/ads/googleads/v19/enums/types/asset_field_type.py rename to google/ads/googleads/v23/enums/types/asset_field_type.py index 19e1d19f5..06a68fbbc 100644 --- a/google/ads/googleads/v19/enums/types/asset_field_type.py +++ b/google/ads/googleads/v23/enums/types/asset_field_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetFieldTypeEnum", }, @@ -130,6 +130,18 @@ class AssetFieldType(proto.Enum): TALL_PORTRAIT_MARKETING_IMAGE (32): The asset is linked for use as a tall portrait marketing image. + RELATED_YOUTUBE_VIDEOS (33): + The asset is linked for use as related + YouTube videos. + LANDING_PAGE_PREVIEW (38): + The asset is linked for use as a landing page + preview image. + LONG_DESCRIPTION (39): + The asset is linked for use as a long + description. + CALL_TO_ACTION (40): + The asset is linked for use as a + call-to-action. """ UNSPECIFIED = 0 @@ -164,6 +176,10 @@ class AssetFieldType(proto.Enum): DEMAND_GEN_CAROUSEL_CARD = 30 BUSINESS_MESSAGE = 31 TALL_PORTRAIT_MARKETING_IMAGE = 32 + RELATED_YOUTUBE_VIDEOS = 33 + LANDING_PAGE_PREVIEW = 38 + LONG_DESCRIPTION = 39 + CALL_TO_ACTION = 40 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/asset_group_primary_status.py b/google/ads/googleads/v23/enums/types/asset_group_primary_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/asset_group_primary_status.py rename to google/ads/googleads/v23/enums/types/asset_group_primary_status.py index d3aa9d28f..e4b880a43 100644 --- a/google/ads/googleads/v19/enums/types/asset_group_primary_status.py +++ b/google/ads/googleads/v23/enums/types/asset_group_primary_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupPrimaryStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_group_primary_status_reason.py b/google/ads/googleads/v23/enums/types/asset_group_primary_status_reason.py similarity index 97% rename from google/ads/googleads/v19/enums/types/asset_group_primary_status_reason.py rename to google/ads/googleads/v23/enums/types/asset_group_primary_status_reason.py index eed575efe..fe472e297 100644 --- a/google/ads/googleads/v19/enums/types/asset_group_primary_status_reason.py +++ b/google/ads/googleads/v23/enums/types/asset_group_primary_status_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupPrimaryStatusReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_group_signal_approval_status.py b/google/ads/googleads/v23/enums/types/asset_group_signal_approval_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/asset_group_signal_approval_status.py rename to google/ads/googleads/v23/enums/types/asset_group_signal_approval_status.py index 2e43d02c3..23ce7e759 100644 --- a/google/ads/googleads/v19/enums/types/asset_group_signal_approval_status.py +++ b/google/ads/googleads/v23/enums/types/asset_group_signal_approval_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupSignalApprovalStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_group_status.py b/google/ads/googleads/v23/enums/types/asset_group_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/asset_group_status.py rename to google/ads/googleads/v23/enums/types/asset_group_status.py index a287dfbe9..3720c32b8 100644 --- a/google/ads/googleads/v19/enums/types/asset_group_status.py +++ b/google/ads/googleads/v23/enums/types/asset_group_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_link_primary_status.py b/google/ads/googleads/v23/enums/types/asset_link_primary_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/asset_link_primary_status.py rename to google/ads/googleads/v23/enums/types/asset_link_primary_status.py index fbf4d8949..bbd308d37 100644 --- a/google/ads/googleads/v19/enums/types/asset_link_primary_status.py +++ b/google/ads/googleads/v23/enums/types/asset_link_primary_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetLinkPrimaryStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_link_primary_status_reason.py b/google/ads/googleads/v23/enums/types/asset_link_primary_status_reason.py similarity index 96% rename from google/ads/googleads/v19/enums/types/asset_link_primary_status_reason.py rename to google/ads/googleads/v23/enums/types/asset_link_primary_status_reason.py index fabcd23d6..b318184bc 100644 --- a/google/ads/googleads/v19/enums/types/asset_link_primary_status_reason.py +++ b/google/ads/googleads/v23/enums/types/asset_link_primary_status_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetLinkPrimaryStatusReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_link_status.py b/google/ads/googleads/v23/enums/types/asset_link_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/asset_link_status.py rename to google/ads/googleads/v23/enums/types/asset_link_status.py index 3cf8bca02..af4d7bc17 100644 --- a/google/ads/googleads/v19/enums/types/asset_link_status.py +++ b/google/ads/googleads/v23/enums/types/asset_link_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetLinkStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_offline_evaluation_error_reasons.py b/google/ads/googleads/v23/enums/types/asset_offline_evaluation_error_reasons.py similarity index 97% rename from google/ads/googleads/v19/enums/types/asset_offline_evaluation_error_reasons.py rename to google/ads/googleads/v23/enums/types/asset_offline_evaluation_error_reasons.py index d5e16d463..3364d1151 100644 --- a/google/ads/googleads/v19/enums/types/asset_offline_evaluation_error_reasons.py +++ b/google/ads/googleads/v23/enums/types/asset_offline_evaluation_error_reasons.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetOfflineEvaluationErrorReasonsEnum", }, diff --git a/google/ads/googleads/v23/enums/types/asset_orientation.py b/google/ads/googleads/v23/enums/types/asset_orientation.py new file mode 100644 index 000000000..914543634 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/asset_orientation.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "AssetOrientationEnum", + }, +) + + +class AssetOrientationEnum(proto.Message): + r"""Container for enum describing the orientation of an image or + video asset. + + """ + + class AssetOrientation(proto.Enum): + r"""The orientation of an image or video asset. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + The value is unknown in this version. + LANDSCAPE (2): + Landscape orientation. + PORTRAIT (3): + Portrait orientation. + SQUARE (4): + Square orientation. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + LANDSCAPE = 2 + PORTRAIT = 3 + SQUARE = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/asset_performance_label.py b/google/ads/googleads/v23/enums/types/asset_performance_label.py similarity index 86% rename from google/ads/googleads/v19/enums/types/asset_performance_label.py rename to google/ads/googleads/v23/enums/types/asset_performance_label.py index 7ef942cbf..36004b251 100644 --- a/google/ads/googleads/v19/enums/types/asset_performance_label.py +++ b/google/ads/googleads/v23/enums/types/asset_performance_label.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetPerformanceLabelEnum", }, @@ -58,6 +58,10 @@ class AssetPerformanceLabel(proto.Enum): Good performing assets. BEST (6): Best performing assets. + NOT_APPLICABLE (7): + Performance label cannot be assigned to this + asset. This may be because it's not used by + asset based creatives. """ UNSPECIFIED = 0 @@ -67,6 +71,7 @@ class AssetPerformanceLabel(proto.Enum): LOW = 4 GOOD = 5 BEST = 6 + NOT_APPLICABLE = 7 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/asset_set_asset_status.py b/google/ads/googleads/v23/enums/types/asset_set_asset_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/asset_set_asset_status.py rename to google/ads/googleads/v23/enums/types/asset_set_asset_status.py index a15127af8..24186f0ae 100644 --- a/google/ads/googleads/v19/enums/types/asset_set_asset_status.py +++ b/google/ads/googleads/v23/enums/types/asset_set_asset_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetSetAssetStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_set_link_status.py b/google/ads/googleads/v23/enums/types/asset_set_link_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/asset_set_link_status.py rename to google/ads/googleads/v23/enums/types/asset_set_link_status.py index 5c843a7f7..4961529c6 100644 --- a/google/ads/googleads/v19/enums/types/asset_set_link_status.py +++ b/google/ads/googleads/v23/enums/types/asset_set_link_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetSetLinkStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_set_status.py b/google/ads/googleads/v23/enums/types/asset_set_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/asset_set_status.py rename to google/ads/googleads/v23/enums/types/asset_set_status.py index 7b5f4e03e..a4ecc8747 100644 --- a/google/ads/googleads/v19/enums/types/asset_set_status.py +++ b/google/ads/googleads/v23/enums/types/asset_set_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetSetStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_set_type.py b/google/ads/googleads/v23/enums/types/asset_set_type.py similarity index 97% rename from google/ads/googleads/v19/enums/types/asset_set_type.py rename to google/ads/googleads/v23/enums/types/asset_set_type.py index b865d5291..d2e682e69 100644 --- a/google/ads/googleads/v19/enums/types/asset_set_type.py +++ b/google/ads/googleads/v23/enums/types/asset_set_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetSetTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_source.py b/google/ads/googleads/v23/enums/types/asset_source.py similarity index 94% rename from google/ads/googleads/v19/enums/types/asset_source.py rename to google/ads/googleads/v23/enums/types/asset_source.py index 0eccd37f2..f1d363ca9 100644 --- a/google/ads/googleads/v19/enums/types/asset_source.py +++ b/google/ads/googleads/v23/enums/types/asset_source.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetSourceEnum", }, diff --git a/google/ads/googleads/v19/enums/types/asset_type.py b/google/ads/googleads/v23/enums/types/asset_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/asset_type.py rename to google/ads/googleads/v23/enums/types/asset_type.py index 5183c4bdf..880a7b520 100644 --- a/google/ads/googleads/v19/enums/types/asset_type.py +++ b/google/ads/googleads/v23/enums/types/asset_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AssetTypeEnum", }, @@ -98,6 +98,8 @@ class AssetType(proto.Enum): Business message asset. APP_DEEP_LINK (31): App deep link asset. + YOUTUBE_VIDEO_LIST (32): + YouTube video list asset. """ UNSPECIFIED = 0 @@ -131,6 +133,7 @@ class AssetType(proto.Enum): DEMAND_GEN_CAROUSEL_CARD = 29 BUSINESS_MESSAGE = 30 APP_DEEP_LINK = 31 + YOUTUBE_VIDEO_LIST = 32 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/async_action_status.py b/google/ads/googleads/v23/enums/types/async_action_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/async_action_status.py rename to google/ads/googleads/v23/enums/types/async_action_status.py index 62161fde4..8c338ca85 100644 --- a/google/ads/googleads/v19/enums/types/async_action_status.py +++ b/google/ads/googleads/v23/enums/types/async_action_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AsyncActionStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/attribution_model.py b/google/ads/googleads/v23/enums/types/attribution_model.py similarity index 97% rename from google/ads/googleads/v19/enums/types/attribution_model.py rename to google/ads/googleads/v23/enums/types/attribution_model.py index 79a850a3d..d838ebb52 100644 --- a/google/ads/googleads/v19/enums/types/attribution_model.py +++ b/google/ads/googleads/v23/enums/types/attribution_model.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AttributionModelEnum", }, diff --git a/google/ads/googleads/v19/enums/types/audience_insights_dimension.py b/google/ads/googleads/v23/enums/types/audience_insights_dimension.py similarity index 82% rename from google/ads/googleads/v19/enums/types/audience_insights_dimension.py rename to google/ads/googleads/v23/enums/types/audience_insights_dimension.py index 9163cafab..8e9b8a2df 100644 --- a/google/ads/googleads/v19/enums/types/audience_insights_dimension.py +++ b/google/ads/googleads/v23/enums/types/audience_insights_dimension.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AudienceInsightsDimensionEnum", }, @@ -49,8 +49,6 @@ class AudienceInsightsDimension(proto.Enum): A geographic location within a country. YOUTUBE_CHANNEL (6): A YouTube channel. - YOUTUBE_DYNAMIC_LINEUP (7): - A YouTube Dynamic Lineup. AFFINITY_USER_INTEREST (8): An Affinity UserInterest. IN_MARKET_USER_INTEREST (9): @@ -66,6 +64,15 @@ class AudienceInsightsDimension(proto.Enum): A gender. YOUTUBE_VIDEO (14): A YouTube video. + DEVICE (15): + A device type, such as Mobile, Desktop, + Tablet, and Connected TV. + YOUTUBE_LINEUP (16): + A YouTube Lineup. + USER_LIST (17): + A User List. + LIFE_EVENT_USER_INTEREST (18): + A Life Event UserInterest. """ UNSPECIFIED = 0 @@ -75,7 +82,6 @@ class AudienceInsightsDimension(proto.Enum): GEO_TARGET_COUNTRY = 4 SUB_COUNTRY_LOCATION = 5 YOUTUBE_CHANNEL = 6 - YOUTUBE_DYNAMIC_LINEUP = 7 AFFINITY_USER_INTEREST = 8 IN_MARKET_USER_INTEREST = 9 PARENTAL_STATUS = 10 @@ -83,6 +89,10 @@ class AudienceInsightsDimension(proto.Enum): AGE_RANGE = 12 GENDER = 13 YOUTUBE_VIDEO = 14 + DEVICE = 15 + YOUTUBE_LINEUP = 16 + USER_LIST = 17 + LIFE_EVENT_USER_INTEREST = 18 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/audience_insights_marketing_objective.py b/google/ads/googleads/v23/enums/types/audience_insights_marketing_objective.py similarity index 87% rename from google/ads/googleads/v19/enums/types/audience_insights_marketing_objective.py rename to google/ads/googleads/v23/enums/types/audience_insights_marketing_objective.py index 10cc7d1db..8d134a56b 100644 --- a/google/ads/googleads/v19/enums/types/audience_insights_marketing_objective.py +++ b/google/ads/googleads/v23/enums/types/audience_insights_marketing_objective.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AudienceInsightsMarketingObjectiveEnum", }, @@ -48,12 +48,16 @@ class AudienceInsightsMarketingObjective(proto.Enum): customers to consider your brand or products when they're researching or shopping for product. + RESEARCH (4): + The objective is for research, to gain + further insights into your audience. """ UNSPECIFIED = 0 UNKNOWN = 1 AWARENESS = 2 CONSIDERATION = 3 + RESEARCH = 4 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/audience_scope.py b/google/ads/googleads/v23/enums/types/audience_scope.py similarity index 94% rename from google/ads/googleads/v19/enums/types/audience_scope.py rename to google/ads/googleads/v23/enums/types/audience_scope.py index b61129a31..7ceb6101d 100644 --- a/google/ads/googleads/v19/enums/types/audience_scope.py +++ b/google/ads/googleads/v23/enums/types/audience_scope.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AudienceScopeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/audience_status.py b/google/ads/googleads/v23/enums/types/audience_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/audience_status.py rename to google/ads/googleads/v23/enums/types/audience_status.py index 3f8181547..8371a8a24 100644 --- a/google/ads/googleads/v19/enums/types/audience_status.py +++ b/google/ads/googleads/v23/enums/types/audience_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "AudienceStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/batch_job_status.py b/google/ads/googleads/v23/enums/types/batch_job_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/batch_job_status.py rename to google/ads/googleads/v23/enums/types/batch_job_status.py index 199cb4492..4c87384d4 100644 --- a/google/ads/googleads/v19/enums/types/batch_job_status.py +++ b/google/ads/googleads/v23/enums/types/batch_job_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BatchJobStatusEnum", }, diff --git a/google/ads/googleads/v23/enums/types/benchmarks_marketing_objective.py b/google/ads/googleads/v23/enums/types/benchmarks_marketing_objective.py new file mode 100644 index 000000000..82d971ddb --- /dev/null +++ b/google/ads/googleads/v23/enums/types/benchmarks_marketing_objective.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "BenchmarksMarketingObjectiveEnum", + }, +) + + +class BenchmarksMarketingObjectiveEnum(proto.Message): + r"""Container for enum describing YouTube ad benchmarks marketing + objectives. + + """ + + class BenchmarksMarketingObjective(proto.Enum): + r"""The YouTube ad benchmarks marketing objective. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + The value is unknown in this version. + AWARENESS (2): + The objective is to increase awareness. + CONSIDERATION (3): + The objective is to encourage potential + customers to consider the brand or products. + ACTION (4): + The objective is to drive a specific + conversion, such as a purchase. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + AWARENESS = 2 + CONSIDERATION = 3 + ACTION = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/enums/types/benchmarks_source_type.py b/google/ads/googleads/v23/enums/types/benchmarks_source_type.py new file mode 100644 index 000000000..477f3435c --- /dev/null +++ b/google/ads/googleads/v23/enums/types/benchmarks_source_type.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "BenchmarksSourceTypeEnum", + }, +) + + +class BenchmarksSourceTypeEnum(proto.Message): + r"""Container for enum describing YouTube ad benchmarks sources.""" + + class BenchmarksSourceType(proto.Enum): + r"""Possible YouTube ad benchmarks sources. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + The value is unknown in this version. + INDUSTRY_VERTICAL (2): + The classification of ad categories for + benchmarking. (for example, "Technology" or + "Finance"). + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + INDUSTRY_VERTICAL = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/bid_modifier_source.py b/google/ads/googleads/v23/enums/types/bid_modifier_source.py similarity index 94% rename from google/ads/googleads/v19/enums/types/bid_modifier_source.py rename to google/ads/googleads/v23/enums/types/bid_modifier_source.py index 8295bc673..4c6ec2155 100644 --- a/google/ads/googleads/v19/enums/types/bid_modifier_source.py +++ b/google/ads/googleads/v23/enums/types/bid_modifier_source.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BidModifierSourceEnum", }, diff --git a/google/ads/googleads/v19/enums/types/bidding_source.py b/google/ads/googleads/v23/enums/types/bidding_source.py similarity index 95% rename from google/ads/googleads/v19/enums/types/bidding_source.py rename to google/ads/googleads/v23/enums/types/bidding_source.py index eba08045f..9a30cbf29 100644 --- a/google/ads/googleads/v19/enums/types/bidding_source.py +++ b/google/ads/googleads/v23/enums/types/bidding_source.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BiddingSourceEnum", }, diff --git a/google/ads/googleads/v19/enums/types/bidding_strategy_status.py b/google/ads/googleads/v23/enums/types/bidding_strategy_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/bidding_strategy_status.py rename to google/ads/googleads/v23/enums/types/bidding_strategy_status.py index 026d696c0..9b699c04b 100644 --- a/google/ads/googleads/v19/enums/types/bidding_strategy_status.py +++ b/google/ads/googleads/v23/enums/types/bidding_strategy_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BiddingStrategyStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/bidding_strategy_system_status.py b/google/ads/googleads/v23/enums/types/bidding_strategy_system_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/bidding_strategy_system_status.py rename to google/ads/googleads/v23/enums/types/bidding_strategy_system_status.py index 6ad224ab8..3f4fe315b 100644 --- a/google/ads/googleads/v19/enums/types/bidding_strategy_system_status.py +++ b/google/ads/googleads/v23/enums/types/bidding_strategy_system_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BiddingStrategySystemStatusEnum", }, @@ -117,13 +117,13 @@ class BiddingStrategySystemStatus(proto.Enum): This bid strategy currently does not support status reporting. MULTIPLE_LEARNING (23): - There were multiple LEARNING_\* system statuses for this bid - strategy during the time in question. + There were multiple LEARNING\_\* system statuses for this + bid strategy during the time in question. MULTIPLE_LIMITED (24): - There were multiple LIMITED_\* system statuses for this bid + There were multiple LIMITED\_\* system statuses for this bid strategy during the time in question. MULTIPLE_MISCONFIGURED (25): - There were multiple MISCONFIGURED_\* system statuses for + There were multiple MISCONFIGURED\_\* system statuses for this bid strategy during the time in question. MULTIPLE (26): There were multiple system statuses for this diff --git a/google/ads/googleads/v19/enums/types/bidding_strategy_type.py b/google/ads/googleads/v23/enums/types/bidding_strategy_type.py similarity index 91% rename from google/ads/googleads/v19/enums/types/bidding_strategy_type.py rename to google/ads/googleads/v23/enums/types/bidding_strategy_type.py index 541197a08..071240d2e 100644 --- a/google/ads/googleads/v19/enums/types/bidding_strategy_type.py +++ b/google/ads/googleads/v23/enums/types/bidding_strategy_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BiddingStrategyTypeEnum", }, @@ -55,6 +55,10 @@ class BiddingStrategyType(proto.Enum): FIXED_CPM (19): Fixed CPM is a manual bidding strategy with a fixed CPM. + FIXED_SHARE_OF_VOICE (22): + Fixed share of voice is a manual bidding + strategy for YouTube Sponsorships that bills + either on CPM or a fixed cost per day. INVALID (17): Used for return value only. Indicates that a campaign does not have a bidding strategy. This @@ -101,6 +105,10 @@ class BiddingStrategyType(proto.Enum): sets bids to help get as many conversions as possible at the target cost-per-acquisition (CPA) you set. + TARGET_CPC (21): + Target CPC is an automated bid strategy that + sets bids to help get as many clicks as possible + at the target cost-per-click (CPC) you set. TARGET_CPM (14): Target CPM is an automated bid strategy that sets bids to help get as many impressions as @@ -137,6 +145,7 @@ class BiddingStrategyType(proto.Enum): COMMISSION = 16 ENHANCED_CPC = 2 FIXED_CPM = 19 + FIXED_SHARE_OF_VOICE = 22 INVALID = 17 MANUAL_CPA = 18 MANUAL_CPC = 3 @@ -147,6 +156,7 @@ class BiddingStrategyType(proto.Enum): PAGE_ONE_PROMOTED = 5 PERCENT_CPC = 12 TARGET_CPA = 6 + TARGET_CPC = 21 TARGET_CPM = 14 TARGET_CPV = 20 TARGET_IMPRESSION_SHARE = 15 diff --git a/google/ads/googleads/v19/enums/types/billing_setup_status.py b/google/ads/googleads/v23/enums/types/billing_setup_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/billing_setup_status.py rename to google/ads/googleads/v23/enums/types/billing_setup_status.py index 6a293c9ae..ead2bd55c 100644 --- a/google/ads/googleads/v19/enums/types/billing_setup_status.py +++ b/google/ads/googleads/v23/enums/types/billing_setup_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BillingSetupStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/brand_request_rejection_reason.py b/google/ads/googleads/v23/enums/types/brand_request_rejection_reason.py similarity index 95% rename from google/ads/googleads/v19/enums/types/brand_request_rejection_reason.py rename to google/ads/googleads/v23/enums/types/brand_request_rejection_reason.py index 612ab9512..034c476b7 100644 --- a/google/ads/googleads/v19/enums/types/brand_request_rejection_reason.py +++ b/google/ads/googleads/v23/enums/types/brand_request_rejection_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BrandRequestRejectionReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/brand_safety_suitability.py b/google/ads/googleads/v23/enums/types/brand_safety_suitability.py similarity index 97% rename from google/ads/googleads/v19/enums/types/brand_safety_suitability.py rename to google/ads/googleads/v23/enums/types/brand_safety_suitability.py index b8a1b048d..ef98821d3 100644 --- a/google/ads/googleads/v19/enums/types/brand_safety_suitability.py +++ b/google/ads/googleads/v23/enums/types/brand_safety_suitability.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BrandSafetySuitabilityEnum", }, diff --git a/google/ads/googleads/v19/enums/types/brand_state.py b/google/ads/googleads/v23/enums/types/brand_state.py similarity index 96% rename from google/ads/googleads/v19/enums/types/brand_state.py rename to google/ads/googleads/v23/enums/types/brand_state.py index a2750e908..51261d0f5 100644 --- a/google/ads/googleads/v19/enums/types/brand_state.py +++ b/google/ads/googleads/v23/enums/types/brand_state.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BrandStateEnum", }, diff --git a/google/ads/googleads/v19/enums/types/budget_campaign_association_status.py b/google/ads/googleads/v23/enums/types/budget_campaign_association_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/budget_campaign_association_status.py rename to google/ads/googleads/v23/enums/types/budget_campaign_association_status.py index a791a1645..9b23721c9 100644 --- a/google/ads/googleads/v19/enums/types/budget_campaign_association_status.py +++ b/google/ads/googleads/v23/enums/types/budget_campaign_association_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BudgetCampaignAssociationStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/budget_delivery_method.py b/google/ads/googleads/v23/enums/types/budget_delivery_method.py similarity index 95% rename from google/ads/googleads/v19/enums/types/budget_delivery_method.py rename to google/ads/googleads/v23/enums/types/budget_delivery_method.py index 6ebecb239..e8ef3a9f1 100644 --- a/google/ads/googleads/v19/enums/types/budget_delivery_method.py +++ b/google/ads/googleads/v23/enums/types/budget_delivery_method.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BudgetDeliveryMethodEnum", }, diff --git a/google/ads/googleads/v19/enums/types/budget_period.py b/google/ads/googleads/v23/enums/types/budget_period.py similarity index 94% rename from google/ads/googleads/v19/enums/types/budget_period.py rename to google/ads/googleads/v23/enums/types/budget_period.py index 128a084f2..7b922d5eb 100644 --- a/google/ads/googleads/v19/enums/types/budget_period.py +++ b/google/ads/googleads/v23/enums/types/budget_period.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BudgetPeriodEnum", }, diff --git a/google/ads/googleads/v19/enums/types/budget_status.py b/google/ads/googleads/v23/enums/types/budget_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/budget_status.py rename to google/ads/googleads/v23/enums/types/budget_status.py index b1e85c5f4..750f85fe8 100644 --- a/google/ads/googleads/v19/enums/types/budget_status.py +++ b/google/ads/googleads/v23/enums/types/budget_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BudgetStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/budget_type.py b/google/ads/googleads/v23/enums/types/budget_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/budget_type.py rename to google/ads/googleads/v23/enums/types/budget_type.py index 30746fd97..80fdc4610 100644 --- a/google/ads/googleads/v19/enums/types/budget_type.py +++ b/google/ads/googleads/v23/enums/types/budget_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BudgetTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/business_message_call_to_action_type.py b/google/ads/googleads/v23/enums/types/business_message_call_to_action_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/business_message_call_to_action_type.py rename to google/ads/googleads/v23/enums/types/business_message_call_to_action_type.py index 21760738c..b10f62c9d 100644 --- a/google/ads/googleads/v19/enums/types/business_message_call_to_action_type.py +++ b/google/ads/googleads/v23/enums/types/business_message_call_to_action_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BusinessMessageCallToActionTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/business_message_provider.py b/google/ads/googleads/v23/enums/types/business_message_provider.py similarity index 83% rename from google/ads/googleads/v19/enums/types/business_message_provider.py rename to google/ads/googleads/v23/enums/types/business_message_provider.py index 2b90ac0a6..c28ec39f7 100644 --- a/google/ads/googleads/v19/enums/types/business_message_provider.py +++ b/google/ads/googleads/v23/enums/types/business_message_provider.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "BusinessMessageProviderEnum", }, @@ -42,11 +42,17 @@ class BusinessMessageProvider(proto.Enum): unknown in this version. WHATSAPP (2): WhatsApp message provider + FACEBOOK_MESSENGER (3): + Facebook Messenger message provider + ZALO (4): + Zalo message provider """ UNSPECIFIED = 0 UNKNOWN = 1 WHATSAPP = 2 + FACEBOOK_MESSENGER = 3 + ZALO = 4 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/call_conversion_reporting_state.py b/google/ads/googleads/v23/enums/types/call_conversion_reporting_state.py similarity index 95% rename from google/ads/googleads/v19/enums/types/call_conversion_reporting_state.py rename to google/ads/googleads/v23/enums/types/call_conversion_reporting_state.py index 368fe5ba2..a5592bb6d 100644 --- a/google/ads/googleads/v19/enums/types/call_conversion_reporting_state.py +++ b/google/ads/googleads/v23/enums/types/call_conversion_reporting_state.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CallConversionReportingStateEnum", }, diff --git a/google/ads/googleads/v19/enums/types/call_to_action_type.py b/google/ads/googleads/v23/enums/types/call_to_action_type.py similarity index 97% rename from google/ads/googleads/v19/enums/types/call_to_action_type.py rename to google/ads/googleads/v23/enums/types/call_to_action_type.py index 5c59edd2e..e770f990b 100644 --- a/google/ads/googleads/v19/enums/types/call_to_action_type.py +++ b/google/ads/googleads/v23/enums/types/call_to_action_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CallToActionTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/call_tracking_display_location.py b/google/ads/googleads/v23/enums/types/call_tracking_display_location.py similarity index 94% rename from google/ads/googleads/v19/enums/types/call_tracking_display_location.py rename to google/ads/googleads/v23/enums/types/call_tracking_display_location.py index 27ce69f00..bed79037d 100644 --- a/google/ads/googleads/v19/enums/types/call_tracking_display_location.py +++ b/google/ads/googleads/v23/enums/types/call_tracking_display_location.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CallTrackingDisplayLocationEnum", }, diff --git a/google/ads/googleads/v19/enums/types/call_type.py b/google/ads/googleads/v23/enums/types/call_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/call_type.py rename to google/ads/googleads/v23/enums/types/call_type.py index 8c58b6d41..9ee8e8392 100644 --- a/google/ads/googleads/v19/enums/types/call_type.py +++ b/google/ads/googleads/v23/enums/types/call_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CallTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/campaign_criterion_status.py b/google/ads/googleads/v23/enums/types/campaign_criterion_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/campaign_criterion_status.py rename to google/ads/googleads/v23/enums/types/campaign_criterion_status.py index ea5e911a0..484a1d4c5 100644 --- a/google/ads/googleads/v19/enums/types/campaign_criterion_status.py +++ b/google/ads/googleads/v23/enums/types/campaign_criterion_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CampaignCriterionStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/campaign_draft_status.py b/google/ads/googleads/v23/enums/types/campaign_draft_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/campaign_draft_status.py rename to google/ads/googleads/v23/enums/types/campaign_draft_status.py index 8d593d9ab..ca5b6febd 100644 --- a/google/ads/googleads/v19/enums/types/campaign_draft_status.py +++ b/google/ads/googleads/v23/enums/types/campaign_draft_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CampaignDraftStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/campaign_experiment_type.py b/google/ads/googleads/v23/enums/types/campaign_experiment_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/campaign_experiment_type.py rename to google/ads/googleads/v23/enums/types/campaign_experiment_type.py index b2c75533c..e95189613 100644 --- a/google/ads/googleads/v19/enums/types/campaign_experiment_type.py +++ b/google/ads/googleads/v23/enums/types/campaign_experiment_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CampaignExperimentTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/campaign_group_status.py b/google/ads/googleads/v23/enums/types/campaign_group_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/campaign_group_status.py rename to google/ads/googleads/v23/enums/types/campaign_group_status.py index e21baf986..298dc1c84 100644 --- a/google/ads/googleads/v19/enums/types/campaign_group_status.py +++ b/google/ads/googleads/v23/enums/types/campaign_group_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CampaignGroupStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/campaign_keyword_match_type.py b/google/ads/googleads/v23/enums/types/campaign_keyword_match_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/campaign_keyword_match_type.py rename to google/ads/googleads/v23/enums/types/campaign_keyword_match_type.py index 7c4773d55..61ced7eec 100644 --- a/google/ads/googleads/v19/enums/types/campaign_keyword_match_type.py +++ b/google/ads/googleads/v23/enums/types/campaign_keyword_match_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CampaignKeywordMatchTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/campaign_primary_status.py b/google/ads/googleads/v23/enums/types/campaign_primary_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/campaign_primary_status.py rename to google/ads/googleads/v23/enums/types/campaign_primary_status.py index 3b336ac08..d27f87004 100644 --- a/google/ads/googleads/v19/enums/types/campaign_primary_status.py +++ b/google/ads/googleads/v23/enums/types/campaign_primary_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CampaignPrimaryStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/campaign_primary_status_reason.py b/google/ads/googleads/v23/enums/types/campaign_primary_status_reason.py similarity index 96% rename from google/ads/googleads/v19/enums/types/campaign_primary_status_reason.py rename to google/ads/googleads/v23/enums/types/campaign_primary_status_reason.py index 808f40b22..db9e08c64 100644 --- a/google/ads/googleads/v19/enums/types/campaign_primary_status_reason.py +++ b/google/ads/googleads/v23/enums/types/campaign_primary_status_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CampaignPrimaryStatusReasonEnum", }, @@ -151,6 +151,9 @@ class CampaignPrimaryStatusReason(proto.Enum): campaign. ASSET_GROUPS_PAUSED (38): All asset groups in this campaign are paused. + MISSING_LOCATION_TARGETING (39): + The campaign has location restrictions but + does not specify location targeting. """ UNSPECIFIED = 0 @@ -192,6 +195,7 @@ class CampaignPrimaryStatusReason(proto.Enum): MOST_ASSET_GROUPS_UNDER_REVIEW = 36 NO_ASSET_GROUPS = 37 ASSET_GROUPS_PAUSED = 38 + MISSING_LOCATION_TARGETING = 39 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/campaign_serving_status.py b/google/ads/googleads/v23/enums/types/campaign_serving_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/campaign_serving_status.py rename to google/ads/googleads/v23/enums/types/campaign_serving_status.py index 5f4b8878c..283f168e5 100644 --- a/google/ads/googleads/v19/enums/types/campaign_serving_status.py +++ b/google/ads/googleads/v23/enums/types/campaign_serving_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CampaignServingStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/campaign_shared_set_status.py b/google/ads/googleads/v23/enums/types/campaign_shared_set_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/campaign_shared_set_status.py rename to google/ads/googleads/v23/enums/types/campaign_shared_set_status.py index 738c1bfdb..82e61196e 100644 --- a/google/ads/googleads/v19/enums/types/campaign_shared_set_status.py +++ b/google/ads/googleads/v23/enums/types/campaign_shared_set_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CampaignSharedSetStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/campaign_status.py b/google/ads/googleads/v23/enums/types/campaign_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/campaign_status.py rename to google/ads/googleads/v23/enums/types/campaign_status.py index 7c89b9351..d9dbae0d4 100644 --- a/google/ads/googleads/v19/enums/types/campaign_status.py +++ b/google/ads/googleads/v23/enums/types/campaign_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CampaignStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/chain_relationship_type.py b/google/ads/googleads/v23/enums/types/chain_relationship_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/chain_relationship_type.py rename to google/ads/googleads/v23/enums/types/chain_relationship_type.py index 5368d8d4e..523006fa1 100644 --- a/google/ads/googleads/v19/enums/types/chain_relationship_type.py +++ b/google/ads/googleads/v23/enums/types/chain_relationship_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ChainRelationshipTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/change_client_type.py b/google/ads/googleads/v23/enums/types/change_client_type.py similarity index 97% rename from google/ads/googleads/v19/enums/types/change_client_type.py rename to google/ads/googleads/v23/enums/types/change_client_type.py index 168a9ec23..cd3dba334 100644 --- a/google/ads/googleads/v19/enums/types/change_client_type.py +++ b/google/ads/googleads/v23/enums/types/change_client_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ChangeClientTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/change_event_resource_type.py b/google/ads/googleads/v23/enums/types/change_event_resource_type.py similarity index 97% rename from google/ads/googleads/v19/enums/types/change_event_resource_type.py rename to google/ads/googleads/v23/enums/types/change_event_resource_type.py index 61bcb0738..ba34792df 100644 --- a/google/ads/googleads/v19/enums/types/change_event_resource_type.py +++ b/google/ads/googleads/v23/enums/types/change_event_resource_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ChangeEventResourceTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/change_status_operation.py b/google/ads/googleads/v23/enums/types/change_status_operation.py similarity index 94% rename from google/ads/googleads/v19/enums/types/change_status_operation.py rename to google/ads/googleads/v23/enums/types/change_status_operation.py index feb1d5801..934152447 100644 --- a/google/ads/googleads/v19/enums/types/change_status_operation.py +++ b/google/ads/googleads/v23/enums/types/change_status_operation.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ChangeStatusOperationEnum", }, diff --git a/google/ads/googleads/v19/enums/types/change_status_resource_type.py b/google/ads/googleads/v23/enums/types/change_status_resource_type.py similarity index 97% rename from google/ads/googleads/v19/enums/types/change_status_resource_type.py rename to google/ads/googleads/v23/enums/types/change_status_resource_type.py index 2b3c39f8d..6e2ace9e5 100644 --- a/google/ads/googleads/v19/enums/types/change_status_resource_type.py +++ b/google/ads/googleads/v23/enums/types/change_status_resource_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ChangeStatusResourceTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/click_type.py b/google/ads/googleads/v23/enums/types/click_type.py similarity index 85% rename from google/ads/googleads/v19/enums/types/click_type.py rename to google/ads/googleads/v23/enums/types/click_type.py index 6c94fac25..5c21ab024 100644 --- a/google/ads/googleads/v19/enums/types/click_type.py +++ b/google/ads/googleads/v23/enums/types/click_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ClickTypeEnum", }, @@ -153,6 +153,26 @@ class ClickType(proto.Enum): AD Images. TRAVEL_ASSETS (59): Travel Feed Assets. + VEHICLE_ASSETS (60): + Vehicle Feed Assets. + PRODUCT_ASSETS (61): + Product Feed Assets. + VIDEO_CHANNEL_CLICK (62): + Click on channel icon that navigates the user + to the corresponding YouTube channel. + VIDEO_RELATED_VIDEOS_CLICK (63): + Click on a related video that navigates the + user to the video watch page. + CLICK_TO_MESSAGE_THIRD_PARTY_CLICK (64): + Click on message button that navigates the + user to a third-party messaging app. If the app + is not installed, the ad will not show on + Android, and the button will redirect to the app + install page on iOS. + CLICK_TO_MESSAGE_LANDING_PAGE_CLICK (65): + Click on non-button surface of message ad + that navigates the user to the Google-hosted + landing page. """ UNSPECIFIED = 0 @@ -213,6 +233,12 @@ class ClickType(proto.Enum): CROSS_NETWORK = 57 AD_IMAGE = 58 TRAVEL_ASSETS = 59 + VEHICLE_ASSETS = 60 + PRODUCT_ASSETS = 61 + VIDEO_CHANNEL_CLICK = 62 + VIDEO_RELATED_VIDEOS_CLICK = 63 + CLICK_TO_MESSAGE_THIRD_PARTY_CLICK = 64 + CLICK_TO_MESSAGE_LANDING_PAGE_CLICK = 65 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/combined_audience_status.py b/google/ads/googleads/v23/enums/types/combined_audience_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/combined_audience_status.py rename to google/ads/googleads/v23/enums/types/combined_audience_status.py index 02ec4b3ea..352a14fb0 100644 --- a/google/ads/googleads/v19/enums/types/combined_audience_status.py +++ b/google/ads/googleads/v23/enums/types/combined_audience_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CombinedAudienceStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/consent_status.py b/google/ads/googleads/v23/enums/types/consent_status.py similarity index 93% rename from google/ads/googleads/v19/enums/types/consent_status.py rename to google/ads/googleads/v23/enums/types/consent_status.py index d0d68e72a..ab1672439 100644 --- a/google/ads/googleads/v19/enums/types/consent_status.py +++ b/google/ads/googleads/v23/enums/types/consent_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConsentStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/content_label_type.py b/google/ads/googleads/v23/enums/types/content_label_type.py similarity index 98% rename from google/ads/googleads/v19/enums/types/content_label_type.py rename to google/ads/googleads/v23/enums/types/content_label_type.py index ea88580b2..440edddff 100644 --- a/google/ads/googleads/v19/enums/types/content_label_type.py +++ b/google/ads/googleads/v23/enums/types/content_label_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ContentLabelTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_action_category.py b/google/ads/googleads/v23/enums/types/conversion_action_category.py similarity index 98% rename from google/ads/googleads/v19/enums/types/conversion_action_category.py rename to google/ads/googleads/v23/enums/types/conversion_action_category.py index 94c53b0a7..8d1b6d6af 100644 --- a/google/ads/googleads/v19/enums/types/conversion_action_category.py +++ b/google/ads/googleads/v23/enums/types/conversion_action_category.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionActionCategoryEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_action_counting_type.py b/google/ads/googleads/v23/enums/types/conversion_action_counting_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/conversion_action_counting_type.py rename to google/ads/googleads/v23/enums/types/conversion_action_counting_type.py index e2789dfeb..8c9aa2351 100644 --- a/google/ads/googleads/v19/enums/types/conversion_action_counting_type.py +++ b/google/ads/googleads/v23/enums/types/conversion_action_counting_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionActionCountingTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_action_status.py b/google/ads/googleads/v23/enums/types/conversion_action_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/conversion_action_status.py rename to google/ads/googleads/v23/enums/types/conversion_action_status.py index ee3314044..1f929e6c6 100644 --- a/google/ads/googleads/v19/enums/types/conversion_action_status.py +++ b/google/ads/googleads/v23/enums/types/conversion_action_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionActionStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_action_type.py b/google/ads/googleads/v23/enums/types/conversion_action_type.py similarity index 99% rename from google/ads/googleads/v19/enums/types/conversion_action_type.py rename to google/ads/googleads/v23/enums/types/conversion_action_type.py index 444868733..54e8d89e5 100644 --- a/google/ads/googleads/v19/enums/types/conversion_action_type.py +++ b/google/ads/googleads/v23/enums/types/conversion_action_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionActionTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_adjustment_type.py b/google/ads/googleads/v23/enums/types/conversion_adjustment_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/conversion_adjustment_type.py rename to google/ads/googleads/v23/enums/types/conversion_adjustment_type.py index e42e3dab9..91a023f53 100644 --- a/google/ads/googleads/v19/enums/types/conversion_adjustment_type.py +++ b/google/ads/googleads/v23/enums/types/conversion_adjustment_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionAdjustmentTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_attribution_event_type.py b/google/ads/googleads/v23/enums/types/conversion_attribution_event_type.py similarity index 87% rename from google/ads/googleads/v19/enums/types/conversion_attribution_event_type.py rename to google/ads/googleads/v23/enums/types/conversion_attribution_event_type.py index 3efaa0bf4..1983ef26e 100644 --- a/google/ads/googleads/v19/enums/types/conversion_attribution_event_type.py +++ b/google/ads/googleads/v23/enums/types/conversion_attribution_event_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionAttributionEventTypeEnum", }, @@ -48,12 +48,16 @@ class ConversionAttributionEventType(proto.Enum): INTERACTION (3): The conversion is attributed to an interaction. + ENGAGED_VIEW (4): + The conversion is attributed to a 10s engaged + view. """ UNSPECIFIED = 0 UNKNOWN = 1 IMPRESSION = 2 INTERACTION = 3 + ENGAGED_VIEW = 4 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/conversion_custom_variable_status.py b/google/ads/googleads/v23/enums/types/conversion_custom_variable_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/conversion_custom_variable_status.py rename to google/ads/googleads/v23/enums/types/conversion_custom_variable_status.py index 39c757f1e..cced1be45 100644 --- a/google/ads/googleads/v19/enums/types/conversion_custom_variable_status.py +++ b/google/ads/googleads/v23/enums/types/conversion_custom_variable_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionCustomVariableStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_customer_type.py b/google/ads/googleads/v23/enums/types/conversion_customer_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/conversion_customer_type.py rename to google/ads/googleads/v23/enums/types/conversion_customer_type.py index 61922488a..589192e59 100644 --- a/google/ads/googleads/v19/enums/types/conversion_customer_type.py +++ b/google/ads/googleads/v23/enums/types/conversion_customer_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionCustomerTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_environment_enum.py b/google/ads/googleads/v23/enums/types/conversion_environment_enum.py similarity index 94% rename from google/ads/googleads/v19/enums/types/conversion_environment_enum.py rename to google/ads/googleads/v23/enums/types/conversion_environment_enum.py index 6df27edf1..55b7e265f 100644 --- a/google/ads/googleads/v19/enums/types/conversion_environment_enum.py +++ b/google/ads/googleads/v23/enums/types/conversion_environment_enum.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionEnvironmentEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_lag_bucket.py b/google/ads/googleads/v23/enums/types/conversion_lag_bucket.py similarity index 98% rename from google/ads/googleads/v19/enums/types/conversion_lag_bucket.py rename to google/ads/googleads/v23/enums/types/conversion_lag_bucket.py index 399b21bbf..8b53894e3 100644 --- a/google/ads/googleads/v19/enums/types/conversion_lag_bucket.py +++ b/google/ads/googleads/v23/enums/types/conversion_lag_bucket.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionLagBucketEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_or_adjustment_lag_bucket.py b/google/ads/googleads/v23/enums/types/conversion_or_adjustment_lag_bucket.py similarity index 99% rename from google/ads/googleads/v19/enums/types/conversion_or_adjustment_lag_bucket.py rename to google/ads/googleads/v23/enums/types/conversion_or_adjustment_lag_bucket.py index 504c596c8..a4a7eedb9 100644 --- a/google/ads/googleads/v19/enums/types/conversion_or_adjustment_lag_bucket.py +++ b/google/ads/googleads/v23/enums/types/conversion_or_adjustment_lag_bucket.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionOrAdjustmentLagBucketEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_origin.py b/google/ads/googleads/v23/enums/types/conversion_origin.py similarity index 96% rename from google/ads/googleads/v19/enums/types/conversion_origin.py rename to google/ads/googleads/v23/enums/types/conversion_origin.py index 2293f83e1..ad85ef394 100644 --- a/google/ads/googleads/v19/enums/types/conversion_origin.py +++ b/google/ads/googleads/v23/enums/types/conversion_origin.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionOriginEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_tracking_status_enum.py b/google/ads/googleads/v23/enums/types/conversion_tracking_status_enum.py similarity index 96% rename from google/ads/googleads/v19/enums/types/conversion_tracking_status_enum.py rename to google/ads/googleads/v23/enums/types/conversion_tracking_status_enum.py index 098016c05..993c9fdc2 100644 --- a/google/ads/googleads/v19/enums/types/conversion_tracking_status_enum.py +++ b/google/ads/googleads/v23/enums/types/conversion_tracking_status_enum.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionTrackingStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_value_rule_primary_dimension.py b/google/ads/googleads/v23/enums/types/conversion_value_rule_primary_dimension.py similarity index 96% rename from google/ads/googleads/v19/enums/types/conversion_value_rule_primary_dimension.py rename to google/ads/googleads/v23/enums/types/conversion_value_rule_primary_dimension.py index 91827ae4d..2cb168249 100644 --- a/google/ads/googleads/v19/enums/types/conversion_value_rule_primary_dimension.py +++ b/google/ads/googleads/v23/enums/types/conversion_value_rule_primary_dimension.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionValueRulePrimaryDimensionEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_value_rule_set_status.py b/google/ads/googleads/v23/enums/types/conversion_value_rule_set_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/conversion_value_rule_set_status.py rename to google/ads/googleads/v23/enums/types/conversion_value_rule_set_status.py index 5d426f07c..3a5bb5dc9 100644 --- a/google/ads/googleads/v19/enums/types/conversion_value_rule_set_status.py +++ b/google/ads/googleads/v23/enums/types/conversion_value_rule_set_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionValueRuleSetStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/conversion_value_rule_status.py b/google/ads/googleads/v23/enums/types/conversion_value_rule_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/conversion_value_rule_status.py rename to google/ads/googleads/v23/enums/types/conversion_value_rule_status.py index 6c05de0e0..aa31902d4 100644 --- a/google/ads/googleads/v19/enums/types/conversion_value_rule_status.py +++ b/google/ads/googleads/v23/enums/types/conversion_value_rule_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConversionValueRuleStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/converting_user_prior_engagement_type_and_ltv_bucket.py b/google/ads/googleads/v23/enums/types/converting_user_prior_engagement_type_and_ltv_bucket.py similarity index 95% rename from google/ads/googleads/v19/enums/types/converting_user_prior_engagement_type_and_ltv_bucket.py rename to google/ads/googleads/v23/enums/types/converting_user_prior_engagement_type_and_ltv_bucket.py index 6103b06d5..1cdcab784 100644 --- a/google/ads/googleads/v19/enums/types/converting_user_prior_engagement_type_and_ltv_bucket.py +++ b/google/ads/googleads/v23/enums/types/converting_user_prior_engagement_type_and_ltv_bucket.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ConvertingUserPriorEngagementTypeAndLtvBucketEnum", }, diff --git a/google/ads/googleads/v19/enums/types/criterion_category_channel_availability_mode.py b/google/ads/googleads/v23/enums/types/criterion_category_channel_availability_mode.py similarity index 96% rename from google/ads/googleads/v19/enums/types/criterion_category_channel_availability_mode.py rename to google/ads/googleads/v23/enums/types/criterion_category_channel_availability_mode.py index 01b8a7196..7a44981d9 100644 --- a/google/ads/googleads/v19/enums/types/criterion_category_channel_availability_mode.py +++ b/google/ads/googleads/v23/enums/types/criterion_category_channel_availability_mode.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CriterionCategoryChannelAvailabilityModeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/criterion_category_locale_availability_mode.py b/google/ads/googleads/v23/enums/types/criterion_category_locale_availability_mode.py similarity index 96% rename from google/ads/googleads/v19/enums/types/criterion_category_locale_availability_mode.py rename to google/ads/googleads/v23/enums/types/criterion_category_locale_availability_mode.py index 0942ce5d8..f83593fe7 100644 --- a/google/ads/googleads/v19/enums/types/criterion_category_locale_availability_mode.py +++ b/google/ads/googleads/v23/enums/types/criterion_category_locale_availability_mode.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CriterionCategoryLocaleAvailabilityModeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/criterion_system_serving_status.py b/google/ads/googleads/v23/enums/types/criterion_system_serving_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/criterion_system_serving_status.py rename to google/ads/googleads/v23/enums/types/criterion_system_serving_status.py index ff4a4a963..8e8c13d9a 100644 --- a/google/ads/googleads/v19/enums/types/criterion_system_serving_status.py +++ b/google/ads/googleads/v23/enums/types/criterion_system_serving_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CriterionSystemServingStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/criterion_type.py b/google/ads/googleads/v23/enums/types/criterion_type.py similarity index 88% rename from google/ads/googleads/v19/enums/types/criterion_type.py rename to google/ads/googleads/v23/enums/types/criterion_type.py index b63758a60..9365f2b83 100644 --- a/google/ads/googleads/v19/enums/types/criterion_type.py +++ b/google/ads/googleads/v23/enums/types/criterion_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CriterionTypeEnum", }, @@ -122,6 +122,17 @@ class CriterionType(proto.Enum): Brand List LIFE_EVENT (41): Life Event + WEBPAGE_LIST (42): + Webpage List + VIDEO_LINEUP (43): + Video lineup + PLACEMENT_LIST (44): + Placement List + VERTICAL_ADS_ITEM_GROUP_RULE_LIST (45): + A list of rules for item groups in Vertical + Ads. + VERTICAL_ADS_ITEM_GROUP_RULE (46): + A rule for an item group in Vertical Ads. """ UNSPECIFIED = 0 @@ -166,6 +177,11 @@ class CriterionType(proto.Enum): BRAND = 39 BRAND_LIST = 40 LIFE_EVENT = 41 + WEBPAGE_LIST = 42 + VIDEO_LINEUP = 43 + PLACEMENT_LIST = 44 + VERTICAL_ADS_ITEM_GROUP_RULE_LIST = 45 + VERTICAL_ADS_ITEM_GROUP_RULE = 46 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/custom_audience_member_type.py b/google/ads/googleads/v23/enums/types/custom_audience_member_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/custom_audience_member_type.py rename to google/ads/googleads/v23/enums/types/custom_audience_member_type.py index 5bdeb6654..33609e8c9 100644 --- a/google/ads/googleads/v19/enums/types/custom_audience_member_type.py +++ b/google/ads/googleads/v23/enums/types/custom_audience_member_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomAudienceMemberTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/custom_audience_status.py b/google/ads/googleads/v23/enums/types/custom_audience_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/custom_audience_status.py rename to google/ads/googleads/v23/enums/types/custom_audience_status.py index b8785a41b..9cb18463b 100644 --- a/google/ads/googleads/v19/enums/types/custom_audience_status.py +++ b/google/ads/googleads/v23/enums/types/custom_audience_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomAudienceStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/custom_audience_type.py b/google/ads/googleads/v23/enums/types/custom_audience_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/custom_audience_type.py rename to google/ads/googleads/v23/enums/types/custom_audience_type.py index 31788ad43..433d94a34 100644 --- a/google/ads/googleads/v19/enums/types/custom_audience_type.py +++ b/google/ads/googleads/v23/enums/types/custom_audience_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomAudienceTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/custom_conversion_goal_status.py b/google/ads/googleads/v23/enums/types/custom_conversion_goal_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/custom_conversion_goal_status.py rename to google/ads/googleads/v23/enums/types/custom_conversion_goal_status.py index 521aa6541..00efdcc46 100644 --- a/google/ads/googleads/v19/enums/types/custom_conversion_goal_status.py +++ b/google/ads/googleads/v23/enums/types/custom_conversion_goal_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomConversionGoalStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/custom_interest_member_type.py b/google/ads/googleads/v23/enums/types/custom_interest_member_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/custom_interest_member_type.py rename to google/ads/googleads/v23/enums/types/custom_interest_member_type.py index f7313378e..2497bd155 100644 --- a/google/ads/googleads/v19/enums/types/custom_interest_member_type.py +++ b/google/ads/googleads/v23/enums/types/custom_interest_member_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomInterestMemberTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/custom_interest_status.py b/google/ads/googleads/v23/enums/types/custom_interest_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/custom_interest_status.py rename to google/ads/googleads/v23/enums/types/custom_interest_status.py index a6b6a93c4..4fd5b74fc 100644 --- a/google/ads/googleads/v19/enums/types/custom_interest_status.py +++ b/google/ads/googleads/v23/enums/types/custom_interest_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomInterestStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/custom_interest_type.py b/google/ads/googleads/v23/enums/types/custom_interest_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/custom_interest_type.py rename to google/ads/googleads/v23/enums/types/custom_interest_type.py index 2fedbb87e..d8742efbd 100644 --- a/google/ads/googleads/v19/enums/types/custom_interest_type.py +++ b/google/ads/googleads/v23/enums/types/custom_interest_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomInterestTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/customer_acquisition_optimization_mode.py b/google/ads/googleads/v23/enums/types/customer_acquisition_optimization_mode.py similarity index 95% rename from google/ads/googleads/v19/enums/types/customer_acquisition_optimization_mode.py rename to google/ads/googleads/v23/enums/types/customer_acquisition_optimization_mode.py index d15771409..da93021d2 100644 --- a/google/ads/googleads/v19/enums/types/customer_acquisition_optimization_mode.py +++ b/google/ads/googleads/v23/enums/types/customer_acquisition_optimization_mode.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomerAcquisitionOptimizationModeEnum", }, diff --git a/google/ads/googleads/v23/enums/types/customer_lifecycle_optimization_mode.py b/google/ads/googleads/v23/enums/types/customer_lifecycle_optimization_mode.py new file mode 100644 index 000000000..dca06e731 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/customer_lifecycle_optimization_mode.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "CustomerLifecycleOptimizationModeEnum", + }, +) + + +class CustomerLifecycleOptimizationModeEnum(proto.Message): + r"""Container for enum describing possible customer lifecycle + optimization modes. + + """ + + class CustomerLifecycleOptimizationMode(proto.Enum): + r"""Possible customer acquisition goal optimization modes. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + TARGET_ALL (2): + The mode is used when the campaign optimizes + for all customers, which is the default value. + TARGET_SPECIFIC (3): + This mode configures the campaign to target + only customers who have previously interacted + but are now lapsed or disengaged. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + TARGET_ALL = 2 + TARGET_SPECIFIC = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/customer_match_upload_key_type.py b/google/ads/googleads/v23/enums/types/customer_match_upload_key_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/customer_match_upload_key_type.py rename to google/ads/googleads/v23/enums/types/customer_match_upload_key_type.py index b17c4b9ad..64be64205 100644 --- a/google/ads/googleads/v19/enums/types/customer_match_upload_key_type.py +++ b/google/ads/googleads/v23/enums/types/customer_match_upload_key_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomerMatchUploadKeyTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/customer_pay_per_conversion_eligibility_failure_reason.py b/google/ads/googleads/v23/enums/types/customer_pay_per_conversion_eligibility_failure_reason.py similarity index 96% rename from google/ads/googleads/v19/enums/types/customer_pay_per_conversion_eligibility_failure_reason.py rename to google/ads/googleads/v23/enums/types/customer_pay_per_conversion_eligibility_failure_reason.py index b2aceaeac..a35ff0275 100644 --- a/google/ads/googleads/v19/enums/types/customer_pay_per_conversion_eligibility_failure_reason.py +++ b/google/ads/googleads/v23/enums/types/customer_pay_per_conversion_eligibility_failure_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomerPayPerConversionEligibilityFailureReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/customer_status.py b/google/ads/googleads/v23/enums/types/customer_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/customer_status.py rename to google/ads/googleads/v23/enums/types/customer_status.py index f0c5a1697..b85ea95a0 100644 --- a/google/ads/googleads/v19/enums/types/customer_status.py +++ b/google/ads/googleads/v23/enums/types/customer_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomerStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/customizer_attribute_status.py b/google/ads/googleads/v23/enums/types/customizer_attribute_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/customizer_attribute_status.py rename to google/ads/googleads/v23/enums/types/customizer_attribute_status.py index a486abb65..7d5ede575 100644 --- a/google/ads/googleads/v19/enums/types/customizer_attribute_status.py +++ b/google/ads/googleads/v23/enums/types/customizer_attribute_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomizerAttributeStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/customizer_attribute_type.py b/google/ads/googleads/v23/enums/types/customizer_attribute_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/customizer_attribute_type.py rename to google/ads/googleads/v23/enums/types/customizer_attribute_type.py index f99f230f9..de325040c 100644 --- a/google/ads/googleads/v19/enums/types/customizer_attribute_type.py +++ b/google/ads/googleads/v23/enums/types/customizer_attribute_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomizerAttributeTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/customizer_value_status.py b/google/ads/googleads/v23/enums/types/customizer_value_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/customizer_value_status.py rename to google/ads/googleads/v23/enums/types/customizer_value_status.py index 537e0089f..ca38fcdc0 100644 --- a/google/ads/googleads/v19/enums/types/customizer_value_status.py +++ b/google/ads/googleads/v23/enums/types/customizer_value_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "CustomizerValueStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/data_driven_model_status.py b/google/ads/googleads/v23/enums/types/data_driven_model_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/data_driven_model_status.py rename to google/ads/googleads/v23/enums/types/data_driven_model_status.py index b59522ece..3b5274a8b 100644 --- a/google/ads/googleads/v19/enums/types/data_driven_model_status.py +++ b/google/ads/googleads/v23/enums/types/data_driven_model_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "DataDrivenModelStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/data_link_status.py b/google/ads/googleads/v23/enums/types/data_link_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/data_link_status.py rename to google/ads/googleads/v23/enums/types/data_link_status.py index 71565170c..85043feb2 100644 --- a/google/ads/googleads/v19/enums/types/data_link_status.py +++ b/google/ads/googleads/v23/enums/types/data_link_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "DataLinkStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/data_link_type.py b/google/ads/googleads/v23/enums/types/data_link_type.py similarity index 93% rename from google/ads/googleads/v19/enums/types/data_link_type.py rename to google/ads/googleads/v23/enums/types/data_link_type.py index 77202e6ea..78c9c562d 100644 --- a/google/ads/googleads/v19/enums/types/data_link_type.py +++ b/google/ads/googleads/v23/enums/types/data_link_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "DataLinkTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/day_of_week.py b/google/ads/googleads/v23/enums/types/day_of_week.py similarity index 95% rename from google/ads/googleads/v19/enums/types/day_of_week.py rename to google/ads/googleads/v23/enums/types/day_of_week.py index 0515c7c89..5bb36677c 100644 --- a/google/ads/googleads/v19/enums/types/day_of_week.py +++ b/google/ads/googleads/v23/enums/types/day_of_week.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "DayOfWeekEnum", }, diff --git a/google/ads/googleads/v19/enums/types/demand_gen_channel_config.py b/google/ads/googleads/v23/enums/types/demand_gen_channel_config.py similarity index 95% rename from google/ads/googleads/v19/enums/types/demand_gen_channel_config.py rename to google/ads/googleads/v23/enums/types/demand_gen_channel_config.py index eeb887688..87bd44300 100644 --- a/google/ads/googleads/v19/enums/types/demand_gen_channel_config.py +++ b/google/ads/googleads/v23/enums/types/demand_gen_channel_config.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "DemandGenChannelConfigEnum", }, diff --git a/google/ads/googleads/v19/enums/types/demand_gen_channel_strategy.py b/google/ads/googleads/v23/enums/types/demand_gen_channel_strategy.py similarity index 95% rename from google/ads/googleads/v19/enums/types/demand_gen_channel_strategy.py rename to google/ads/googleads/v23/enums/types/demand_gen_channel_strategy.py index 1f18e5253..b1bf3cc5a 100644 --- a/google/ads/googleads/v19/enums/types/demand_gen_channel_strategy.py +++ b/google/ads/googleads/v23/enums/types/demand_gen_channel_strategy.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "DemandGenChannelStrategyEnum", }, diff --git a/google/ads/googleads/v19/enums/types/device.py b/google/ads/googleads/v23/enums/types/device.py similarity index 95% rename from google/ads/googleads/v19/enums/types/device.py rename to google/ads/googleads/v23/enums/types/device.py index c040ab34a..a28a95399 100644 --- a/google/ads/googleads/v19/enums/types/device.py +++ b/google/ads/googleads/v23/enums/types/device.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "DeviceEnum", }, diff --git a/google/ads/googleads/v19/enums/types/display_ad_format_setting.py b/google/ads/googleads/v23/enums/types/display_ad_format_setting.py similarity index 94% rename from google/ads/googleads/v19/enums/types/display_ad_format_setting.py rename to google/ads/googleads/v23/enums/types/display_ad_format_setting.py index 3b5f3e3a3..82b05c5bc 100644 --- a/google/ads/googleads/v19/enums/types/display_ad_format_setting.py +++ b/google/ads/googleads/v23/enums/types/display_ad_format_setting.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "DisplayAdFormatSettingEnum", }, diff --git a/google/ads/googleads/v19/enums/types/display_upload_product_type.py b/google/ads/googleads/v23/enums/types/display_upload_product_type.py similarity index 98% rename from google/ads/googleads/v19/enums/types/display_upload_product_type.py rename to google/ads/googleads/v23/enums/types/display_upload_product_type.py index 23ab125b6..6e4f2fa76 100644 --- a/google/ads/googleads/v19/enums/types/display_upload_product_type.py +++ b/google/ads/googleads/v23/enums/types/display_upload_product_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "DisplayUploadProductTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/distance_bucket.py b/google/ads/googleads/v23/enums/types/distance_bucket.py similarity index 98% rename from google/ads/googleads/v19/enums/types/distance_bucket.py rename to google/ads/googleads/v23/enums/types/distance_bucket.py index c66c1851a..29f041c04 100644 --- a/google/ads/googleads/v19/enums/types/distance_bucket.py +++ b/google/ads/googleads/v23/enums/types/distance_bucket.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "DistanceBucketEnum", }, diff --git a/google/ads/googleads/v19/enums/types/eu_political_advertising_status.py b/google/ads/googleads/v23/enums/types/eu_political_advertising_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/eu_political_advertising_status.py rename to google/ads/googleads/v23/enums/types/eu_political_advertising_status.py index 20b3d9153..425bf65a3 100644 --- a/google/ads/googleads/v19/enums/types/eu_political_advertising_status.py +++ b/google/ads/googleads/v23/enums/types/eu_political_advertising_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "EuPoliticalAdvertisingStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/experiment_metric.py b/google/ads/googleads/v23/enums/types/experiment_metric.py similarity index 97% rename from google/ads/googleads/v19/enums/types/experiment_metric.py rename to google/ads/googleads/v23/enums/types/experiment_metric.py index d7181f074..5ecd9480e 100644 --- a/google/ads/googleads/v19/enums/types/experiment_metric.py +++ b/google/ads/googleads/v23/enums/types/experiment_metric.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ExperimentMetricEnum", }, diff --git a/google/ads/googleads/v19/enums/types/experiment_metric_direction.py b/google/ads/googleads/v23/enums/types/experiment_metric_direction.py similarity index 95% rename from google/ads/googleads/v19/enums/types/experiment_metric_direction.py rename to google/ads/googleads/v23/enums/types/experiment_metric_direction.py index fb668735a..b1115bd76 100644 --- a/google/ads/googleads/v19/enums/types/experiment_metric_direction.py +++ b/google/ads/googleads/v23/enums/types/experiment_metric_direction.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ExperimentMetricDirectionEnum", }, diff --git a/google/ads/googleads/v19/enums/types/experiment_status.py b/google/ads/googleads/v23/enums/types/experiment_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/experiment_status.py rename to google/ads/googleads/v23/enums/types/experiment_status.py index 910bced53..09f56f155 100644 --- a/google/ads/googleads/v19/enums/types/experiment_status.py +++ b/google/ads/googleads/v23/enums/types/experiment_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ExperimentStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/experiment_type.py b/google/ads/googleads/v23/enums/types/experiment_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/experiment_type.py rename to google/ads/googleads/v23/enums/types/experiment_type.py index 8b144d439..b29b23d65 100644 --- a/google/ads/googleads/v19/enums/types/experiment_type.py +++ b/google/ads/googleads/v23/enums/types/experiment_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ExperimentTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/external_conversion_source.py b/google/ads/googleads/v23/enums/types/external_conversion_source.py similarity index 98% rename from google/ads/googleads/v19/enums/types/external_conversion_source.py rename to google/ads/googleads/v23/enums/types/external_conversion_source.py index 993ee0048..638825c22 100644 --- a/google/ads/googleads/v19/enums/types/external_conversion_source.py +++ b/google/ads/googleads/v23/enums/types/external_conversion_source.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ExternalConversionSourceEnum", }, diff --git a/google/ads/googleads/v19/enums/types/fixed_cpm_goal.py b/google/ads/googleads/v23/enums/types/fixed_cpm_goal.py similarity index 95% rename from google/ads/googleads/v19/enums/types/fixed_cpm_goal.py rename to google/ads/googleads/v23/enums/types/fixed_cpm_goal.py index 09e59b3cf..3b4385a28 100644 --- a/google/ads/googleads/v19/enums/types/fixed_cpm_goal.py +++ b/google/ads/googleads/v23/enums/types/fixed_cpm_goal.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "FixedCpmGoalEnum", }, diff --git a/google/ads/googleads/v19/enums/types/fixed_cpm_target_frequency_time_unit.py b/google/ads/googleads/v23/enums/types/fixed_cpm_target_frequency_time_unit.py similarity index 94% rename from google/ads/googleads/v19/enums/types/fixed_cpm_target_frequency_time_unit.py rename to google/ads/googleads/v23/enums/types/fixed_cpm_target_frequency_time_unit.py index ad7f834d2..9bbb8bb2f 100644 --- a/google/ads/googleads/v19/enums/types/fixed_cpm_target_frequency_time_unit.py +++ b/google/ads/googleads/v23/enums/types/fixed_cpm_target_frequency_time_unit.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "FixedCpmTargetFrequencyTimeUnitEnum", }, diff --git a/google/ads/googleads/v19/enums/types/frequency_cap_event_type.py b/google/ads/googleads/v23/enums/types/frequency_cap_event_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/frequency_cap_event_type.py rename to google/ads/googleads/v23/enums/types/frequency_cap_event_type.py index e8298d9c3..00745a0f2 100644 --- a/google/ads/googleads/v19/enums/types/frequency_cap_event_type.py +++ b/google/ads/googleads/v23/enums/types/frequency_cap_event_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "FrequencyCapEventTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/frequency_cap_level.py b/google/ads/googleads/v23/enums/types/frequency_cap_level.py similarity index 95% rename from google/ads/googleads/v19/enums/types/frequency_cap_level.py rename to google/ads/googleads/v23/enums/types/frequency_cap_level.py index 5b619a0a1..24544882d 100644 --- a/google/ads/googleads/v19/enums/types/frequency_cap_level.py +++ b/google/ads/googleads/v23/enums/types/frequency_cap_level.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "FrequencyCapLevelEnum", }, diff --git a/google/ads/googleads/v19/enums/types/frequency_cap_time_unit.py b/google/ads/googleads/v23/enums/types/frequency_cap_time_unit.py similarity index 94% rename from google/ads/googleads/v19/enums/types/frequency_cap_time_unit.py rename to google/ads/googleads/v23/enums/types/frequency_cap_time_unit.py index 5a359832a..9d07b1b9b 100644 --- a/google/ads/googleads/v19/enums/types/frequency_cap_time_unit.py +++ b/google/ads/googleads/v23/enums/types/frequency_cap_time_unit.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "FrequencyCapTimeUnitEnum", }, diff --git a/google/ads/googleads/v19/enums/types/gender_type.py b/google/ads/googleads/v23/enums/types/gender_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/gender_type.py rename to google/ads/googleads/v23/enums/types/gender_type.py index 451199689..f22e17816 100644 --- a/google/ads/googleads/v19/enums/types/gender_type.py +++ b/google/ads/googleads/v23/enums/types/gender_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "GenderTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/geo_target_constant_status.py b/google/ads/googleads/v23/enums/types/geo_target_constant_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/geo_target_constant_status.py rename to google/ads/googleads/v23/enums/types/geo_target_constant_status.py index 03eee4fbc..b7756d7a4 100644 --- a/google/ads/googleads/v19/enums/types/geo_target_constant_status.py +++ b/google/ads/googleads/v23/enums/types/geo_target_constant_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "GeoTargetConstantStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/geo_targeting_type.py b/google/ads/googleads/v23/enums/types/geo_targeting_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/geo_targeting_type.py rename to google/ads/googleads/v23/enums/types/geo_targeting_type.py index 3bbfce7dd..8ea54f75f 100644 --- a/google/ads/googleads/v19/enums/types/geo_targeting_type.py +++ b/google/ads/googleads/v23/enums/types/geo_targeting_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "GeoTargetingTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/goal_config_level.py b/google/ads/googleads/v23/enums/types/goal_config_level.py similarity index 95% rename from google/ads/googleads/v19/enums/types/goal_config_level.py rename to google/ads/googleads/v23/enums/types/goal_config_level.py index 0b714e482..d9d527964 100644 --- a/google/ads/googleads/v19/enums/types/goal_config_level.py +++ b/google/ads/googleads/v23/enums/types/goal_config_level.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "GoalConfigLevelEnum", }, diff --git a/google/ads/googleads/v23/enums/types/goal_optimization_eligibility.py b/google/ads/googleads/v23/enums/types/goal_optimization_eligibility.py new file mode 100644 index 000000000..f31a8e77f --- /dev/null +++ b/google/ads/googleads/v23/enums/types/goal_optimization_eligibility.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "GoalOptimizationEligibilityEnum", + }, +) + + +class GoalOptimizationEligibilityEnum(proto.Message): + r"""Container for enum describing possible goal optimization + eligibility. + + """ + + class GoalOptimizationEligibility(proto.Enum): + r"""The possible goal optimization eligibility. + + Values: + UNSPECIFIED (0): + The goal optimization status has not been + specified. + UNKNOWN (1): + The goal optimization status is not known in + this version. + ELIGIBLE (2): + The goal is eligible for campaign + optimization. + INELIGIBLE (3): + The goal is not eligible for campaign + optimization. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + ELIGIBLE = 2 + INELIGIBLE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/enums/types/goal_type.py b/google/ads/googleads/v23/enums/types/goal_type.py new file mode 100644 index 000000000..1df9862b3 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/goal_type.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "GoalTypeEnum", + }, +) + + +class GoalTypeEnum(proto.Message): + r"""Container for enum describing goal types.""" + + class GoalType(proto.Enum): + r"""The possible value of goal types. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + CUSTOMER_RETENTION (3): + Retention goal, which allows advertisers to + optimize campaigns to win back lapsed customers. + (https://support.google.com/google-ads/answer/14792043?hl=en) + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + CUSTOMER_RETENTION = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/google_ads_field_category.py b/google/ads/googleads/v23/enums/types/google_ads_field_category.py similarity index 95% rename from google/ads/googleads/v19/enums/types/google_ads_field_category.py rename to google/ads/googleads/v23/enums/types/google_ads_field_category.py index 9e0834dd6..28ed30f24 100644 --- a/google/ads/googleads/v19/enums/types/google_ads_field_category.py +++ b/google/ads/googleads/v23/enums/types/google_ads_field_category.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "GoogleAdsFieldCategoryEnum", }, diff --git a/google/ads/googleads/v19/enums/types/google_ads_field_data_type.py b/google/ads/googleads/v23/enums/types/google_ads_field_data_type.py similarity index 97% rename from google/ads/googleads/v19/enums/types/google_ads_field_data_type.py rename to google/ads/googleads/v23/enums/types/google_ads_field_data_type.py index f11eda300..99b184680 100644 --- a/google/ads/googleads/v19/enums/types/google_ads_field_data_type.py +++ b/google/ads/googleads/v23/enums/types/google_ads_field_data_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "GoogleAdsFieldDataTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/google_voice_call_status.py b/google/ads/googleads/v23/enums/types/google_voice_call_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/google_voice_call_status.py rename to google/ads/googleads/v23/enums/types/google_voice_call_status.py index e16172a6e..61aacce34 100644 --- a/google/ads/googleads/v19/enums/types/google_voice_call_status.py +++ b/google/ads/googleads/v23/enums/types/google_voice_call_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "GoogleVoiceCallStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/hotel_asset_suggestion_status.py b/google/ads/googleads/v23/enums/types/hotel_asset_suggestion_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/hotel_asset_suggestion_status.py rename to google/ads/googleads/v23/enums/types/hotel_asset_suggestion_status.py index 86c6cf975..d47eb89e7 100644 --- a/google/ads/googleads/v19/enums/types/hotel_asset_suggestion_status.py +++ b/google/ads/googleads/v23/enums/types/hotel_asset_suggestion_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "HotelAssetSuggestionStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/hotel_date_selection_type.py b/google/ads/googleads/v23/enums/types/hotel_date_selection_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/hotel_date_selection_type.py rename to google/ads/googleads/v23/enums/types/hotel_date_selection_type.py index 71f013468..1583e4eaa 100644 --- a/google/ads/googleads/v19/enums/types/hotel_date_selection_type.py +++ b/google/ads/googleads/v23/enums/types/hotel_date_selection_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "HotelDateSelectionTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/hotel_price_bucket.py b/google/ads/googleads/v23/enums/types/hotel_price_bucket.py similarity index 95% rename from google/ads/googleads/v19/enums/types/hotel_price_bucket.py rename to google/ads/googleads/v23/enums/types/hotel_price_bucket.py index 7b03da850..c8eda25a1 100644 --- a/google/ads/googleads/v19/enums/types/hotel_price_bucket.py +++ b/google/ads/googleads/v23/enums/types/hotel_price_bucket.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "HotelPriceBucketEnum", }, diff --git a/google/ads/googleads/v19/enums/types/hotel_rate_type.py b/google/ads/googleads/v23/enums/types/hotel_rate_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/hotel_rate_type.py rename to google/ads/googleads/v23/enums/types/hotel_rate_type.py index 45df7b27e..cbaffb5af 100644 --- a/google/ads/googleads/v19/enums/types/hotel_rate_type.py +++ b/google/ads/googleads/v23/enums/types/hotel_rate_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "HotelRateTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/hotel_reconciliation_status.py b/google/ads/googleads/v23/enums/types/hotel_reconciliation_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/hotel_reconciliation_status.py rename to google/ads/googleads/v23/enums/types/hotel_reconciliation_status.py index e07c9c14c..e0da181ea 100644 --- a/google/ads/googleads/v19/enums/types/hotel_reconciliation_status.py +++ b/google/ads/googleads/v23/enums/types/hotel_reconciliation_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "HotelReconciliationStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/identity_verification_program.py b/google/ads/googleads/v23/enums/types/identity_verification_program.py similarity index 94% rename from google/ads/googleads/v19/enums/types/identity_verification_program.py rename to google/ads/googleads/v23/enums/types/identity_verification_program.py index f98e0e40d..929c269d6 100644 --- a/google/ads/googleads/v19/enums/types/identity_verification_program.py +++ b/google/ads/googleads/v23/enums/types/identity_verification_program.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "IdentityVerificationProgramEnum", }, diff --git a/google/ads/googleads/v19/enums/types/identity_verification_program_status.py b/google/ads/googleads/v23/enums/types/identity_verification_program_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/identity_verification_program_status.py rename to google/ads/googleads/v23/enums/types/identity_verification_program_status.py index c929205f0..ff8040d71 100644 --- a/google/ads/googleads/v19/enums/types/identity_verification_program_status.py +++ b/google/ads/googleads/v23/enums/types/identity_verification_program_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "IdentityVerificationProgramStatusEnum", }, diff --git a/google/ads/googleads/v23/enums/types/incentive_state.py b/google/ads/googleads/v23/enums/types/incentive_state.py new file mode 100644 index 000000000..0fd9c5c8a --- /dev/null +++ b/google/ads/googleads/v23/enums/types/incentive_state.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "IncentiveStateEnum", + }, +) + + +class IncentiveStateEnum(proto.Message): + r"""Container for the incentive state enum.""" + + class IncentiveState(proto.Enum): + r"""The possible states of a redeemed incentive. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + REDEEMED (2): + The incentive has been redeemed but the + requirements are not yet met. + FULFILLED (3): + The incentive's requirements have been met + but the reward has not yet been granted. + REWARD_GRANTED (4): + The reward for the incentive has been + granted. + EXPIRED (5): + The incentive expired before the requirements + were met. + REWARD_EXPIRED (6): + The granted reward has expired. + INVALIDATED (7): + The incentive was marked as invalid after + redemption. + REWARD_EXHAUSTED (8): + The granted reward has been fully used. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + REDEEMED = 2 + FULFILLED = 3 + REWARD_GRANTED = 4 + EXPIRED = 5 + REWARD_EXPIRED = 6 + INVALIDATED = 7 + REWARD_EXHAUSTED = 8 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/income_range_type.py b/google/ads/googleads/v23/enums/types/income_range_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/income_range_type.py rename to google/ads/googleads/v23/enums/types/income_range_type.py index 3b9ac6787..5a243d87a 100644 --- a/google/ads/googleads/v19/enums/types/income_range_type.py +++ b/google/ads/googleads/v23/enums/types/income_range_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "IncomeRangeTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/insights_knowledge_graph_entity_capabilities.py b/google/ads/googleads/v23/enums/types/insights_knowledge_graph_entity_capabilities.py similarity index 86% rename from google/ads/googleads/v19/enums/types/insights_knowledge_graph_entity_capabilities.py rename to google/ads/googleads/v23/enums/types/insights_knowledge_graph_entity_capabilities.py index 95cc9207d..1e77c1754 100644 --- a/google/ads/googleads/v19/enums/types/insights_knowledge_graph_entity_capabilities.py +++ b/google/ads/googleads/v23/enums/types/insights_knowledge_graph_entity_capabilities.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "InsightsKnowledgeGraphEntityCapabilitiesEnum", }, @@ -44,10 +44,10 @@ class InsightsKnowledgeGraphEntityCapabilities(proto.Enum): The value is unknown in this version. CONTENT_TRENDING_INSIGHTS (2): An entity that is supported to use as a trending topic in - [ContentCreatorInsightsService.GenerateTrendingInsights]. + [ContentCreatorInsightsService.GenerateTrendingInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateTrendingInsights]. CREATOR_ATTRIBUTE (3): An entity that is supported to use as a creator attribute in - [ContentCreatorInsightsService.GenerateCreatorInsights]. + [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateCreatorInsights]. """ UNSPECIFIED = 0 diff --git a/google/ads/googleads/v19/enums/types/insights_trend.py b/google/ads/googleads/v23/enums/types/insights_trend.py similarity index 94% rename from google/ads/googleads/v19/enums/types/insights_trend.py rename to google/ads/googleads/v23/enums/types/insights_trend.py index 284bee287..475db1589 100644 --- a/google/ads/googleads/v19/enums/types/insights_trend.py +++ b/google/ads/googleads/v23/enums/types/insights_trend.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "InsightsTrendEnum", }, diff --git a/google/ads/googleads/v19/enums/types/interaction_event_type.py b/google/ads/googleads/v23/enums/types/interaction_event_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/interaction_event_type.py rename to google/ads/googleads/v23/enums/types/interaction_event_type.py index 92b8740cb..26cb705ba 100644 --- a/google/ads/googleads/v19/enums/types/interaction_event_type.py +++ b/google/ads/googleads/v23/enums/types/interaction_event_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "InteractionEventTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/interaction_type.py b/google/ads/googleads/v23/enums/types/interaction_type.py similarity index 93% rename from google/ads/googleads/v19/enums/types/interaction_type.py rename to google/ads/googleads/v23/enums/types/interaction_type.py index c4633474b..0acdd3f3d 100644 --- a/google/ads/googleads/v19/enums/types/interaction_type.py +++ b/google/ads/googleads/v23/enums/types/interaction_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "InteractionTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/invoice_type.py b/google/ads/googleads/v23/enums/types/invoice_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/invoice_type.py rename to google/ads/googleads/v23/enums/types/invoice_type.py index a4a4051de..7b374fd5d 100644 --- a/google/ads/googleads/v19/enums/types/invoice_type.py +++ b/google/ads/googleads/v23/enums/types/invoice_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "InvoiceTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/keyword_match_type.py b/google/ads/googleads/v23/enums/types/keyword_match_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/keyword_match_type.py rename to google/ads/googleads/v23/enums/types/keyword_match_type.py index c8de35610..994250ea4 100644 --- a/google/ads/googleads/v19/enums/types/keyword_match_type.py +++ b/google/ads/googleads/v23/enums/types/keyword_match_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "KeywordMatchTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/keyword_plan_aggregate_metric_type.py b/google/ads/googleads/v23/enums/types/keyword_plan_aggregate_metric_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/keyword_plan_aggregate_metric_type.py rename to google/ads/googleads/v23/enums/types/keyword_plan_aggregate_metric_type.py index 54f88251c..4ced31432 100644 --- a/google/ads/googleads/v19/enums/types/keyword_plan_aggregate_metric_type.py +++ b/google/ads/googleads/v23/enums/types/keyword_plan_aggregate_metric_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanAggregateMetricTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/keyword_plan_competition_level.py b/google/ads/googleads/v23/enums/types/keyword_plan_competition_level.py similarity index 95% rename from google/ads/googleads/v19/enums/types/keyword_plan_competition_level.py rename to google/ads/googleads/v23/enums/types/keyword_plan_competition_level.py index 7e784742d..4d5e71435 100644 --- a/google/ads/googleads/v19/enums/types/keyword_plan_competition_level.py +++ b/google/ads/googleads/v23/enums/types/keyword_plan_competition_level.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanCompetitionLevelEnum", }, diff --git a/google/ads/googleads/v19/enums/types/keyword_plan_concept_group_type.py b/google/ads/googleads/v23/enums/types/keyword_plan_concept_group_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/keyword_plan_concept_group_type.py rename to google/ads/googleads/v23/enums/types/keyword_plan_concept_group_type.py index 7a4eb182f..e865e9104 100644 --- a/google/ads/googleads/v19/enums/types/keyword_plan_concept_group_type.py +++ b/google/ads/googleads/v23/enums/types/keyword_plan_concept_group_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanConceptGroupTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/keyword_plan_forecast_interval.py b/google/ads/googleads/v23/enums/types/keyword_plan_forecast_interval.py similarity index 95% rename from google/ads/googleads/v19/enums/types/keyword_plan_forecast_interval.py rename to google/ads/googleads/v23/enums/types/keyword_plan_forecast_interval.py index 1607a8cc4..f92b5bd20 100644 --- a/google/ads/googleads/v19/enums/types/keyword_plan_forecast_interval.py +++ b/google/ads/googleads/v23/enums/types/keyword_plan_forecast_interval.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanForecastIntervalEnum", }, diff --git a/google/ads/googleads/v19/enums/types/keyword_plan_keyword_annotation.py b/google/ads/googleads/v23/enums/types/keyword_plan_keyword_annotation.py similarity index 94% rename from google/ads/googleads/v19/enums/types/keyword_plan_keyword_annotation.py rename to google/ads/googleads/v23/enums/types/keyword_plan_keyword_annotation.py index 945db9b69..e0d8e165c 100644 --- a/google/ads/googleads/v19/enums/types/keyword_plan_keyword_annotation.py +++ b/google/ads/googleads/v23/enums/types/keyword_plan_keyword_annotation.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanKeywordAnnotationEnum", }, diff --git a/google/ads/googleads/v19/enums/types/keyword_plan_network.py b/google/ads/googleads/v23/enums/types/keyword_plan_network.py similarity index 94% rename from google/ads/googleads/v19/enums/types/keyword_plan_network.py rename to google/ads/googleads/v23/enums/types/keyword_plan_network.py index 7a36c6761..a37205f5b 100644 --- a/google/ads/googleads/v19/enums/types/keyword_plan_network.py +++ b/google/ads/googleads/v23/enums/types/keyword_plan_network.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanNetworkEnum", }, diff --git a/google/ads/googleads/v19/enums/types/label_status.py b/google/ads/googleads/v23/enums/types/label_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/label_status.py rename to google/ads/googleads/v23/enums/types/label_status.py index 3615fe7e0..f2c39f453 100644 --- a/google/ads/googleads/v19/enums/types/label_status.py +++ b/google/ads/googleads/v23/enums/types/label_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LabelStatusEnum", }, diff --git a/google/ads/googleads/v23/enums/types/landing_page_source.py b/google/ads/googleads/v23/enums/types/landing_page_source.py new file mode 100644 index 000000000..4395eff39 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/landing_page_source.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "LandingPageSourceEnum", + }, +) + + +class LandingPageSourceEnum(proto.Message): + r"""Container for enum describing the source of a landing page in + the landing page report. + + """ + + class LandingPageSource(proto.Enum): + r"""The source of a landing page in the landing page report. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + ADVERTISER (2): + The landing page was explicitly provided by + the advertiser. + AUTOMATIC (3): + The landing page was selected automatically. + This could happen when the advertiser enables AI + Max or other features that automatically select + landing pages and Google selects the best + landing page for the query. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + ADVERTISER = 2 + AUTOMATIC = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/lead_form_call_to_action_type.py b/google/ads/googleads/v23/enums/types/lead_form_call_to_action_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/lead_form_call_to_action_type.py rename to google/ads/googleads/v23/enums/types/lead_form_call_to_action_type.py index a6e35b7ad..b5e8a36f6 100644 --- a/google/ads/googleads/v19/enums/types/lead_form_call_to_action_type.py +++ b/google/ads/googleads/v23/enums/types/lead_form_call_to_action_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LeadFormCallToActionTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/lead_form_desired_intent.py b/google/ads/googleads/v23/enums/types/lead_form_desired_intent.py similarity index 94% rename from google/ads/googleads/v19/enums/types/lead_form_desired_intent.py rename to google/ads/googleads/v23/enums/types/lead_form_desired_intent.py index e6bf1dd45..802d67c38 100644 --- a/google/ads/googleads/v19/enums/types/lead_form_desired_intent.py +++ b/google/ads/googleads/v23/enums/types/lead_form_desired_intent.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LeadFormDesiredIntentEnum", }, diff --git a/google/ads/googleads/v19/enums/types/lead_form_field_user_input_type.py b/google/ads/googleads/v23/enums/types/lead_form_field_user_input_type.py similarity index 99% rename from google/ads/googleads/v19/enums/types/lead_form_field_user_input_type.py rename to google/ads/googleads/v23/enums/types/lead_form_field_user_input_type.py index 0fd95c3f3..50ef85ea1 100644 --- a/google/ads/googleads/v19/enums/types/lead_form_field_user_input_type.py +++ b/google/ads/googleads/v23/enums/types/lead_form_field_user_input_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LeadFormFieldUserInputTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/lead_form_post_submit_call_to_action_type.py b/google/ads/googleads/v23/enums/types/lead_form_post_submit_call_to_action_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/lead_form_post_submit_call_to_action_type.py rename to google/ads/googleads/v23/enums/types/lead_form_post_submit_call_to_action_type.py index ead9e484a..e6c3a97b6 100644 --- a/google/ads/googleads/v19/enums/types/lead_form_post_submit_call_to_action_type.py +++ b/google/ads/googleads/v23/enums/types/lead_form_post_submit_call_to_action_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LeadFormPostSubmitCallToActionTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/legacy_app_install_ad_app_store.py b/google/ads/googleads/v23/enums/types/legacy_app_install_ad_app_store.py similarity index 95% rename from google/ads/googleads/v19/enums/types/legacy_app_install_ad_app_store.py rename to google/ads/googleads/v23/enums/types/legacy_app_install_ad_app_store.py index 4dfff0451..29edf9bed 100644 --- a/google/ads/googleads/v19/enums/types/legacy_app_install_ad_app_store.py +++ b/google/ads/googleads/v23/enums/types/legacy_app_install_ad_app_store.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LegacyAppInstallAdAppStoreEnum", }, diff --git a/google/ads/googleads/v19/enums/types/linked_account_type.py b/google/ads/googleads/v23/enums/types/linked_account_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/linked_account_type.py rename to google/ads/googleads/v23/enums/types/linked_account_type.py index bde66a477..fc104aff8 100644 --- a/google/ads/googleads/v19/enums/types/linked_account_type.py +++ b/google/ads/googleads/v23/enums/types/linked_account_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LinkedAccountTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/linked_product_type.py b/google/ads/googleads/v23/enums/types/linked_product_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/linked_product_type.py rename to google/ads/googleads/v23/enums/types/linked_product_type.py index 6e5af4130..4df44b696 100644 --- a/google/ads/googleads/v19/enums/types/linked_product_type.py +++ b/google/ads/googleads/v23/enums/types/linked_product_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LinkedProductTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/listing_group_filter_custom_attribute_index.py b/google/ads/googleads/v23/enums/types/listing_group_filter_custom_attribute_index.py similarity index 95% rename from google/ads/googleads/v19/enums/types/listing_group_filter_custom_attribute_index.py rename to google/ads/googleads/v23/enums/types/listing_group_filter_custom_attribute_index.py index 2ff7cdbc5..6c645385d 100644 --- a/google/ads/googleads/v19/enums/types/listing_group_filter_custom_attribute_index.py +++ b/google/ads/googleads/v23/enums/types/listing_group_filter_custom_attribute_index.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ListingGroupFilterCustomAttributeIndexEnum", }, diff --git a/google/ads/googleads/v19/enums/types/listing_group_filter_listing_source.py b/google/ads/googleads/v23/enums/types/listing_group_filter_listing_source.py similarity index 95% rename from google/ads/googleads/v19/enums/types/listing_group_filter_listing_source.py rename to google/ads/googleads/v23/enums/types/listing_group_filter_listing_source.py index 6e9547adb..b25daa1f0 100644 --- a/google/ads/googleads/v19/enums/types/listing_group_filter_listing_source.py +++ b/google/ads/googleads/v23/enums/types/listing_group_filter_listing_source.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ListingGroupFilterListingSourceEnum", }, diff --git a/google/ads/googleads/v19/enums/types/listing_group_filter_product_category_level.py b/google/ads/googleads/v23/enums/types/listing_group_filter_product_category_level.py similarity index 95% rename from google/ads/googleads/v19/enums/types/listing_group_filter_product_category_level.py rename to google/ads/googleads/v23/enums/types/listing_group_filter_product_category_level.py index 486dc7398..c00ae2e0c 100644 --- a/google/ads/googleads/v19/enums/types/listing_group_filter_product_category_level.py +++ b/google/ads/googleads/v23/enums/types/listing_group_filter_product_category_level.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ListingGroupFilterProductCategoryLevelEnum", }, diff --git a/google/ads/googleads/v19/enums/types/listing_group_filter_product_channel.py b/google/ads/googleads/v23/enums/types/listing_group_filter_product_channel.py similarity index 94% rename from google/ads/googleads/v19/enums/types/listing_group_filter_product_channel.py rename to google/ads/googleads/v23/enums/types/listing_group_filter_product_channel.py index e431c6987..9621e0b27 100644 --- a/google/ads/googleads/v19/enums/types/listing_group_filter_product_channel.py +++ b/google/ads/googleads/v23/enums/types/listing_group_filter_product_channel.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ListingGroupFilterProductChannelEnum", }, diff --git a/google/ads/googleads/v19/enums/types/listing_group_filter_product_condition.py b/google/ads/googleads/v23/enums/types/listing_group_filter_product_condition.py similarity index 94% rename from google/ads/googleads/v19/enums/types/listing_group_filter_product_condition.py rename to google/ads/googleads/v23/enums/types/listing_group_filter_product_condition.py index f5797f175..b7e5e47e7 100644 --- a/google/ads/googleads/v19/enums/types/listing_group_filter_product_condition.py +++ b/google/ads/googleads/v23/enums/types/listing_group_filter_product_condition.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ListingGroupFilterProductConditionEnum", }, diff --git a/google/ads/googleads/v19/enums/types/listing_group_filter_product_type_level.py b/google/ads/googleads/v23/enums/types/listing_group_filter_product_type_level.py similarity index 95% rename from google/ads/googleads/v19/enums/types/listing_group_filter_product_type_level.py rename to google/ads/googleads/v23/enums/types/listing_group_filter_product_type_level.py index 71ca6f098..91f647bc0 100644 --- a/google/ads/googleads/v19/enums/types/listing_group_filter_product_type_level.py +++ b/google/ads/googleads/v23/enums/types/listing_group_filter_product_type_level.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ListingGroupFilterProductTypeLevelEnum", }, diff --git a/google/ads/googleads/v19/enums/types/listing_group_filter_type_enum.py b/google/ads/googleads/v23/enums/types/listing_group_filter_type_enum.py similarity index 95% rename from google/ads/googleads/v19/enums/types/listing_group_filter_type_enum.py rename to google/ads/googleads/v23/enums/types/listing_group_filter_type_enum.py index f0e5844ba..448dbe438 100644 --- a/google/ads/googleads/v19/enums/types/listing_group_filter_type_enum.py +++ b/google/ads/googleads/v23/enums/types/listing_group_filter_type_enum.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ListingGroupFilterTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/listing_group_type.py b/google/ads/googleads/v23/enums/types/listing_group_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/listing_group_type.py rename to google/ads/googleads/v23/enums/types/listing_group_type.py index a15a3db07..91bcf2a94 100644 --- a/google/ads/googleads/v19/enums/types/listing_group_type.py +++ b/google/ads/googleads/v23/enums/types/listing_group_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ListingGroupTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/listing_type.py b/google/ads/googleads/v23/enums/types/listing_type.py similarity index 93% rename from google/ads/googleads/v19/enums/types/listing_type.py rename to google/ads/googleads/v23/enums/types/listing_type.py index d14fd3851..414d69c72 100644 --- a/google/ads/googleads/v19/enums/types/listing_type.py +++ b/google/ads/googleads/v23/enums/types/listing_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ListingTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_business_registration_check_rejection_reason.py b/google/ads/googleads/v23/enums/types/local_services_business_registration_check_rejection_reason.py similarity index 97% rename from google/ads/googleads/v19/enums/types/local_services_business_registration_check_rejection_reason.py rename to google/ads/googleads/v23/enums/types/local_services_business_registration_check_rejection_reason.py index 9b7ed25f5..5ebc0c024 100644 --- a/google/ads/googleads/v19/enums/types/local_services_business_registration_check_rejection_reason.py +++ b/google/ads/googleads/v23/enums/types/local_services_business_registration_check_rejection_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesBusinessRegistrationCheckRejectionReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_business_registration_type.py b/google/ads/googleads/v23/enums/types/local_services_business_registration_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/local_services_business_registration_type.py rename to google/ads/googleads/v23/enums/types/local_services_business_registration_type.py index 6fab2b5e9..03a4e433a 100644 --- a/google/ads/googleads/v19/enums/types/local_services_business_registration_type.py +++ b/google/ads/googleads/v23/enums/types/local_services_business_registration_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesBusinessRegistrationTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_conversation_type.py b/google/ads/googleads/v23/enums/types/local_services_conversation_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/local_services_conversation_type.py rename to google/ads/googleads/v23/enums/types/local_services_conversation_type.py index cdd50a729..172a763e9 100644 --- a/google/ads/googleads/v19/enums/types/local_services_conversation_type.py +++ b/google/ads/googleads/v23/enums/types/local_services_conversation_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesLeadConversationTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_employee_status.py b/google/ads/googleads/v23/enums/types/local_services_employee_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/local_services_employee_status.py rename to google/ads/googleads/v23/enums/types/local_services_employee_status.py index 60c03d235..bc924ac88 100644 --- a/google/ads/googleads/v19/enums/types/local_services_employee_status.py +++ b/google/ads/googleads/v23/enums/types/local_services_employee_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesEmployeeStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_employee_type.py b/google/ads/googleads/v23/enums/types/local_services_employee_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/local_services_employee_type.py rename to google/ads/googleads/v23/enums/types/local_services_employee_type.py index 11eb0775b..5383f5e62 100644 --- a/google/ads/googleads/v19/enums/types/local_services_employee_type.py +++ b/google/ads/googleads/v23/enums/types/local_services_employee_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesEmployeeTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_insurance_rejection_reason.py b/google/ads/googleads/v23/enums/types/local_services_insurance_rejection_reason.py similarity index 97% rename from google/ads/googleads/v19/enums/types/local_services_insurance_rejection_reason.py rename to google/ads/googleads/v23/enums/types/local_services_insurance_rejection_reason.py index a29850c28..6029d7394 100644 --- a/google/ads/googleads/v19/enums/types/local_services_insurance_rejection_reason.py +++ b/google/ads/googleads/v23/enums/types/local_services_insurance_rejection_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesInsuranceRejectionReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_lead_credit_issuance_decision.py b/google/ads/googleads/v23/enums/types/local_services_lead_credit_issuance_decision.py similarity index 96% rename from google/ads/googleads/v19/enums/types/local_services_lead_credit_issuance_decision.py rename to google/ads/googleads/v23/enums/types/local_services_lead_credit_issuance_decision.py index 3a535df55..931c0a6de 100644 --- a/google/ads/googleads/v19/enums/types/local_services_lead_credit_issuance_decision.py +++ b/google/ads/googleads/v23/enums/types/local_services_lead_credit_issuance_decision.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesLeadCreditIssuanceDecisionEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_lead_credit_state.py b/google/ads/googleads/v23/enums/types/local_services_lead_credit_state.py similarity index 94% rename from google/ads/googleads/v19/enums/types/local_services_lead_credit_state.py rename to google/ads/googleads/v23/enums/types/local_services_lead_credit_state.py index e854f0012..f1a87fb40 100644 --- a/google/ads/googleads/v19/enums/types/local_services_lead_credit_state.py +++ b/google/ads/googleads/v23/enums/types/local_services_lead_credit_state.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesCreditStateEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_lead_status.py b/google/ads/googleads/v23/enums/types/local_services_lead_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/local_services_lead_status.py rename to google/ads/googleads/v23/enums/types/local_services_lead_status.py index 6d3563f1e..6e063c6f1 100644 --- a/google/ads/googleads/v19/enums/types/local_services_lead_status.py +++ b/google/ads/googleads/v23/enums/types/local_services_lead_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesLeadStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_lead_survey_answer.py b/google/ads/googleads/v23/enums/types/local_services_lead_survey_answer.py similarity index 95% rename from google/ads/googleads/v19/enums/types/local_services_lead_survey_answer.py rename to google/ads/googleads/v23/enums/types/local_services_lead_survey_answer.py index 6cb73f0fe..ef57b74c6 100644 --- a/google/ads/googleads/v19/enums/types/local_services_lead_survey_answer.py +++ b/google/ads/googleads/v23/enums/types/local_services_lead_survey_answer.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesLeadSurveyAnswerEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_lead_survey_dissatisfied_reason.py b/google/ads/googleads/v23/enums/types/local_services_lead_survey_dissatisfied_reason.py similarity index 96% rename from google/ads/googleads/v19/enums/types/local_services_lead_survey_dissatisfied_reason.py rename to google/ads/googleads/v23/enums/types/local_services_lead_survey_dissatisfied_reason.py index a9493ad0f..60cbe74c1 100644 --- a/google/ads/googleads/v19/enums/types/local_services_lead_survey_dissatisfied_reason.py +++ b/google/ads/googleads/v23/enums/types/local_services_lead_survey_dissatisfied_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesLeadSurveyDissatisfiedReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_lead_survey_satisfied_reason.py b/google/ads/googleads/v23/enums/types/local_services_lead_survey_satisfied_reason.py similarity index 96% rename from google/ads/googleads/v19/enums/types/local_services_lead_survey_satisfied_reason.py rename to google/ads/googleads/v23/enums/types/local_services_lead_survey_satisfied_reason.py index 8ce711622..ad5ec5797 100644 --- a/google/ads/googleads/v19/enums/types/local_services_lead_survey_satisfied_reason.py +++ b/google/ads/googleads/v23/enums/types/local_services_lead_survey_satisfied_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesLeadSurveySatisfiedReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_lead_type.py b/google/ads/googleads/v23/enums/types/local_services_lead_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/local_services_lead_type.py rename to google/ads/googleads/v23/enums/types/local_services_lead_type.py index f4bd3ce3c..b7ec776f0 100644 --- a/google/ads/googleads/v19/enums/types/local_services_lead_type.py +++ b/google/ads/googleads/v23/enums/types/local_services_lead_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesLeadTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_license_rejection_reason.py b/google/ads/googleads/v23/enums/types/local_services_license_rejection_reason.py similarity index 96% rename from google/ads/googleads/v19/enums/types/local_services_license_rejection_reason.py rename to google/ads/googleads/v23/enums/types/local_services_license_rejection_reason.py index 7f6e7b9ee..7d2fb2d9a 100644 --- a/google/ads/googleads/v19/enums/types/local_services_license_rejection_reason.py +++ b/google/ads/googleads/v23/enums/types/local_services_license_rejection_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesLicenseRejectionReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_participant_type.py b/google/ads/googleads/v23/enums/types/local_services_participant_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/local_services_participant_type.py rename to google/ads/googleads/v23/enums/types/local_services_participant_type.py index 4dff39f18..f51725145 100644 --- a/google/ads/googleads/v19/enums/types/local_services_participant_type.py +++ b/google/ads/googleads/v23/enums/types/local_services_participant_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesParticipantTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_verification_artifact_status.py b/google/ads/googleads/v23/enums/types/local_services_verification_artifact_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/local_services_verification_artifact_status.py rename to google/ads/googleads/v23/enums/types/local_services_verification_artifact_status.py index fcae86c03..7738f7084 100644 --- a/google/ads/googleads/v19/enums/types/local_services_verification_artifact_status.py +++ b/google/ads/googleads/v23/enums/types/local_services_verification_artifact_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesVerificationArtifactStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_verification_artifact_type.py b/google/ads/googleads/v23/enums/types/local_services_verification_artifact_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/local_services_verification_artifact_type.py rename to google/ads/googleads/v23/enums/types/local_services_verification_artifact_type.py index 66f5c78d2..94f02f13a 100644 --- a/google/ads/googleads/v19/enums/types/local_services_verification_artifact_type.py +++ b/google/ads/googleads/v23/enums/types/local_services_verification_artifact_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesVerificationArtifactTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/local_services_verification_status.py b/google/ads/googleads/v23/enums/types/local_services_verification_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/local_services_verification_status.py rename to google/ads/googleads/v23/enums/types/local_services_verification_status.py index 0b0040a90..ce2890a7c 100644 --- a/google/ads/googleads/v19/enums/types/local_services_verification_status.py +++ b/google/ads/googleads/v23/enums/types/local_services_verification_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesVerificationStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/location_group_radius_units.py b/google/ads/googleads/v23/enums/types/location_group_radius_units.py similarity index 94% rename from google/ads/googleads/v19/enums/types/location_group_radius_units.py rename to google/ads/googleads/v23/enums/types/location_group_radius_units.py index 4da4c4903..2f6fbbf36 100644 --- a/google/ads/googleads/v19/enums/types/location_group_radius_units.py +++ b/google/ads/googleads/v23/enums/types/location_group_radius_units.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocationGroupRadiusUnitsEnum", }, diff --git a/google/ads/googleads/v19/enums/types/location_ownership_type.py b/google/ads/googleads/v23/enums/types/location_ownership_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/location_ownership_type.py rename to google/ads/googleads/v23/enums/types/location_ownership_type.py index 1aa664a30..a9e42f3ec 100644 --- a/google/ads/googleads/v19/enums/types/location_ownership_type.py +++ b/google/ads/googleads/v23/enums/types/location_ownership_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocationOwnershipTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/location_source_type.py b/google/ads/googleads/v23/enums/types/location_source_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/location_source_type.py rename to google/ads/googleads/v23/enums/types/location_source_type.py index db99f4acb..19d03042d 100644 --- a/google/ads/googleads/v19/enums/types/location_source_type.py +++ b/google/ads/googleads/v23/enums/types/location_source_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocationSourceTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/location_string_filter_type.py b/google/ads/googleads/v23/enums/types/location_string_filter_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/location_string_filter_type.py rename to google/ads/googleads/v23/enums/types/location_string_filter_type.py index 411f99bd9..72b35b8b6 100644 --- a/google/ads/googleads/v19/enums/types/location_string_filter_type.py +++ b/google/ads/googleads/v23/enums/types/location_string_filter_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LocationStringFilterTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/lookalike_expansion_level.py b/google/ads/googleads/v23/enums/types/lookalike_expansion_level.py similarity index 95% rename from google/ads/googleads/v19/enums/types/lookalike_expansion_level.py rename to google/ads/googleads/v23/enums/types/lookalike_expansion_level.py index acc6d03d4..5a8a4ab6d 100644 --- a/google/ads/googleads/v19/enums/types/lookalike_expansion_level.py +++ b/google/ads/googleads/v23/enums/types/lookalike_expansion_level.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "LookalikeExpansionLevelEnum", }, diff --git a/google/ads/googleads/v19/enums/types/manager_link_status.py b/google/ads/googleads/v23/enums/types/manager_link_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/manager_link_status.py rename to google/ads/googleads/v23/enums/types/manager_link_status.py index 553acb13b..30cbc1f2b 100644 --- a/google/ads/googleads/v19/enums/types/manager_link_status.py +++ b/google/ads/googleads/v23/enums/types/manager_link_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ManagerLinkStatusEnum", }, diff --git a/google/ads/googleads/v23/enums/types/match_type.py b/google/ads/googleads/v23/enums/types/match_type.py new file mode 100644 index 000000000..f193d7c38 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/match_type.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "MatchTypeEnum", + }, +) + + +class MatchTypeEnum(proto.Message): + r"""Container for enum describing match types for a keyword + triggering an ad. + + """ + + class MatchType(proto.Enum): + r"""Possible match types for a keyword triggering an ad. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + BROAD (2): + Broad match. + EXACT (3): + Exact match. + PHRASE (4): + Phrase match. + AI_MAX (5): + Match type for AI Max Search. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + BROAD = 2 + EXACT = 3 + PHRASE = 4 + AI_MAX = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/media_type.py b/google/ads/googleads/v23/enums/types/media_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/media_type.py rename to google/ads/googleads/v23/enums/types/media_type.py index da4701d74..90dcf5b93 100644 --- a/google/ads/googleads/v19/enums/types/media_type.py +++ b/google/ads/googleads/v23/enums/types/media_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "MediaTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/mime_type.py b/google/ads/googleads/v23/enums/types/mime_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/mime_type.py rename to google/ads/googleads/v23/enums/types/mime_type.py index 584314770..3fe466f1a 100644 --- a/google/ads/googleads/v19/enums/types/mime_type.py +++ b/google/ads/googleads/v23/enums/types/mime_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "MimeTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/minute_of_hour.py b/google/ads/googleads/v23/enums/types/minute_of_hour.py similarity index 94% rename from google/ads/googleads/v19/enums/types/minute_of_hour.py rename to google/ads/googleads/v23/enums/types/minute_of_hour.py index 6cafd821b..6d0c4e817 100644 --- a/google/ads/googleads/v19/enums/types/minute_of_hour.py +++ b/google/ads/googleads/v23/enums/types/minute_of_hour.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "MinuteOfHourEnum", }, diff --git a/google/ads/googleads/v19/enums/types/mobile_app_vendor.py b/google/ads/googleads/v23/enums/types/mobile_app_vendor.py similarity index 94% rename from google/ads/googleads/v19/enums/types/mobile_app_vendor.py rename to google/ads/googleads/v23/enums/types/mobile_app_vendor.py index d3aac4176..3b02c18d6 100644 --- a/google/ads/googleads/v19/enums/types/mobile_app_vendor.py +++ b/google/ads/googleads/v23/enums/types/mobile_app_vendor.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "MobileAppVendorEnum", }, diff --git a/google/ads/googleads/v19/enums/types/mobile_device_type.py b/google/ads/googleads/v23/enums/types/mobile_device_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/mobile_device_type.py rename to google/ads/googleads/v23/enums/types/mobile_device_type.py index 4c38dc07e..7116e0025 100644 --- a/google/ads/googleads/v19/enums/types/mobile_device_type.py +++ b/google/ads/googleads/v23/enums/types/mobile_device_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "MobileDeviceTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/month_of_year.py b/google/ads/googleads/v23/enums/types/month_of_year.py similarity index 96% rename from google/ads/googleads/v19/enums/types/month_of_year.py rename to google/ads/googleads/v23/enums/types/month_of_year.py index fb5212efe..3edcd9670 100644 --- a/google/ads/googleads/v19/enums/types/month_of_year.py +++ b/google/ads/googleads/v23/enums/types/month_of_year.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "MonthOfYearEnum", }, diff --git a/google/ads/googleads/v19/enums/types/negative_geo_target_type.py b/google/ads/googleads/v23/enums/types/negative_geo_target_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/negative_geo_target_type.py rename to google/ads/googleads/v23/enums/types/negative_geo_target_type.py index 739b67607..ec9eca089 100644 --- a/google/ads/googleads/v19/enums/types/negative_geo_target_type.py +++ b/google/ads/googleads/v23/enums/types/negative_geo_target_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "NegativeGeoTargetTypeEnum", }, diff --git a/google/ads/googleads/v23/enums/types/non_skippable_max_duration.py b/google/ads/googleads/v23/enums/types/non_skippable_max_duration.py new file mode 100644 index 000000000..78153c775 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/non_skippable_max_duration.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "NonSkippableMaxDurationEnum", + }, +) + + +class NonSkippableMaxDurationEnum(proto.Message): + r"""Container for enum describing the allowed maximum duration + values for videos used in non-skippable video responsive ads. + + """ + + class NonSkippableMaxDuration(proto.Enum): + r"""Enum describing the allowed maximum duration values for + videos used in non-skippable video responsive ads. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + MAX_DURATION_FIFTEEN_SECONDS (2): + Indicates that non-skippable ads must be at + most 15 seconds long. + MAX_DURATION_THIRTY_SECONDS (3): + Indicates that non-skippable ads must be at + most 30 seconds long. + MAX_DURATION_SIXTY_SECONDS (4): + Indicates that non-skippable ads must be at + most 60 seconds long. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + MAX_DURATION_FIFTEEN_SECONDS = 2 + MAX_DURATION_THIRTY_SECONDS = 3 + MAX_DURATION_SIXTY_SECONDS = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/enums/types/non_skippable_min_duration.py b/google/ads/googleads/v23/enums/types/non_skippable_min_duration.py new file mode 100644 index 000000000..bc6042ac3 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/non_skippable_min_duration.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "NonSkippableMinDurationEnum", + }, +) + + +class NonSkippableMinDurationEnum(proto.Message): + r"""Container for enum describing the allowed minimum duration + values for videos used in non-skippable video responsive ads. + + """ + + class NonSkippableMinDuration(proto.Enum): + r"""Enum describing the allowed minimum duration values for + videos used in non-skippable video responsive ads. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + MIN_DURATION_FIVE_SECONDS (2): + Indicates that non-skippable ads must be at + least 5 seconds long. + MIN_DURATION_SEVEN_SECONDS (3): + Indicates that non-skippable ads must be at + least 7 seconds long. + MIN_DURATION_SIXTEEN_SECONDS (4): + Indicates that non-skippable ads must be at + least 16 seconds long. + MIN_DURATION_THIRTY_ONE_SECONDS (5): + Indicates that non-skippable ads must be at + least 31 seconds long. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + MIN_DURATION_FIVE_SECONDS = 2 + MIN_DURATION_SEVEN_SECONDS = 3 + MIN_DURATION_SIXTEEN_SECONDS = 4 + MIN_DURATION_THIRTY_ONE_SECONDS = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/offline_conversion_diagnostic_status_enum.py b/google/ads/googleads/v23/enums/types/offline_conversion_diagnostic_status_enum.py similarity index 96% rename from google/ads/googleads/v19/enums/types/offline_conversion_diagnostic_status_enum.py rename to google/ads/googleads/v23/enums/types/offline_conversion_diagnostic_status_enum.py index fdfff0256..3524f0c03 100644 --- a/google/ads/googleads/v19/enums/types/offline_conversion_diagnostic_status_enum.py +++ b/google/ads/googleads/v23/enums/types/offline_conversion_diagnostic_status_enum.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "OfflineConversionDiagnosticStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/offline_event_upload_client_enum.py b/google/ads/googleads/v23/enums/types/offline_event_upload_client_enum.py similarity index 95% rename from google/ads/googleads/v19/enums/types/offline_event_upload_client_enum.py rename to google/ads/googleads/v23/enums/types/offline_event_upload_client_enum.py index 80d413e8b..aa04f24d6 100644 --- a/google/ads/googleads/v19/enums/types/offline_event_upload_client_enum.py +++ b/google/ads/googleads/v23/enums/types/offline_event_upload_client_enum.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "OfflineEventUploadClientEnum", }, diff --git a/google/ads/googleads/v19/enums/types/offline_user_data_job_failure_reason.py b/google/ads/googleads/v23/enums/types/offline_user_data_job_failure_reason.py similarity index 96% rename from google/ads/googleads/v19/enums/types/offline_user_data_job_failure_reason.py rename to google/ads/googleads/v23/enums/types/offline_user_data_job_failure_reason.py index c2899d3f5..87964fe8e 100644 --- a/google/ads/googleads/v19/enums/types/offline_user_data_job_failure_reason.py +++ b/google/ads/googleads/v23/enums/types/offline_user_data_job_failure_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "OfflineUserDataJobFailureReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/offline_user_data_job_match_rate_range.py b/google/ads/googleads/v23/enums/types/offline_user_data_job_match_rate_range.py similarity index 97% rename from google/ads/googleads/v19/enums/types/offline_user_data_job_match_rate_range.py rename to google/ads/googleads/v23/enums/types/offline_user_data_job_match_rate_range.py index 6dfe70cf4..14b1a238b 100644 --- a/google/ads/googleads/v19/enums/types/offline_user_data_job_match_rate_range.py +++ b/google/ads/googleads/v23/enums/types/offline_user_data_job_match_rate_range.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "OfflineUserDataJobMatchRateRangeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/offline_user_data_job_status.py b/google/ads/googleads/v23/enums/types/offline_user_data_job_status.py similarity index 80% rename from google/ads/googleads/v19/enums/types/offline_user_data_job_status.py rename to google/ads/googleads/v23/enums/types/offline_user_data_job_status.py index a31ae4680..6166ed0cc 100644 --- a/google/ads/googleads/v19/enums/types/offline_user_data_job_status.py +++ b/google/ads/googleads/v23/enums/types/offline_user_data_job_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "OfflineUserDataJobStatusEnum", }, @@ -51,9 +51,15 @@ class OfflineUserDataJobStatus(proto.Enum): being processed. SUCCESS (4): Uploaded data has been successfully - processed. + processed. The job might have no operations, + which can happen if the job was run without any + operations added, or if all operations failed + validation individually when attempting to add + them to the job. FAILED (5): Uploaded data has failed to be processed. + Some operations may have been successfully + processed. """ UNSPECIFIED = 0 diff --git a/google/ads/googleads/v19/enums/types/offline_user_data_job_type.py b/google/ads/googleads/v23/enums/types/offline_user_data_job_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/offline_user_data_job_type.py rename to google/ads/googleads/v23/enums/types/offline_user_data_job_type.py index 901fe863e..256ec2a63 100644 --- a/google/ads/googleads/v19/enums/types/offline_user_data_job_type.py +++ b/google/ads/googleads/v23/enums/types/offline_user_data_job_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "OfflineUserDataJobTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/operating_system_version_operator_type.py b/google/ads/googleads/v23/enums/types/operating_system_version_operator_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/operating_system_version_operator_type.py rename to google/ads/googleads/v23/enums/types/operating_system_version_operator_type.py index 9978d7adb..afac42c4e 100644 --- a/google/ads/googleads/v19/enums/types/operating_system_version_operator_type.py +++ b/google/ads/googleads/v23/enums/types/operating_system_version_operator_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "OperatingSystemVersionOperatorTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/optimization_goal_type.py b/google/ads/googleads/v23/enums/types/optimization_goal_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/optimization_goal_type.py rename to google/ads/googleads/v23/enums/types/optimization_goal_type.py index c4dabf242..a28fb575e 100644 --- a/google/ads/googleads/v19/enums/types/optimization_goal_type.py +++ b/google/ads/googleads/v23/enums/types/optimization_goal_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "OptimizationGoalTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/parental_status_type.py b/google/ads/googleads/v23/enums/types/parental_status_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/parental_status_type.py rename to google/ads/googleads/v23/enums/types/parental_status_type.py index 896289e5a..91d10a4af 100644 --- a/google/ads/googleads/v19/enums/types/parental_status_type.py +++ b/google/ads/googleads/v23/enums/types/parental_status_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ParentalStatusTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/payment_mode.py b/google/ads/googleads/v23/enums/types/payment_mode.py similarity index 96% rename from google/ads/googleads/v19/enums/types/payment_mode.py rename to google/ads/googleads/v23/enums/types/payment_mode.py index 9f5b13b69..58fa27ea4 100644 --- a/google/ads/googleads/v19/enums/types/payment_mode.py +++ b/google/ads/googleads/v23/enums/types/payment_mode.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PaymentModeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/performance_max_upgrade_status.py b/google/ads/googleads/v23/enums/types/performance_max_upgrade_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/performance_max_upgrade_status.py rename to google/ads/googleads/v23/enums/types/performance_max_upgrade_status.py index d2d332eef..484390627 100644 --- a/google/ads/googleads/v19/enums/types/performance_max_upgrade_status.py +++ b/google/ads/googleads/v23/enums/types/performance_max_upgrade_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PerformanceMaxUpgradeStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/placement_type.py b/google/ads/googleads/v23/enums/types/placement_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/placement_type.py rename to google/ads/googleads/v23/enums/types/placement_type.py index 2c9e27d0b..7385c8f5e 100644 --- a/google/ads/googleads/v19/enums/types/placement_type.py +++ b/google/ads/googleads/v23/enums/types/placement_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PlacementTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/policy_approval_status.py b/google/ads/googleads/v23/enums/types/policy_approval_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/policy_approval_status.py rename to google/ads/googleads/v23/enums/types/policy_approval_status.py index caddf9534..1521e3359 100644 --- a/google/ads/googleads/v19/enums/types/policy_approval_status.py +++ b/google/ads/googleads/v23/enums/types/policy_approval_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PolicyApprovalStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/policy_review_status.py b/google/ads/googleads/v23/enums/types/policy_review_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/policy_review_status.py rename to google/ads/googleads/v23/enums/types/policy_review_status.py index 5a13c588e..3fd4d74eb 100644 --- a/google/ads/googleads/v19/enums/types/policy_review_status.py +++ b/google/ads/googleads/v23/enums/types/policy_review_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PolicyReviewStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/policy_topic_entry_type.py b/google/ads/googleads/v23/enums/types/policy_topic_entry_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/policy_topic_entry_type.py rename to google/ads/googleads/v23/enums/types/policy_topic_entry_type.py index d9e0cb33c..c7c427c7f 100644 --- a/google/ads/googleads/v19/enums/types/policy_topic_entry_type.py +++ b/google/ads/googleads/v23/enums/types/policy_topic_entry_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PolicyTopicEntryTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/policy_topic_evidence_destination_mismatch_url_type.py b/google/ads/googleads/v23/enums/types/policy_topic_evidence_destination_mismatch_url_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/policy_topic_evidence_destination_mismatch_url_type.py rename to google/ads/googleads/v23/enums/types/policy_topic_evidence_destination_mismatch_url_type.py index 47f50126c..b55f7e9b2 100644 --- a/google/ads/googleads/v19/enums/types/policy_topic_evidence_destination_mismatch_url_type.py +++ b/google/ads/googleads/v23/enums/types/policy_topic_evidence_destination_mismatch_url_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PolicyTopicEvidenceDestinationMismatchUrlTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/policy_topic_evidence_destination_not_working_device.py b/google/ads/googleads/v23/enums/types/policy_topic_evidence_destination_not_working_device.py similarity index 95% rename from google/ads/googleads/v19/enums/types/policy_topic_evidence_destination_not_working_device.py rename to google/ads/googleads/v23/enums/types/policy_topic_evidence_destination_not_working_device.py index 85337ac48..7177777e5 100644 --- a/google/ads/googleads/v19/enums/types/policy_topic_evidence_destination_not_working_device.py +++ b/google/ads/googleads/v23/enums/types/policy_topic_evidence_destination_not_working_device.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PolicyTopicEvidenceDestinationNotWorkingDeviceEnum", }, diff --git a/google/ads/googleads/v19/enums/types/policy_topic_evidence_destination_not_working_dns_error_type.py b/google/ads/googleads/v23/enums/types/policy_topic_evidence_destination_not_working_dns_error_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/policy_topic_evidence_destination_not_working_dns_error_type.py rename to google/ads/googleads/v23/enums/types/policy_topic_evidence_destination_not_working_dns_error_type.py index b0875ba4f..e3112e3ca 100644 --- a/google/ads/googleads/v19/enums/types/policy_topic_evidence_destination_not_working_dns_error_type.py +++ b/google/ads/googleads/v23/enums/types/policy_topic_evidence_destination_not_working_dns_error_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PolicyTopicEvidenceDestinationNotWorkingDnsErrorTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/positive_geo_target_type.py b/google/ads/googleads/v23/enums/types/positive_geo_target_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/positive_geo_target_type.py rename to google/ads/googleads/v23/enums/types/positive_geo_target_type.py index ea69d7abd..33c0b056f 100644 --- a/google/ads/googleads/v19/enums/types/positive_geo_target_type.py +++ b/google/ads/googleads/v23/enums/types/positive_geo_target_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PositiveGeoTargetTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/price_extension_price_qualifier.py b/google/ads/googleads/v23/enums/types/price_extension_price_qualifier.py similarity index 94% rename from google/ads/googleads/v19/enums/types/price_extension_price_qualifier.py rename to google/ads/googleads/v23/enums/types/price_extension_price_qualifier.py index 89fc4af23..3c83c55c9 100644 --- a/google/ads/googleads/v19/enums/types/price_extension_price_qualifier.py +++ b/google/ads/googleads/v23/enums/types/price_extension_price_qualifier.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PriceExtensionPriceQualifierEnum", }, diff --git a/google/ads/googleads/v19/enums/types/price_extension_price_unit.py b/google/ads/googleads/v23/enums/types/price_extension_price_unit.py similarity index 95% rename from google/ads/googleads/v19/enums/types/price_extension_price_unit.py rename to google/ads/googleads/v23/enums/types/price_extension_price_unit.py index bf8c1ae50..9c5771a65 100644 --- a/google/ads/googleads/v19/enums/types/price_extension_price_unit.py +++ b/google/ads/googleads/v23/enums/types/price_extension_price_unit.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PriceExtensionPriceUnitEnum", }, diff --git a/google/ads/googleads/v19/enums/types/price_extension_type.py b/google/ads/googleads/v23/enums/types/price_extension_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/price_extension_type.py rename to google/ads/googleads/v23/enums/types/price_extension_type.py index a71cd8134..bb183a577 100644 --- a/google/ads/googleads/v19/enums/types/price_extension_type.py +++ b/google/ads/googleads/v23/enums/types/price_extension_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PriceExtensionTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/product_availability.py b/google/ads/googleads/v23/enums/types/product_availability.py similarity index 94% rename from google/ads/googleads/v19/enums/types/product_availability.py rename to google/ads/googleads/v23/enums/types/product_availability.py index 83019feb2..b0ad658f1 100644 --- a/google/ads/googleads/v19/enums/types/product_availability.py +++ b/google/ads/googleads/v23/enums/types/product_availability.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProductAvailabilityEnum", }, diff --git a/google/ads/googleads/v19/enums/types/product_category_level.py b/google/ads/googleads/v23/enums/types/product_category_level.py similarity index 94% rename from google/ads/googleads/v19/enums/types/product_category_level.py rename to google/ads/googleads/v23/enums/types/product_category_level.py index ccb6f58b6..866dfc5b3 100644 --- a/google/ads/googleads/v19/enums/types/product_category_level.py +++ b/google/ads/googleads/v23/enums/types/product_category_level.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProductCategoryLevelEnum", }, diff --git a/google/ads/googleads/v19/enums/types/product_category_state.py b/google/ads/googleads/v23/enums/types/product_category_state.py similarity index 94% rename from google/ads/googleads/v19/enums/types/product_category_state.py rename to google/ads/googleads/v23/enums/types/product_category_state.py index d3e036aa9..267836beb 100644 --- a/google/ads/googleads/v19/enums/types/product_category_state.py +++ b/google/ads/googleads/v23/enums/types/product_category_state.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProductCategoryStateEnum", }, diff --git a/google/ads/googleads/v19/enums/types/product_channel.py b/google/ads/googleads/v23/enums/types/product_channel.py similarity index 94% rename from google/ads/googleads/v19/enums/types/product_channel.py rename to google/ads/googleads/v23/enums/types/product_channel.py index 68329212b..81c02fc56 100644 --- a/google/ads/googleads/v19/enums/types/product_channel.py +++ b/google/ads/googleads/v23/enums/types/product_channel.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProductChannelEnum", }, diff --git a/google/ads/googleads/v19/enums/types/product_channel_exclusivity.py b/google/ads/googleads/v23/enums/types/product_channel_exclusivity.py similarity index 95% rename from google/ads/googleads/v19/enums/types/product_channel_exclusivity.py rename to google/ads/googleads/v23/enums/types/product_channel_exclusivity.py index 780f6103d..60bcbc134 100644 --- a/google/ads/googleads/v19/enums/types/product_channel_exclusivity.py +++ b/google/ads/googleads/v23/enums/types/product_channel_exclusivity.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProductChannelExclusivityEnum", }, diff --git a/google/ads/googleads/v19/enums/types/product_condition.py b/google/ads/googleads/v23/enums/types/product_condition.py similarity index 94% rename from google/ads/googleads/v19/enums/types/product_condition.py rename to google/ads/googleads/v23/enums/types/product_condition.py index a90aab9f2..31acce7e5 100644 --- a/google/ads/googleads/v19/enums/types/product_condition.py +++ b/google/ads/googleads/v23/enums/types/product_condition.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProductConditionEnum", }, diff --git a/google/ads/googleads/v19/enums/types/product_custom_attribute_index.py b/google/ads/googleads/v23/enums/types/product_custom_attribute_index.py similarity index 95% rename from google/ads/googleads/v19/enums/types/product_custom_attribute_index.py rename to google/ads/googleads/v23/enums/types/product_custom_attribute_index.py index 7d454ff31..45ffbe20d 100644 --- a/google/ads/googleads/v19/enums/types/product_custom_attribute_index.py +++ b/google/ads/googleads/v23/enums/types/product_custom_attribute_index.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProductCustomAttributeIndexEnum", }, diff --git a/google/ads/googleads/v19/enums/types/product_issue_severity.py b/google/ads/googleads/v23/enums/types/product_issue_severity.py similarity index 94% rename from google/ads/googleads/v19/enums/types/product_issue_severity.py rename to google/ads/googleads/v23/enums/types/product_issue_severity.py index 4a7caa730..da8ff7e84 100644 --- a/google/ads/googleads/v19/enums/types/product_issue_severity.py +++ b/google/ads/googleads/v23/enums/types/product_issue_severity.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProductIssueSeverityEnum", }, diff --git a/google/ads/googleads/v19/enums/types/product_link_invitation_status.py b/google/ads/googleads/v23/enums/types/product_link_invitation_status.py similarity index 96% rename from google/ads/googleads/v19/enums/types/product_link_invitation_status.py rename to google/ads/googleads/v23/enums/types/product_link_invitation_status.py index 04f5687fe..bbf9c2400 100644 --- a/google/ads/googleads/v19/enums/types/product_link_invitation_status.py +++ b/google/ads/googleads/v23/enums/types/product_link_invitation_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProductLinkInvitationStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/product_status.py b/google/ads/googleads/v23/enums/types/product_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/product_status.py rename to google/ads/googleads/v23/enums/types/product_status.py index 2ca992aed..0b74daa87 100644 --- a/google/ads/googleads/v19/enums/types/product_status.py +++ b/google/ads/googleads/v23/enums/types/product_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProductStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/product_type_level.py b/google/ads/googleads/v23/enums/types/product_type_level.py similarity index 94% rename from google/ads/googleads/v19/enums/types/product_type_level.py rename to google/ads/googleads/v23/enums/types/product_type_level.py index 23d55a205..0456ae8bf 100644 --- a/google/ads/googleads/v19/enums/types/product_type_level.py +++ b/google/ads/googleads/v23/enums/types/product_type_level.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProductTypeLevelEnum", }, diff --git a/google/ads/googleads/v23/enums/types/promotion_barcode_type.py b/google/ads/googleads/v23/enums/types/promotion_barcode_type.py new file mode 100644 index 000000000..d30f375f6 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/promotion_barcode_type.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "PromotionBarcodeTypeEnum", + }, +) + + +class PromotionBarcodeTypeEnum(proto.Message): + r"""Container for enum describing a promotion barcode type.""" + + class PromotionBarcodeType(proto.Enum): + r"""A promotion barcode type. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + AZTEC (2): + Aztec 2D barcode format. + Max 350 characters and no links + CODABAR (3): + CODABAR 1D format. + Max 12 characters and no links. Supported + characters include 0123456789-$:/.+ and optional + start and end guards from ABCD. + CODE39 (4): + Code 39 1D format. Max 8 characters and no links. Supported + characters include 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. + \*$/+%. + CODE128 (5): + Code 128 1D format. + Max 18 ASCII characters only and no links + DATA_MATRIX (6): + Data Matrix 2D barcode format. + Max 525 ISO-8859-1 characters only and no links + EAN8 (7): + EAN-8 1D format. + The barcode value should be 7 digits (the check + digit will be computed automatically) or 8 + digits (if you are providing your own check + digit). + EAN13 (8): + EAN-13 1D format. + The barcode value should be 12 digits (the check + digit will be computed automatically) or 13 + digits (if you are providing your own check + digit). + ITF (9): + ITF (Interleaved Two of Five) 1D format. + Must be 14 digits long + PDF417 (10): + PDF417 format. + Max 140 characters and no links + UPC_A (11): + UPC-A 1D format. + The barcode value should be 11 digits (the check + digit will be computed automatically) or 12 + digits (if you are providing your own check + digit). + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + AZTEC = 2 + CODABAR = 3 + CODE39 = 4 + CODE128 = 5 + DATA_MATRIX = 6 + EAN8 = 7 + EAN13 = 8 + ITF = 9 + PDF417 = 10 + UPC_A = 11 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/promotion_extension_discount_modifier.py b/google/ads/googleads/v23/enums/types/promotion_extension_discount_modifier.py similarity index 94% rename from google/ads/googleads/v19/enums/types/promotion_extension_discount_modifier.py rename to google/ads/googleads/v23/enums/types/promotion_extension_discount_modifier.py index 08dc480c1..8102c207b 100644 --- a/google/ads/googleads/v19/enums/types/promotion_extension_discount_modifier.py +++ b/google/ads/googleads/v23/enums/types/promotion_extension_discount_modifier.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PromotionExtensionDiscountModifierEnum", }, diff --git a/google/ads/googleads/v19/enums/types/promotion_extension_occasion.py b/google/ads/googleads/v23/enums/types/promotion_extension_occasion.py similarity index 98% rename from google/ads/googleads/v19/enums/types/promotion_extension_occasion.py rename to google/ads/googleads/v23/enums/types/promotion_extension_occasion.py index 06a7b4c09..97355f0f0 100644 --- a/google/ads/googleads/v19/enums/types/promotion_extension_occasion.py +++ b/google/ads/googleads/v23/enums/types/promotion_extension_occasion.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "PromotionExtensionOccasionEnum", }, diff --git a/google/ads/googleads/v19/enums/types/proximity_radius_units.py b/google/ads/googleads/v23/enums/types/proximity_radius_units.py similarity index 94% rename from google/ads/googleads/v19/enums/types/proximity_radius_units.py rename to google/ads/googleads/v23/enums/types/proximity_radius_units.py index f4e89f49f..55f10eda7 100644 --- a/google/ads/googleads/v19/enums/types/proximity_radius_units.py +++ b/google/ads/googleads/v23/enums/types/proximity_radius_units.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ProximityRadiusUnitsEnum", }, diff --git a/google/ads/googleads/v19/enums/types/quality_score_bucket.py b/google/ads/googleads/v23/enums/types/quality_score_bucket.py similarity index 94% rename from google/ads/googleads/v19/enums/types/quality_score_bucket.py rename to google/ads/googleads/v23/enums/types/quality_score_bucket.py index 79a444d03..95d065daa 100644 --- a/google/ads/googleads/v19/enums/types/quality_score_bucket.py +++ b/google/ads/googleads/v23/enums/types/quality_score_bucket.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "QualityScoreBucketEnum", }, diff --git a/google/ads/googleads/v19/enums/types/reach_plan_age_range.py b/google/ads/googleads/v23/enums/types/reach_plan_age_range.py similarity index 97% rename from google/ads/googleads/v19/enums/types/reach_plan_age_range.py rename to google/ads/googleads/v23/enums/types/reach_plan_age_range.py index 8358cbc65..d0510b8aa 100644 --- a/google/ads/googleads/v19/enums/types/reach_plan_age_range.py +++ b/google/ads/googleads/v23/enums/types/reach_plan_age_range.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ReachPlanAgeRangeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/reach_plan_conversion_rate_model.py b/google/ads/googleads/v23/enums/types/reach_plan_conversion_rate_model.py similarity index 96% rename from google/ads/googleads/v19/enums/types/reach_plan_conversion_rate_model.py rename to google/ads/googleads/v23/enums/types/reach_plan_conversion_rate_model.py index caa101b3f..6608dfe8b 100644 --- a/google/ads/googleads/v19/enums/types/reach_plan_conversion_rate_model.py +++ b/google/ads/googleads/v23/enums/types/reach_plan_conversion_rate_model.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ReachPlanConversionRateModelEnum", }, diff --git a/google/ads/googleads/v19/enums/types/reach_plan_network.py b/google/ads/googleads/v23/enums/types/reach_plan_network.py similarity index 95% rename from google/ads/googleads/v19/enums/types/reach_plan_network.py rename to google/ads/googleads/v23/enums/types/reach_plan_network.py index ca197fecd..e790b0ee9 100644 --- a/google/ads/googleads/v19/enums/types/reach_plan_network.py +++ b/google/ads/googleads/v23/enums/types/reach_plan_network.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ReachPlanNetworkEnum", }, diff --git a/google/ads/googleads/v23/enums/types/reach_plan_plannable_user_list_status.py b/google/ads/googleads/v23/enums/types/reach_plan_plannable_user_list_status.py new file mode 100644 index 000000000..2675d33be --- /dev/null +++ b/google/ads/googleads/v23/enums/types/reach_plan_plannable_user_list_status.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "ReachPlanPlannableUserListStatusEnum", + }, +) + + +class ReachPlanPlannableUserListStatusEnum(proto.Message): + r"""Container for enum describing the plannable status of a user + list. + + """ + + class ReachPlanPlannableUserListStatus(proto.Enum): + r"""The plannable user list status. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + PLANNABLE (2): + The user list is plannable. + UNPLANNABLE (3): + The user list is not plannable. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + PLANNABLE = 2 + UNPLANNABLE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/reach_plan_surface.py b/google/ads/googleads/v23/enums/types/reach_plan_surface.py similarity index 95% rename from google/ads/googleads/v19/enums/types/reach_plan_surface.py rename to google/ads/googleads/v23/enums/types/reach_plan_surface.py index e9957eba3..1ae940e80 100644 --- a/google/ads/googleads/v19/enums/types/reach_plan_surface.py +++ b/google/ads/googleads/v23/enums/types/reach_plan_surface.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ReachPlanSurfaceEnum", }, diff --git a/google/ads/googleads/v19/enums/types/recommendation_subscription_status.py b/google/ads/googleads/v23/enums/types/recommendation_subscription_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/recommendation_subscription_status.py rename to google/ads/googleads/v23/enums/types/recommendation_subscription_status.py index 67f4b50b5..399893f85 100644 --- a/google/ads/googleads/v19/enums/types/recommendation_subscription_status.py +++ b/google/ads/googleads/v23/enums/types/recommendation_subscription_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "RecommendationSubscriptionStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/recommendation_type.py b/google/ads/googleads/v23/enums/types/recommendation_type.py similarity index 99% rename from google/ads/googleads/v19/enums/types/recommendation_type.py rename to google/ads/googleads/v23/enums/types/recommendation_type.py index c465a92a4..62ccf2530 100644 --- a/google/ads/googleads/v19/enums/types/recommendation_type.py +++ b/google/ads/googleads/v23/enums/types/recommendation_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "RecommendationTypeEnum", }, diff --git a/google/ads/googleads/v23/enums/types/regulatory_fee_type.py b/google/ads/googleads/v23/enums/types/regulatory_fee_type.py new file mode 100644 index 000000000..2ac12f10d --- /dev/null +++ b/google/ads/googleads/v23/enums/types/regulatory_fee_type.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "RegulatoryFeeTypeEnum", + }, +) + + +class RegulatoryFeeTypeEnum(proto.Message): + r"""Container for enum describing the type of regulatory fees.""" + + class RegulatoryFeeType(proto.Enum): + r"""The possible type of regulatory fees. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + AUSTRIA_DST_FEE (2): + Represents Austria DST fee. + TURKIYE_REGULATORY_OPERATING_COST (3): + Represents Türkiye regulatory operating cost. + UK_DST_FEE (4): + Represents UK DST fee. + SPAIN_REGULATORY_OPERATING_COST (5): + Represents Spain regulatory operating cost. + FRANCE_REGULATORY_OPERATING_COST (6): + Represents France regulatory operating cost. + ITALY_REGULATORY_OPERATING_COST (7): + Represents Italy regulatory operating cost. + INDIA_REGULATORY_OPERATING_COST (8): + Represents India regulatory operating cost. + POLAND_REGULATORY_OPERATING_COST (9): + Represents Poland regulatory operating cost. + OPERATING_CHARGES (10): + Represents operating charges. + CANADA_DST_FEE (11): + Represents Canada DST fee. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + AUSTRIA_DST_FEE = 2 + TURKIYE_REGULATORY_OPERATING_COST = 3 + UK_DST_FEE = 4 + SPAIN_REGULATORY_OPERATING_COST = 5 + FRANCE_REGULATORY_OPERATING_COST = 6 + ITALY_REGULATORY_OPERATING_COST = 7 + INDIA_REGULATORY_OPERATING_COST = 8 + POLAND_REGULATORY_OPERATING_COST = 9 + OPERATING_CHARGES = 10 + CANADA_DST_FEE = 11 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/resource_change_operation.py b/google/ads/googleads/v23/enums/types/resource_change_operation.py similarity index 95% rename from google/ads/googleads/v19/enums/types/resource_change_operation.py rename to google/ads/googleads/v23/enums/types/resource_change_operation.py index 0ea3c5856..a997f8f2a 100644 --- a/google/ads/googleads/v19/enums/types/resource_change_operation.py +++ b/google/ads/googleads/v23/enums/types/resource_change_operation.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ResourceChangeOperationEnum", }, diff --git a/google/ads/googleads/v19/enums/types/resource_limit_type.py b/google/ads/googleads/v23/enums/types/resource_limit_type.py similarity index 99% rename from google/ads/googleads/v19/enums/types/resource_limit_type.py rename to google/ads/googleads/v23/enums/types/resource_limit_type.py index 26f719468..b4ef2e7a2 100644 --- a/google/ads/googleads/v19/enums/types/resource_limit_type.py +++ b/google/ads/googleads/v23/enums/types/resource_limit_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ResourceLimitTypeEnum", }, @@ -473,6 +473,9 @@ class ResourceLimitType(proto.Enum): WHATSAPP_BUSINESS_MESSAGE_ASSET_LINKS_PER_AD_GROUP (190): Maximum number of active WhatsApp business message asset links at ad group level. + BRAND_LIST_CRITERIA_PER_AD_GROUP (193): + Number of ENABLED brand list criteria per ad + group. """ UNSPECIFIED = 0 @@ -623,6 +626,7 @@ class ResourceLimitType(proto.Enum): BUSINESS_MESSAGE_ASSET_LINKS_PER_CUSTOMER = 188 WHATSAPP_BUSINESS_MESSAGE_ASSET_LINKS_PER_CAMPAIGN = 189 WHATSAPP_BUSINESS_MESSAGE_ASSET_LINKS_PER_AD_GROUP = 190 + BRAND_LIST_CRITERIA_PER_AD_GROUP = 193 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/response_content_type.py b/google/ads/googleads/v23/enums/types/response_content_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/response_content_type.py rename to google/ads/googleads/v23/enums/types/response_content_type.py index e15eb333b..a412cbcc8 100644 --- a/google/ads/googleads/v19/enums/types/response_content_type.py +++ b/google/ads/googleads/v23/enums/types/response_content_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ResponseContentTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/search_engine_results_page_type.py b/google/ads/googleads/v23/enums/types/search_engine_results_page_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/search_engine_results_page_type.py rename to google/ads/googleads/v23/enums/types/search_engine_results_page_type.py index 9b04f60e3..8586f1f2d 100644 --- a/google/ads/googleads/v19/enums/types/search_engine_results_page_type.py +++ b/google/ads/googleads/v23/enums/types/search_engine_results_page_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SearchEngineResultsPageTypeEnum", }, diff --git a/google/ads/googleads/v23/enums/types/search_term_match_source.py b/google/ads/googleads/v23/enums/types/search_term_match_source.py new file mode 100644 index 000000000..70ff710c0 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/search_term_match_source.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "SearchTermMatchSourceEnum", + }, +) + + +class SearchTermMatchSourceEnum(proto.Message): + r"""Container for enum describing the source for search term + matches in the search term report. + + """ + + class SearchTermMatchSource(proto.Enum): + r"""The search term match sources. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + ADVERTISER_PROVIDED_KEYWORD (2): + The match is from a user-provided keyword. + AI_MAX_KEYWORDLESS (3): + The match is from the keywordless expansion + portion of AI Max. + AI_MAX_BROAD_MATCH (4): + The match is from the broad match expansion + portion of AI Max. + DYNAMIC_SEARCH_ADS (5): + The match is from a Dynamic Search Ad. + PERFORMANCE_MAX (6): + The match is from the search term matching + functionality in PMax. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + ADVERTISER_PROVIDED_KEYWORD = 2 + AI_MAX_KEYWORDLESS = 3 + AI_MAX_BROAD_MATCH = 4 + DYNAMIC_SEARCH_ADS = 5 + PERFORMANCE_MAX = 6 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/search_term_match_type.py b/google/ads/googleads/v23/enums/types/search_term_match_type.py similarity index 85% rename from google/ads/googleads/v19/enums/types/search_term_match_type.py rename to google/ads/googleads/v23/enums/types/search_term_match_type.py index 398db7067..e26f6dba3 100644 --- a/google/ads/googleads/v19/enums/types/search_term_match_type.py +++ b/google/ads/googleads/v23/enums/types/search_term_match_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SearchTermMatchTypeEnum", }, @@ -54,6 +54,10 @@ class SearchTermMatchType(proto.Enum): Exact match (close variant). NEAR_PHRASE (6): Phrase match (close variant). + AI_MAX (7): + Match type for AI Max Search. + PERFORMANCE_MAX (8): + Match type for Performance Max campaigns. """ UNSPECIFIED = 0 @@ -63,6 +67,8 @@ class SearchTermMatchType(proto.Enum): PHRASE = 4 NEAR_EXACT = 5 NEAR_PHRASE = 6 + AI_MAX = 7 + PERFORMANCE_MAX = 8 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/search_term_targeting_status.py b/google/ads/googleads/v23/enums/types/search_term_targeting_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/search_term_targeting_status.py rename to google/ads/googleads/v23/enums/types/search_term_targeting_status.py index a811c486f..791f35e82 100644 --- a/google/ads/googleads/v19/enums/types/search_term_targeting_status.py +++ b/google/ads/googleads/v23/enums/types/search_term_targeting_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SearchTermTargetingStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/seasonality_event_scope.py b/google/ads/googleads/v23/enums/types/seasonality_event_scope.py similarity index 95% rename from google/ads/googleads/v19/enums/types/seasonality_event_scope.py rename to google/ads/googleads/v23/enums/types/seasonality_event_scope.py index b76a04159..7401c1665 100644 --- a/google/ads/googleads/v19/enums/types/seasonality_event_scope.py +++ b/google/ads/googleads/v23/enums/types/seasonality_event_scope.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SeasonalityEventScopeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/seasonality_event_status.py b/google/ads/googleads/v23/enums/types/seasonality_event_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/seasonality_event_status.py rename to google/ads/googleads/v23/enums/types/seasonality_event_status.py index 83f556b9a..c98587ce6 100644 --- a/google/ads/googleads/v19/enums/types/seasonality_event_status.py +++ b/google/ads/googleads/v23/enums/types/seasonality_event_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SeasonalityEventStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/served_asset_field_type.py b/google/ads/googleads/v23/enums/types/served_asset_field_type.py similarity index 82% rename from google/ads/googleads/v19/enums/types/served_asset_field_type.py rename to google/ads/googleads/v23/enums/types/served_asset_field_type.py index d2921921d..c66d43f9c 100644 --- a/google/ads/googleads/v19/enums/types/served_asset_field_type.py +++ b/google/ads/googleads/v23/enums/types/served_asset_field_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ServedAssetFieldTypeEnum", }, @@ -64,7 +64,7 @@ class ServedAssetFieldType(proto.Enum): DESCRIPTION (10): The asset was used in a description. Use this only if there is only one description in the ad. Otherwise, use the - DESCRIPTION_1 or DESCRIPTION_@ enums + DESCRIPTION_1 or DESCRIPTION\_@ enums DESCRIPTION_IN_PORTRAIT (11): The asset was used as description in portrait image. @@ -112,6 +112,20 @@ class ServedAssetFieldType(proto.Enum): The asset is used as a lead form. BUSINESS_LOGO (31): The asset is used as a business logo. + DESCRIPTION_PREFIX (32): + The asset is used as a description prefix. + HEADLINE_AS_SITELINK_POSITION_ONE (39): + A headline asset used as a sitelink in + position 1. + HEADLINE_AS_SITELINK_POSITION_TWO (40): + A headline asset used as a sitelink in + position 2. + DESCRIPTION_LINE_HEADLINE_AS_SITELINK_POSITION_ONE (41): + A description line asset used as a sitelink + in position 1. + DESCRIPTION_LINE_HEADLINE_AS_SITELINK_POSITION_TWO (42): + A description line asset used as a sitelink + in position 2. """ UNSPECIFIED = 0 @@ -146,6 +160,11 @@ class ServedAssetFieldType(proto.Enum): AD_IMAGE = 29 LEAD_FORM = 30 BUSINESS_LOGO = 31 + DESCRIPTION_PREFIX = 32 + HEADLINE_AS_SITELINK_POSITION_ONE = 39 + HEADLINE_AS_SITELINK_POSITION_TWO = 40 + DESCRIPTION_LINE_HEADLINE_AS_SITELINK_POSITION_ONE = 41 + DESCRIPTION_LINE_HEADLINE_AS_SITELINK_POSITION_TWO = 42 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/shared_set_status.py b/google/ads/googleads/v23/enums/types/shared_set_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/shared_set_status.py rename to google/ads/googleads/v23/enums/types/shared_set_status.py index 55d25b66c..8cbf3b422 100644 --- a/google/ads/googleads/v19/enums/types/shared_set_status.py +++ b/google/ads/googleads/v23/enums/types/shared_set_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SharedSetStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/shared_set_type.py b/google/ads/googleads/v23/enums/types/shared_set_type.py similarity index 77% rename from google/ads/googleads/v19/enums/types/shared_set_type.py rename to google/ads/googleads/v23/enums/types/shared_set_type.py index 548b52e52..b939355cd 100644 --- a/google/ads/googleads/v19/enums/types/shared_set_type.py +++ b/google/ads/googleads/v23/enums/types/shared_set_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SharedSetTypeEnum", }, @@ -52,6 +52,14 @@ class SharedSetType(proto.Enum): BRANDS (5): A set of brands can be included or excluded from targeting. + WEBPAGES (6): + A set of webpages that can be excluded from + targeting. This shared set type is not publicly + available. + VERTICAL_ADS_ITEM_GROUP_RULE_LIST (7): + A set of vertical ads item group rules that + can be included or excluded from targeting in + Vertical Ads (e.g., for hotel ads). """ UNSPECIFIED = 0 @@ -60,6 +68,8 @@ class SharedSetType(proto.Enum): NEGATIVE_PLACEMENTS = 3 ACCOUNT_LEVEL_NEGATIVE_KEYWORDS = 4 BRANDS = 5 + WEBPAGES = 6 + VERTICAL_ADS_ITEM_GROUP_RULE_LIST = 7 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/shopping_add_products_to_campaign_recommendation_enum.py b/google/ads/googleads/v23/enums/types/shopping_add_products_to_campaign_recommendation_enum.py similarity index 96% rename from google/ads/googleads/v19/enums/types/shopping_add_products_to_campaign_recommendation_enum.py rename to google/ads/googleads/v23/enums/types/shopping_add_products_to_campaign_recommendation_enum.py index b7b54ebd3..28b6bd624 100644 --- a/google/ads/googleads/v19/enums/types/shopping_add_products_to_campaign_recommendation_enum.py +++ b/google/ads/googleads/v23/enums/types/shopping_add_products_to_campaign_recommendation_enum.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ShoppingAddProductsToCampaignRecommendationEnum", }, diff --git a/google/ads/googleads/v19/enums/types/simulation_modification_method.py b/google/ads/googleads/v23/enums/types/simulation_modification_method.py similarity index 96% rename from google/ads/googleads/v19/enums/types/simulation_modification_method.py rename to google/ads/googleads/v23/enums/types/simulation_modification_method.py index 8c9ca2fca..f567e412e 100644 --- a/google/ads/googleads/v19/enums/types/simulation_modification_method.py +++ b/google/ads/googleads/v23/enums/types/simulation_modification_method.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SimulationModificationMethodEnum", }, diff --git a/google/ads/googleads/v19/enums/types/simulation_type.py b/google/ads/googleads/v23/enums/types/simulation_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/simulation_type.py rename to google/ads/googleads/v23/enums/types/simulation_type.py index 125711e4a..30c9839a1 100644 --- a/google/ads/googleads/v19/enums/types/simulation_type.py +++ b/google/ads/googleads/v23/enums/types/simulation_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SimulationTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/sk_ad_network_ad_event_type.py b/google/ads/googleads/v23/enums/types/sk_ad_network_ad_event_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/sk_ad_network_ad_event_type.py rename to google/ads/googleads/v23/enums/types/sk_ad_network_ad_event_type.py index 53c3454e3..014f5f958 100644 --- a/google/ads/googleads/v19/enums/types/sk_ad_network_ad_event_type.py +++ b/google/ads/googleads/v23/enums/types/sk_ad_network_ad_event_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SkAdNetworkAdEventTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/sk_ad_network_attribution_credit.py b/google/ads/googleads/v23/enums/types/sk_ad_network_attribution_credit.py similarity index 95% rename from google/ads/googleads/v19/enums/types/sk_ad_network_attribution_credit.py rename to google/ads/googleads/v23/enums/types/sk_ad_network_attribution_credit.py index 14b567b72..9d2292e81 100644 --- a/google/ads/googleads/v19/enums/types/sk_ad_network_attribution_credit.py +++ b/google/ads/googleads/v23/enums/types/sk_ad_network_attribution_credit.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SkAdNetworkAttributionCreditEnum", }, diff --git a/google/ads/googleads/v19/enums/types/sk_ad_network_coarse_conversion_value.py b/google/ads/googleads/v23/enums/types/sk_ad_network_coarse_conversion_value.py similarity index 95% rename from google/ads/googleads/v19/enums/types/sk_ad_network_coarse_conversion_value.py rename to google/ads/googleads/v23/enums/types/sk_ad_network_coarse_conversion_value.py index 6147abb92..f5e93ef2d 100644 --- a/google/ads/googleads/v19/enums/types/sk_ad_network_coarse_conversion_value.py +++ b/google/ads/googleads/v23/enums/types/sk_ad_network_coarse_conversion_value.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SkAdNetworkCoarseConversionValueEnum", }, diff --git a/google/ads/googleads/v19/enums/types/sk_ad_network_source_type.py b/google/ads/googleads/v23/enums/types/sk_ad_network_source_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/sk_ad_network_source_type.py rename to google/ads/googleads/v23/enums/types/sk_ad_network_source_type.py index b595c19fe..1b9f8a838 100644 --- a/google/ads/googleads/v19/enums/types/sk_ad_network_source_type.py +++ b/google/ads/googleads/v23/enums/types/sk_ad_network_source_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SkAdNetworkSourceTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/sk_ad_network_user_type.py b/google/ads/googleads/v23/enums/types/sk_ad_network_user_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/sk_ad_network_user_type.py rename to google/ads/googleads/v23/enums/types/sk_ad_network_user_type.py index cd5198ec0..632f98b50 100644 --- a/google/ads/googleads/v19/enums/types/sk_ad_network_user_type.py +++ b/google/ads/googleads/v23/enums/types/sk_ad_network_user_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SkAdNetworkUserTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/slot.py b/google/ads/googleads/v23/enums/types/slot.py similarity index 95% rename from google/ads/googleads/v19/enums/types/slot.py rename to google/ads/googleads/v23/enums/types/slot.py index 8a8b6a150..1a90e7b7f 100644 --- a/google/ads/googleads/v19/enums/types/slot.py +++ b/google/ads/googleads/v23/enums/types/slot.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SlotEnum", }, diff --git a/google/ads/googleads/v19/enums/types/smart_campaign_not_eligible_reason.py b/google/ads/googleads/v23/enums/types/smart_campaign_not_eligible_reason.py similarity index 96% rename from google/ads/googleads/v19/enums/types/smart_campaign_not_eligible_reason.py rename to google/ads/googleads/v23/enums/types/smart_campaign_not_eligible_reason.py index 4c948250a..ee18c1fd9 100644 --- a/google/ads/googleads/v19/enums/types/smart_campaign_not_eligible_reason.py +++ b/google/ads/googleads/v23/enums/types/smart_campaign_not_eligible_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SmartCampaignNotEligibleReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/smart_campaign_status.py b/google/ads/googleads/v23/enums/types/smart_campaign_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/smart_campaign_status.py rename to google/ads/googleads/v23/enums/types/smart_campaign_status.py index 4907554c4..14b1f853c 100644 --- a/google/ads/googleads/v19/enums/types/smart_campaign_status.py +++ b/google/ads/googleads/v23/enums/types/smart_campaign_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SmartCampaignStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/spending_limit_type.py b/google/ads/googleads/v23/enums/types/spending_limit_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/spending_limit_type.py rename to google/ads/googleads/v23/enums/types/spending_limit_type.py index 91b150c90..865c2e638 100644 --- a/google/ads/googleads/v19/enums/types/spending_limit_type.py +++ b/google/ads/googleads/v23/enums/types/spending_limit_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SpendingLimitTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/summary_row_setting.py b/google/ads/googleads/v23/enums/types/summary_row_setting.py similarity index 95% rename from google/ads/googleads/v19/enums/types/summary_row_setting.py rename to google/ads/googleads/v23/enums/types/summary_row_setting.py index 05f66f8f9..89d332847 100644 --- a/google/ads/googleads/v19/enums/types/summary_row_setting.py +++ b/google/ads/googleads/v23/enums/types/summary_row_setting.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SummaryRowSettingEnum", }, diff --git a/google/ads/googleads/v19/enums/types/system_managed_entity_source.py b/google/ads/googleads/v23/enums/types/system_managed_entity_source.py similarity index 94% rename from google/ads/googleads/v19/enums/types/system_managed_entity_source.py rename to google/ads/googleads/v23/enums/types/system_managed_entity_source.py index a10f607e1..2400db789 100644 --- a/google/ads/googleads/v19/enums/types/system_managed_entity_source.py +++ b/google/ads/googleads/v23/enums/types/system_managed_entity_source.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "SystemManagedResourceSourceEnum", }, diff --git a/google/ads/googleads/v19/enums/types/target_cpa_opt_in_recommendation_goal.py b/google/ads/googleads/v23/enums/types/target_cpa_opt_in_recommendation_goal.py similarity index 95% rename from google/ads/googleads/v19/enums/types/target_cpa_opt_in_recommendation_goal.py rename to google/ads/googleads/v23/enums/types/target_cpa_opt_in_recommendation_goal.py index d90e3fe0e..fa366d896 100644 --- a/google/ads/googleads/v19/enums/types/target_cpa_opt_in_recommendation_goal.py +++ b/google/ads/googleads/v23/enums/types/target_cpa_opt_in_recommendation_goal.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "TargetCpaOptInRecommendationGoalEnum", }, diff --git a/google/ads/googleads/v19/enums/types/target_frequency_time_unit.py b/google/ads/googleads/v23/enums/types/target_frequency_time_unit.py similarity index 94% rename from google/ads/googleads/v19/enums/types/target_frequency_time_unit.py rename to google/ads/googleads/v23/enums/types/target_frequency_time_unit.py index db15dcbbc..dc8a13653 100644 --- a/google/ads/googleads/v19/enums/types/target_frequency_time_unit.py +++ b/google/ads/googleads/v23/enums/types/target_frequency_time_unit.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "TargetFrequencyTimeUnitEnum", }, diff --git a/google/ads/googleads/v19/enums/types/target_impression_share_location.py b/google/ads/googleads/v23/enums/types/target_impression_share_location.py similarity index 95% rename from google/ads/googleads/v19/enums/types/target_impression_share_location.py rename to google/ads/googleads/v23/enums/types/target_impression_share_location.py index fd1cb74ac..3cfac5eb8 100644 --- a/google/ads/googleads/v19/enums/types/target_impression_share_location.py +++ b/google/ads/googleads/v23/enums/types/target_impression_share_location.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "TargetImpressionShareLocationEnum", }, diff --git a/google/ads/googleads/v19/enums/types/targeting_dimension.py b/google/ads/googleads/v23/enums/types/targeting_dimension.py similarity index 96% rename from google/ads/googleads/v19/enums/types/targeting_dimension.py rename to google/ads/googleads/v23/enums/types/targeting_dimension.py index 1620774e3..37d44366f 100644 --- a/google/ads/googleads/v19/enums/types/targeting_dimension.py +++ b/google/ads/googleads/v23/enums/types/targeting_dimension.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "TargetingDimensionEnum", }, diff --git a/google/ads/googleads/v23/enums/types/third_party_brand_lift_integration_partner.py b/google/ads/googleads/v23/enums/types/third_party_brand_lift_integration_partner.py new file mode 100644 index 000000000..c85c3adc7 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/third_party_brand_lift_integration_partner.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "ThirdPartyBrandLiftIntegrationPartnerEnum", + }, +) + + +class ThirdPartyBrandLiftIntegrationPartnerEnum(proto.Message): + r"""Container for enum describing available third party + integration partners for Brand Lift verification. + + """ + + class ThirdPartyBrandLiftIntegrationPartner(proto.Enum): + r"""Enum describing available third party integration partners + for Brand Lift verification. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + KANTAR_MILLWARD_BROWN (2): + Kantar + DYNATA (3): + Dynata + INTAGE (4): + Intage + MACROMILL (5): + Macromill + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + KANTAR_MILLWARD_BROWN = 2 + DYNATA = 3 + INTAGE = 4 + MACROMILL = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/enums/types/third_party_brand_safety_integration_partner.py b/google/ads/googleads/v23/enums/types/third_party_brand_safety_integration_partner.py new file mode 100644 index 000000000..47f4ec6d9 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/third_party_brand_safety_integration_partner.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "ThirdPartyBrandSafetyIntegrationPartnerEnum", + }, +) + + +class ThirdPartyBrandSafetyIntegrationPartnerEnum(proto.Message): + r"""Container for enum describing available third party + integration partners for brand safety verification. + + """ + + class ThirdPartyBrandSafetyIntegrationPartner(proto.Enum): + r"""Enum describing available third party integration partners + for brand safety verification. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + DOUBLE_VERIFY (2): + DoubleVerify. + INTEGRAL_AD_SCIENCE (3): + Integral Ad Science. + ZEFR (4): + Zefr. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + DOUBLE_VERIFY = 2 + INTEGRAL_AD_SCIENCE = 3 + ZEFR = 4 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/enums/types/third_party_reach_integration_partner.py b/google/ads/googleads/v23/enums/types/third_party_reach_integration_partner.py new file mode 100644 index 000000000..018149d11 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/third_party_reach_integration_partner.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "ThirdPartyReachIntegrationPartnerEnum", + }, +) + + +class ThirdPartyReachIntegrationPartnerEnum(proto.Message): + r"""Container for enum describing available third party + integration partners for reach verification. + + """ + + class ThirdPartyReachIntegrationPartner(proto.Enum): + r"""Enum describing available third party integration partners + for reach verification. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + NIELSEN (2): + Nielsen. + COMSCORE (3): + Comscore. + KANTAR_MILLWARD_BROWN (4): + Kantar. + VIDEO_RESEARCH (5): + Video Research. + GEMIUS (6): + Gemius. + MEDIA_SCOPE (7): + MediaScope. + AUDIENCE_PROJECT (8): + AudienceProject + VIDEO_AMP (9): + VideoAmp + ISPOT_TV (10): + iSpot.tv + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + NIELSEN = 2 + COMSCORE = 3 + KANTAR_MILLWARD_BROWN = 4 + VIDEO_RESEARCH = 5 + GEMIUS = 6 + MEDIA_SCOPE = 7 + AUDIENCE_PROJECT = 8 + VIDEO_AMP = 9 + ISPOT_TV = 10 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/enums/types/third_party_viewability_integration_partner.py b/google/ads/googleads/v23/enums/types/third_party_viewability_integration_partner.py new file mode 100644 index 000000000..32bb2bf5f --- /dev/null +++ b/google/ads/googleads/v23/enums/types/third_party_viewability_integration_partner.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "ThirdPartyViewabilityIntegrationPartnerEnum", + }, +) + + +class ThirdPartyViewabilityIntegrationPartnerEnum(proto.Message): + r"""Container for enum describing available third party + integration partners for YouTube viewability verification. + + """ + + class ThirdPartyViewabilityIntegrationPartner(proto.Enum): + r"""Enum describing available third party integration partners + for YouTube viewability verification. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + DOUBLE_VERIFY (2): + DoubleVerify. + INTEGRAL_AD_SCIENCE (3): + Integral Ad Science. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + DOUBLE_VERIFY = 2 + INTEGRAL_AD_SCIENCE = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/time_type.py b/google/ads/googleads/v23/enums/types/time_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/time_type.py rename to google/ads/googleads/v23/enums/types/time_type.py index a003c4bd5..edc0138a3 100644 --- a/google/ads/googleads/v19/enums/types/time_type.py +++ b/google/ads/googleads/v23/enums/types/time_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "TimeTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/tracking_code_page_format.py b/google/ads/googleads/v23/enums/types/tracking_code_page_format.py similarity index 94% rename from google/ads/googleads/v19/enums/types/tracking_code_page_format.py rename to google/ads/googleads/v23/enums/types/tracking_code_page_format.py index 4c3fd1603..2b78a53dd 100644 --- a/google/ads/googleads/v19/enums/types/tracking_code_page_format.py +++ b/google/ads/googleads/v23/enums/types/tracking_code_page_format.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "TrackingCodePageFormatEnum", }, diff --git a/google/ads/googleads/v19/enums/types/tracking_code_type.py b/google/ads/googleads/v23/enums/types/tracking_code_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/tracking_code_type.py rename to google/ads/googleads/v23/enums/types/tracking_code_type.py index 9b97d580a..cce80b4cc 100644 --- a/google/ads/googleads/v19/enums/types/tracking_code_type.py +++ b/google/ads/googleads/v23/enums/types/tracking_code_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "TrackingCodeTypeEnum", }, diff --git a/google/ads/googleads/v23/enums/types/unit_of_measure.py b/google/ads/googleads/v23/enums/types/unit_of_measure.py new file mode 100644 index 000000000..4ba4c2db1 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/unit_of_measure.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "UnitOfMeasureEnum", + }, +) + + +class UnitOfMeasureEnum(proto.Message): + r"""Container for enum describing the type of unit of measure.""" + + class UnitOfMeasure(proto.Enum): + r"""The possible type of unit of measure. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + CLICKS (2): + Clicks as unit of measure. + IMPRESSIONS (3): + Impressions as unit of measure. + ACQUISITIONS (4): + Acquisitions as unit of measure. + PHONE_CALLS (5): + Phone calls as unit of measure. + VIDEO_PLAYS (6): + Video plays as unit of measure. + DAYS (7): + Days as unit of measure. + AUDIO_PLAYS (8): + Audio plays as unit of measure. + ENGAGEMENTS (9): + Engagements as unit of measure. + SECONDS (10): + Seconds as unit of measure. + LEADS (11): + Leads as unit of measure. + GUEST_STAYS (12): + Guest stays as unit of measure. + HOURS (13): + Hours as unit of measure. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + CLICKS = 2 + IMPRESSIONS = 3 + ACQUISITIONS = 4 + PHONE_CALLS = 5 + VIDEO_PLAYS = 6 + DAYS = 7 + AUDIO_PLAYS = 8 + ENGAGEMENTS = 9 + SECONDS = 10 + LEADS = 11 + GUEST_STAYS = 12 + HOURS = 13 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/user_identifier_source.py b/google/ads/googleads/v23/enums/types/user_identifier_source.py similarity index 95% rename from google/ads/googleads/v19/enums/types/user_identifier_source.py rename to google/ads/googleads/v23/enums/types/user_identifier_source.py index 66e7fd49a..c159c7d13 100644 --- a/google/ads/googleads/v19/enums/types/user_identifier_source.py +++ b/google/ads/googleads/v23/enums/types/user_identifier_source.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserIdentifierSourceEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_interest_taxonomy_type.py b/google/ads/googleads/v23/enums/types/user_interest_taxonomy_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/user_interest_taxonomy_type.py rename to google/ads/googleads/v23/enums/types/user_interest_taxonomy_type.py index a636c8407..cd346983a 100644 --- a/google/ads/googleads/v19/enums/types/user_interest_taxonomy_type.py +++ b/google/ads/googleads/v23/enums/types/user_interest_taxonomy_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserInterestTaxonomyTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_access_status.py b/google/ads/googleads/v23/enums/types/user_list_access_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/user_list_access_status.py rename to google/ads/googleads/v23/enums/types/user_list_access_status.py index 5b7f14dd3..56ba4fdd7 100644 --- a/google/ads/googleads/v19/enums/types/user_list_access_status.py +++ b/google/ads/googleads/v23/enums/types/user_list_access_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListAccessStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_closing_reason.py b/google/ads/googleads/v23/enums/types/user_list_closing_reason.py similarity index 94% rename from google/ads/googleads/v19/enums/types/user_list_closing_reason.py rename to google/ads/googleads/v23/enums/types/user_list_closing_reason.py index 51aa56fdd..78a3c6f55 100644 --- a/google/ads/googleads/v19/enums/types/user_list_closing_reason.py +++ b/google/ads/googleads/v23/enums/types/user_list_closing_reason.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListClosingReasonEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_crm_data_source_type.py b/google/ads/googleads/v23/enums/types/user_list_crm_data_source_type.py similarity index 87% rename from google/ads/googleads/v19/enums/types/user_list_crm_data_source_type.py rename to google/ads/googleads/v23/enums/types/user_list_crm_data_source_type.py index cbc6e45fa..ff96c74a5 100644 --- a/google/ads/googleads/v19/enums/types/user_list_crm_data_source_type.py +++ b/google/ads/googleads/v23/enums/types/user_list_crm_data_source_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListCrmDataSourceTypeEnum", }, @@ -48,6 +48,9 @@ class UserListCrmDataSourceType(proto.Enum): THIRD_PARTY_VOTER_FILE (4): The uploaded data is from a third-party voter file. + THIRD_PARTY_PARTNER_DATA (5): + The uploaded data is third party partner + data. """ UNSPECIFIED = 0 @@ -55,6 +58,7 @@ class UserListCrmDataSourceType(proto.Enum): FIRST_PARTY = 2 THIRD_PARTY_CREDIT_BUREAU = 3 THIRD_PARTY_VOTER_FILE = 4 + THIRD_PARTY_PARTNER_DATA = 5 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/user_list_customer_type_category.py b/google/ads/googleads/v23/enums/types/user_list_customer_type_category.py similarity index 97% rename from google/ads/googleads/v19/enums/types/user_list_customer_type_category.py rename to google/ads/googleads/v23/enums/types/user_list_customer_type_category.py index 53cf360b2..4f1a3ce08 100644 --- a/google/ads/googleads/v19/enums/types/user_list_customer_type_category.py +++ b/google/ads/googleads/v23/enums/types/user_list_customer_type_category.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListCustomerTypeCategoryEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_date_rule_item_operator.py b/google/ads/googleads/v23/enums/types/user_list_date_rule_item_operator.py similarity index 94% rename from google/ads/googleads/v19/enums/types/user_list_date_rule_item_operator.py rename to google/ads/googleads/v23/enums/types/user_list_date_rule_item_operator.py index fe8b85143..945ceffc8 100644 --- a/google/ads/googleads/v19/enums/types/user_list_date_rule_item_operator.py +++ b/google/ads/googleads/v23/enums/types/user_list_date_rule_item_operator.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListDateRuleItemOperatorEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_flexible_rule_operator.py b/google/ads/googleads/v23/enums/types/user_list_flexible_rule_operator.py similarity index 94% rename from google/ads/googleads/v19/enums/types/user_list_flexible_rule_operator.py rename to google/ads/googleads/v23/enums/types/user_list_flexible_rule_operator.py index 1b00976cd..e7ee3e2f8 100644 --- a/google/ads/googleads/v19/enums/types/user_list_flexible_rule_operator.py +++ b/google/ads/googleads/v23/enums/types/user_list_flexible_rule_operator.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListFlexibleRuleOperatorEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_logical_rule_operator.py b/google/ads/googleads/v23/enums/types/user_list_logical_rule_operator.py similarity index 94% rename from google/ads/googleads/v19/enums/types/user_list_logical_rule_operator.py rename to google/ads/googleads/v23/enums/types/user_list_logical_rule_operator.py index e8ea51dbf..2355a0a60 100644 --- a/google/ads/googleads/v19/enums/types/user_list_logical_rule_operator.py +++ b/google/ads/googleads/v23/enums/types/user_list_logical_rule_operator.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListLogicalRuleOperatorEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_membership_status.py b/google/ads/googleads/v23/enums/types/user_list_membership_status.py similarity index 95% rename from google/ads/googleads/v19/enums/types/user_list_membership_status.py rename to google/ads/googleads/v23/enums/types/user_list_membership_status.py index 5272e6381..e45e1980e 100644 --- a/google/ads/googleads/v19/enums/types/user_list_membership_status.py +++ b/google/ads/googleads/v23/enums/types/user_list_membership_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListMembershipStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_number_rule_item_operator.py b/google/ads/googleads/v23/enums/types/user_list_number_rule_item_operator.py similarity index 95% rename from google/ads/googleads/v19/enums/types/user_list_number_rule_item_operator.py rename to google/ads/googleads/v23/enums/types/user_list_number_rule_item_operator.py index 71c2d28a6..6f055e2d3 100644 --- a/google/ads/googleads/v19/enums/types/user_list_number_rule_item_operator.py +++ b/google/ads/googleads/v23/enums/types/user_list_number_rule_item_operator.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListNumberRuleItemOperatorEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_prepopulation_status.py b/google/ads/googleads/v23/enums/types/user_list_prepopulation_status.py similarity index 94% rename from google/ads/googleads/v19/enums/types/user_list_prepopulation_status.py rename to google/ads/googleads/v23/enums/types/user_list_prepopulation_status.py index 1eab5c91b..7a02cd8a3 100644 --- a/google/ads/googleads/v19/enums/types/user_list_prepopulation_status.py +++ b/google/ads/googleads/v23/enums/types/user_list_prepopulation_status.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListPrepopulationStatusEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_rule_type.py b/google/ads/googleads/v23/enums/types/user_list_rule_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/user_list_rule_type.py rename to google/ads/googleads/v23/enums/types/user_list_rule_type.py index 0bb25badf..25855985c 100644 --- a/google/ads/googleads/v19/enums/types/user_list_rule_type.py +++ b/google/ads/googleads/v23/enums/types/user_list_rule_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListRuleTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_size_range.py b/google/ads/googleads/v23/enums/types/user_list_size_range.py similarity index 97% rename from google/ads/googleads/v19/enums/types/user_list_size_range.py rename to google/ads/googleads/v23/enums/types/user_list_size_range.py index 50ac6ca0b..cb6ef3f23 100644 --- a/google/ads/googleads/v19/enums/types/user_list_size_range.py +++ b/google/ads/googleads/v23/enums/types/user_list_size_range.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListSizeRangeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_string_rule_item_operator.py b/google/ads/googleads/v23/enums/types/user_list_string_rule_item_operator.py similarity index 95% rename from google/ads/googleads/v19/enums/types/user_list_string_rule_item_operator.py rename to google/ads/googleads/v23/enums/types/user_list_string_rule_item_operator.py index d290d0570..9e7c7eed4 100644 --- a/google/ads/googleads/v19/enums/types/user_list_string_rule_item_operator.py +++ b/google/ads/googleads/v23/enums/types/user_list_string_rule_item_operator.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListStringRuleItemOperatorEnum", }, diff --git a/google/ads/googleads/v19/enums/types/user_list_type.py b/google/ads/googleads/v23/enums/types/user_list_type.py similarity index 96% rename from google/ads/googleads/v19/enums/types/user_list_type.py rename to google/ads/googleads/v23/enums/types/user_list_type.py index e4d5f864b..6b29cdb9b 100644 --- a/google/ads/googleads/v19/enums/types/user_list_type.py +++ b/google/ads/googleads/v23/enums/types/user_list_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "UserListTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/value_rule_device_type.py b/google/ads/googleads/v23/enums/types/value_rule_device_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/value_rule_device_type.py rename to google/ads/googleads/v23/enums/types/value_rule_device_type.py index 85f662485..02d4880a3 100644 --- a/google/ads/googleads/v19/enums/types/value_rule_device_type.py +++ b/google/ads/googleads/v23/enums/types/value_rule_device_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ValueRuleDeviceTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/value_rule_geo_location_match_type.py b/google/ads/googleads/v23/enums/types/value_rule_geo_location_match_type.py similarity index 95% rename from google/ads/googleads/v19/enums/types/value_rule_geo_location_match_type.py rename to google/ads/googleads/v23/enums/types/value_rule_geo_location_match_type.py index a11a4084f..8ad6ba74b 100644 --- a/google/ads/googleads/v19/enums/types/value_rule_geo_location_match_type.py +++ b/google/ads/googleads/v23/enums/types/value_rule_geo_location_match_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ValueRuleGeoLocationMatchTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/value_rule_operation.py b/google/ads/googleads/v23/enums/types/value_rule_operation.py similarity index 95% rename from google/ads/googleads/v19/enums/types/value_rule_operation.py rename to google/ads/googleads/v23/enums/types/value_rule_operation.py index 7d96d43dc..ce07ad865 100644 --- a/google/ads/googleads/v19/enums/types/value_rule_operation.py +++ b/google/ads/googleads/v23/enums/types/value_rule_operation.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ValueRuleOperationEnum", }, diff --git a/google/ads/googleads/v19/enums/types/value_rule_set_attachment_type.py b/google/ads/googleads/v23/enums/types/value_rule_set_attachment_type.py similarity index 94% rename from google/ads/googleads/v19/enums/types/value_rule_set_attachment_type.py rename to google/ads/googleads/v23/enums/types/value_rule_set_attachment_type.py index f5e66021a..b3a0db796 100644 --- a/google/ads/googleads/v19/enums/types/value_rule_set_attachment_type.py +++ b/google/ads/googleads/v23/enums/types/value_rule_set_attachment_type.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ValueRuleSetAttachmentTypeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/value_rule_set_dimension.py b/google/ads/googleads/v23/enums/types/value_rule_set_dimension.py similarity index 95% rename from google/ads/googleads/v19/enums/types/value_rule_set_dimension.py rename to google/ads/googleads/v23/enums/types/value_rule_set_dimension.py index 25b5c9735..2602c8123 100644 --- a/google/ads/googleads/v19/enums/types/value_rule_set_dimension.py +++ b/google/ads/googleads/v23/enums/types/value_rule_set_dimension.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "ValueRuleSetDimensionEnum", }, diff --git a/google/ads/googleads/v19/enums/types/vanity_pharma_display_url_mode.py b/google/ads/googleads/v23/enums/types/vanity_pharma_display_url_mode.py similarity index 95% rename from google/ads/googleads/v19/enums/types/vanity_pharma_display_url_mode.py rename to google/ads/googleads/v23/enums/types/vanity_pharma_display_url_mode.py index 6cd70a4d0..df4d2af14 100644 --- a/google/ads/googleads/v19/enums/types/vanity_pharma_display_url_mode.py +++ b/google/ads/googleads/v23/enums/types/vanity_pharma_display_url_mode.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "VanityPharmaDisplayUrlModeEnum", }, diff --git a/google/ads/googleads/v19/enums/types/vanity_pharma_text.py b/google/ads/googleads/v23/enums/types/vanity_pharma_text.py similarity index 97% rename from google/ads/googleads/v19/enums/types/vanity_pharma_text.py rename to google/ads/googleads/v23/enums/types/vanity_pharma_text.py index 82b2230c4..5904fe6a3 100644 --- a/google/ads/googleads/v19/enums/types/vanity_pharma_text.py +++ b/google/ads/googleads/v23/enums/types/vanity_pharma_text.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "VanityPharmaTextEnum", }, diff --git a/google/ads/googleads/v23/enums/types/vertical_ads_item_vertical_type.py b/google/ads/googleads/v23/enums/types/vertical_ads_item_vertical_type.py new file mode 100644 index 000000000..04e8dcdaa --- /dev/null +++ b/google/ads/googleads/v23/enums/types/vertical_ads_item_vertical_type.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "VerticalAdsItemVerticalTypeEnum", + }, +) + + +class VerticalAdsItemVerticalTypeEnum(proto.Message): + r"""Container for enum describing Vertical Ads Item Vertical Type for + SharedSet of type VERTICAL_ADS_ITEM_GROUP_RULE_LIST. + + """ + + class VerticalAdsItemVerticalType(proto.Enum): + r"""Enum describing Vertical Ads Item Vertical Type for SharedSet of + type VERTICAL_ADS_ITEM_GROUP_RULE_LIST. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + HOTELS (2): + Hotels travel vertical. + VACATION_RENTALS (3): + Vacation rentals travel vertical. + RENTAL_CARS (4): + Rental cars travel vertical. + EVENTS (5): + Events travel vertical. + THINGS_TO_DO (6): + Things to do travel vertical. + FLIGHTS (7): + Flights travel vertical. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + HOTELS = 2 + VACATION_RENTALS = 3 + RENTAL_CARS = 4 + EVENTS = 5 + THINGS_TO_DO = 6 + FLIGHTS = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/enums/types/video_ad_format_restriction.py b/google/ads/googleads/v23/enums/types/video_ad_format_restriction.py new file mode 100644 index 000000000..02d8d9823 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/video_ad_format_restriction.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "VideoAdFormatRestrictionEnum", + }, +) + + +class VideoAdFormatRestrictionEnum(proto.Message): + r"""Container for enum describing format restrictions for video + responsive ads in video campaigns. + + """ + + class VideoAdFormatRestriction(proto.Enum): + r"""Enum describing format restrictions for responsive ads in + video campaigns. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + NON_SKIPPABLE_IN_STREAM (2): + Non-skippable in-stream video responsive ad. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + NON_SKIPPABLE_IN_STREAM = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/enums/types/video_ad_sequence_interaction_type.py b/google/ads/googleads/v23/enums/types/video_ad_sequence_interaction_type.py new file mode 100644 index 000000000..1ef6a91d5 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/video_ad_sequence_interaction_type.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "VideoAdSequenceInteractionTypeEnum", + }, +) + + +class VideoAdSequenceInteractionTypeEnum(proto.Message): + r"""Container for enum describing an interaction between a viewer + and a video in a video ad sequence. + + """ + + class VideoAdSequenceInteractionType(proto.Enum): + r"""Enum describing an interaction between a viewer and a video + in a video ad sequence. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + PAID_VIEW (2): + The viewer engaged with or watched at least + 30 seconds of the ad (or the entire ad, if it + was less than 30 seconds). Only available for + campaigns using Target CPM as the bidding + strategy and skippable in-stream ads as the ad + format. + SKIP (3): + The viewer skipped the ad. Only available for + campaigns using Target CPM as the bidding + strategy and skippable in-stream ads as the ad + format. + IMPRESSION (4): + The ad was shown to the viewer. + ENGAGED_IMPRESSION (5): + An ad impression that was not immediately + skipped, but didn't reach the billable event + either. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + PAID_VIEW = 2 + SKIP = 3 + IMPRESSION = 4 + ENGAGED_IMPRESSION = 5 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/enums/types/video_ad_sequence_minimum_duration.py b/google/ads/googleads/v23/enums/types/video_ad_sequence_minimum_duration.py new file mode 100644 index 000000000..3fa663fe5 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/video_ad_sequence_minimum_duration.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "VideoAdSequenceMinimumDurationEnum", + }, +) + + +class VideoAdSequenceMinimumDurationEnum(proto.Message): + r"""Container for enum describing possible times after starting a + video ad sequence when a user is eligible to repeat the + sequence. + + """ + + class VideoAdSequenceMinimumDuration(proto.Enum): + r"""Enum describing possible times after starting a video ad + sequence when a user is eligible to repeat the sequence. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + WEEK (2): + Users are eligible to restart a sequence once + they have completed the sequence and at least 7 + days have passed since sequence start. + MONTH (3): + Users are eligible to restart a sequence once + at least 30 days have passed since sequence + start. Users are eligible to start the sequence + again even if they haven't completed the + sequence. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + WEEK = 2 + MONTH = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/enums/types/video_thumbnail.py b/google/ads/googleads/v23/enums/types/video_thumbnail.py similarity index 95% rename from google/ads/googleads/v19/enums/types/video_thumbnail.py rename to google/ads/googleads/v23/enums/types/video_thumbnail.py index 8abb11b13..18f7ab77e 100644 --- a/google/ads/googleads/v19/enums/types/video_thumbnail.py +++ b/google/ads/googleads/v23/enums/types/video_thumbnail.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "VideoThumbnailEnum", }, diff --git a/google/ads/googleads/v19/enums/types/webpage_condition_operand.py b/google/ads/googleads/v23/enums/types/webpage_condition_operand.py similarity index 95% rename from google/ads/googleads/v19/enums/types/webpage_condition_operand.py rename to google/ads/googleads/v23/enums/types/webpage_condition_operand.py index 3697e3e1a..f9754821b 100644 --- a/google/ads/googleads/v19/enums/types/webpage_condition_operand.py +++ b/google/ads/googleads/v23/enums/types/webpage_condition_operand.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "WebpageConditionOperandEnum", }, diff --git a/google/ads/googleads/v19/enums/types/webpage_condition_operator.py b/google/ads/googleads/v23/enums/types/webpage_condition_operator.py similarity index 94% rename from google/ads/googleads/v19/enums/types/webpage_condition_operator.py rename to google/ads/googleads/v23/enums/types/webpage_condition_operator.py index 0bebe7fcf..c5cd6d330 100644 --- a/google/ads/googleads/v19/enums/types/webpage_condition_operator.py +++ b/google/ads/googleads/v23/enums/types/webpage_condition_operator.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.enums", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", manifest={ "WebpageConditionOperatorEnum", }, diff --git a/google/ads/googleads/v23/enums/types/youtube_video_property.py b/google/ads/googleads/v23/enums/types/youtube_video_property.py new file mode 100644 index 000000000..a99a43515 --- /dev/null +++ b/google/ads/googleads/v23/enums/types/youtube_video_property.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.enums", + marshal="google.ads.googleads.v23", + manifest={ + "YouTubeVideoPropertyEnum", + }, +) + + +class YouTubeVideoPropertyEnum(proto.Message): + r"""Container for enum describing the property of a YouTube + video. + + """ + + class YouTubeVideoProperty(proto.Enum): + r"""Describes a property of a YouTube video. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + The value is unknown in this version. + LIVE_STREAM (2): + Video is a live stream. + SHORTS (3): + Video is Shorts eligible. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + LIVE_STREAM = 2 + SHORTS = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/errors/__init__.py b/google/ads/googleads/v23/errors/__init__.py new file mode 100644 index 000000000..43577d19e --- /dev/null +++ b/google/ads/googleads/v23/errors/__init__.py @@ -0,0 +1,519 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from google.ads.googleads.v23 import gapic_version as package_version + +import google.api_core as api_core +import sys + +__version__ = package_version.__version__ + +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata + + +from .types.access_invitation_error import AccessInvitationErrorEnum +from .types.account_budget_proposal_error import AccountBudgetProposalErrorEnum +from .types.account_link_error import AccountLinkErrorEnum +from .types.ad_customizer_error import AdCustomizerErrorEnum +from .types.ad_error import AdErrorEnum +from .types.ad_group_ad_error import AdGroupAdErrorEnum +from .types.ad_group_bid_modifier_error import AdGroupBidModifierErrorEnum +from .types.ad_group_criterion_customizer_error import ( + AdGroupCriterionCustomizerErrorEnum, +) +from .types.ad_group_criterion_error import AdGroupCriterionErrorEnum +from .types.ad_group_customizer_error import AdGroupCustomizerErrorEnum +from .types.ad_group_error import AdGroupErrorEnum +from .types.ad_group_feed_error import AdGroupFeedErrorEnum +from .types.ad_parameter_error import AdParameterErrorEnum +from .types.ad_sharing_error import AdSharingErrorEnum +from .types.adx_error import AdxErrorEnum +from .types.asset_error import AssetErrorEnum +from .types.asset_generation_error import AssetGenerationErrorEnum +from .types.asset_group_asset_error import AssetGroupAssetErrorEnum +from .types.asset_group_error import AssetGroupErrorEnum +from .types.asset_group_listing_group_filter_error import ( + AssetGroupListingGroupFilterErrorEnum, +) +from .types.asset_group_signal_error import AssetGroupSignalErrorEnum +from .types.asset_link_error import AssetLinkErrorEnum +from .types.asset_set_asset_error import AssetSetAssetErrorEnum +from .types.asset_set_error import AssetSetErrorEnum +from .types.asset_set_link_error import AssetSetLinkErrorEnum +from .types.audience_error import AudienceErrorEnum +from .types.audience_insights_error import AudienceInsightsErrorEnum +from .types.authentication_error import AuthenticationErrorEnum +from .types.authorization_error import AuthorizationErrorEnum +from .types.automatically_created_asset_removal_error import ( + AutomaticallyCreatedAssetRemovalErrorEnum, +) +from .types.batch_job_error import BatchJobErrorEnum +from .types.benchmarks_error import BenchmarksErrorEnum +from .types.bidding_error import BiddingErrorEnum +from .types.bidding_strategy_error import BiddingStrategyErrorEnum +from .types.billing_setup_error import BillingSetupErrorEnum +from .types.brand_guidelines_migration_error import ( + BrandGuidelinesMigrationErrorEnum, +) +from .types.campaign_budget_error import CampaignBudgetErrorEnum +from .types.campaign_conversion_goal_error import ( + CampaignConversionGoalErrorEnum, +) +from .types.campaign_criterion_error import CampaignCriterionErrorEnum +from .types.campaign_customizer_error import CampaignCustomizerErrorEnum +from .types.campaign_draft_error import CampaignDraftErrorEnum +from .types.campaign_error import CampaignErrorEnum +from .types.campaign_experiment_error import CampaignExperimentErrorEnum +from .types.campaign_feed_error import CampaignFeedErrorEnum +from .types.campaign_goal_config_error import CampaignGoalConfigErrorEnum +from .types.campaign_lifecycle_goal_error import CampaignLifecycleGoalErrorEnum +from .types.campaign_shared_set_error import CampaignSharedSetErrorEnum +from .types.change_event_error import ChangeEventErrorEnum +from .types.change_status_error import ChangeStatusErrorEnum +from .types.click_view_error import ClickViewErrorEnum +from .types.collection_size_error import CollectionSizeErrorEnum +from .types.context_error import ContextErrorEnum +from .types.conversion_action_error import ConversionActionErrorEnum +from .types.conversion_adjustment_upload_error import ( + ConversionAdjustmentUploadErrorEnum, +) +from .types.conversion_custom_variable_error import ( + ConversionCustomVariableErrorEnum, +) +from .types.conversion_goal_campaign_config_error import ( + ConversionGoalCampaignConfigErrorEnum, +) +from .types.conversion_upload_error import ConversionUploadErrorEnum +from .types.conversion_value_rule_error import ConversionValueRuleErrorEnum +from .types.conversion_value_rule_set_error import ( + ConversionValueRuleSetErrorEnum, +) +from .types.country_code_error import CountryCodeErrorEnum +from .types.criterion_error import CriterionErrorEnum +from .types.currency_code_error import CurrencyCodeErrorEnum +from .types.currency_error import CurrencyErrorEnum +from .types.custom_audience_error import CustomAudienceErrorEnum +from .types.custom_conversion_goal_error import CustomConversionGoalErrorEnum +from .types.custom_interest_error import CustomInterestErrorEnum +from .types.customer_client_link_error import CustomerClientLinkErrorEnum +from .types.customer_customizer_error import CustomerCustomizerErrorEnum +from .types.customer_error import CustomerErrorEnum +from .types.customer_feed_error import CustomerFeedErrorEnum +from .types.customer_lifecycle_goal_error import CustomerLifecycleGoalErrorEnum +from .types.customer_manager_link_error import CustomerManagerLinkErrorEnum +from .types.customer_sk_ad_network_conversion_value_schema_error import ( + CustomerSkAdNetworkConversionValueSchemaErrorEnum, +) +from .types.customer_user_access_error import CustomerUserAccessErrorEnum +from .types.customizer_attribute_error import CustomizerAttributeErrorEnum +from .types.data_link_error import DataLinkErrorEnum +from .types.database_error import DatabaseErrorEnum +from .types.date_error import DateErrorEnum +from .types.date_range_error import DateRangeErrorEnum +from .types.distinct_error import DistinctErrorEnum +from .types.enum_error import EnumErrorEnum +from .types.errors import BudgetPerDayMinimumErrorDetails +from .types.errors import ErrorCode +from .types.errors import ErrorDetails +from .types.errors import ErrorLocation +from .types.errors import GoogleAdsError +from .types.errors import GoogleAdsFailure +from .types.errors import PolicyFindingDetails +from .types.errors import PolicyViolationDetails +from .types.errors import QuotaErrorDetails +from .types.errors import ResourceCountDetails +from .types.experiment_arm_error import ExperimentArmErrorEnum +from .types.experiment_error import ExperimentErrorEnum +from .types.extension_feed_item_error import ExtensionFeedItemErrorEnum +from .types.extension_setting_error import ExtensionSettingErrorEnum +from .types.feed_attribute_reference_error import ( + FeedAttributeReferenceErrorEnum, +) +from .types.feed_error import FeedErrorEnum +from .types.feed_item_error import FeedItemErrorEnum +from .types.feed_item_set_error import FeedItemSetErrorEnum +from .types.feed_item_set_link_error import FeedItemSetLinkErrorEnum +from .types.feed_item_target_error import FeedItemTargetErrorEnum +from .types.feed_item_validation_error import FeedItemValidationErrorEnum +from .types.feed_mapping_error import FeedMappingErrorEnum +from .types.field_error import FieldErrorEnum +from .types.field_mask_error import FieldMaskErrorEnum +from .types.final_url_expansion_asset_view_error import ( + FinalUrlExpansionAssetViewErrorEnum, +) +from .types.function_error import FunctionErrorEnum +from .types.function_parsing_error import FunctionParsingErrorEnum +from .types.geo_target_constant_suggestion_error import ( + GeoTargetConstantSuggestionErrorEnum, +) +from .types.goal_error import GoalErrorEnum +from .types.header_error import HeaderErrorEnum +from .types.id_error import IdErrorEnum +from .types.identity_verification_error import IdentityVerificationErrorEnum +from .types.image_error import ImageErrorEnum +from .types.incentive_error import IncentiveErrorEnum +from .types.internal_error import InternalErrorEnum +from .types.invoice_error import InvoiceErrorEnum +from .types.keyword_plan_ad_group_error import KeywordPlanAdGroupErrorEnum +from .types.keyword_plan_ad_group_keyword_error import ( + KeywordPlanAdGroupKeywordErrorEnum, +) +from .types.keyword_plan_campaign_error import KeywordPlanCampaignErrorEnum +from .types.keyword_plan_campaign_keyword_error import ( + KeywordPlanCampaignKeywordErrorEnum, +) +from .types.keyword_plan_error import KeywordPlanErrorEnum +from .types.keyword_plan_idea_error import KeywordPlanIdeaErrorEnum +from .types.label_error import LabelErrorEnum +from .types.language_code_error import LanguageCodeErrorEnum +from .types.list_operation_error import ListOperationErrorEnum +from .types.manager_link_error import ManagerLinkErrorEnum +from .types.media_bundle_error import MediaBundleErrorEnum +from .types.media_file_error import MediaFileErrorEnum +from .types.media_upload_error import MediaUploadErrorEnum +from .types.merchant_center_error import MerchantCenterErrorEnum +from .types.multiplier_error import MultiplierErrorEnum +from .types.mutate_error import MutateErrorEnum +from .types.new_resource_creation_error import NewResourceCreationErrorEnum +from .types.not_allowlisted_error import NotAllowlistedErrorEnum +from .types.not_empty_error import NotEmptyErrorEnum +from .types.null_error import NullErrorEnum +from .types.offline_user_data_job_error import OfflineUserDataJobErrorEnum +from .types.operation_access_denied_error import OperationAccessDeniedErrorEnum +from .types.operator_error import OperatorErrorEnum +from .types.partial_failure_error import PartialFailureErrorEnum +from .types.payments_account_error import PaymentsAccountErrorEnum +from .types.policy_finding_error import PolicyFindingErrorEnum +from .types.policy_validation_parameter_error import ( + PolicyValidationParameterErrorEnum, +) +from .types.policy_violation_error import PolicyViolationErrorEnum +from .types.product_link_error import ProductLinkErrorEnum +from .types.product_link_invitation_error import ProductLinkInvitationErrorEnum +from .types.query_error import QueryErrorEnum +from .types.quota_error import QuotaErrorEnum +from .types.range_error import RangeErrorEnum +from .types.reach_plan_error import ReachPlanErrorEnum +from .types.recommendation_error import RecommendationErrorEnum +from .types.recommendation_subscription_error import ( + RecommendationSubscriptionErrorEnum, +) +from .types.region_code_error import RegionCodeErrorEnum +from .types.request_error import RequestErrorEnum +from .types.resource_access_denied_error import ResourceAccessDeniedErrorEnum +from .types.resource_count_limit_exceeded_error import ( + ResourceCountLimitExceededErrorEnum, +) +from .types.search_term_insight_error import SearchTermInsightErrorEnum +from .types.setting_error import SettingErrorEnum +from .types.shareable_preview_error import ShareablePreviewErrorEnum +from .types.shared_criterion_error import SharedCriterionErrorEnum +from .types.shared_set_error import SharedSetErrorEnum +from .types.shopping_product_error import ShoppingProductErrorEnum +from .types.size_limit_error import SizeLimitErrorEnum +from .types.smart_campaign_error import SmartCampaignErrorEnum +from .types.string_format_error import StringFormatErrorEnum +from .types.string_length_error import StringLengthErrorEnum +from .types.third_party_app_analytics_link_error import ( + ThirdPartyAppAnalyticsLinkErrorEnum, +) +from .types.time_zone_error import TimeZoneErrorEnum +from .types.url_field_error import UrlFieldErrorEnum +from .types.user_data_error import UserDataErrorEnum +from .types.user_list_customer_type_error import UserListCustomerTypeErrorEnum +from .types.user_list_error import UserListErrorEnum +from .types.video_campaign_error import VideoCampaignErrorEnum +from .types.youtube_video_registration_error import ( + YoutubeVideoRegistrationErrorEnum, +) + +if hasattr(api_core, "check_python_version") and hasattr( + api_core, "check_dependency_versions" +): # pragma: NO COVER + api_core.check_python_version("google.ads.googleads.v23") # type: ignore + api_core.check_dependency_versions("google.ads.googleads.v23") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.ads.googleads.v23" + if sys.version_info < (3, 9): + warnings.warn( + "You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning, + ) + if sys.version_info[:2] == (3, 9): + warnings.warn( + f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning, + ) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version( + _dependency_package + ) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn( + f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning, + ) + except Exception: + warnings.warn( + "Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/" + ) + +__all__ = ( + "AccessInvitationErrorEnum", + "AccountBudgetProposalErrorEnum", + "AccountLinkErrorEnum", + "AdCustomizerErrorEnum", + "AdErrorEnum", + "AdGroupAdErrorEnum", + "AdGroupBidModifierErrorEnum", + "AdGroupCriterionCustomizerErrorEnum", + "AdGroupCriterionErrorEnum", + "AdGroupCustomizerErrorEnum", + "AdGroupErrorEnum", + "AdGroupFeedErrorEnum", + "AdParameterErrorEnum", + "AdSharingErrorEnum", + "AdxErrorEnum", + "AssetErrorEnum", + "AssetGenerationErrorEnum", + "AssetGroupAssetErrorEnum", + "AssetGroupErrorEnum", + "AssetGroupListingGroupFilterErrorEnum", + "AssetGroupSignalErrorEnum", + "AssetLinkErrorEnum", + "AssetSetAssetErrorEnum", + "AssetSetErrorEnum", + "AssetSetLinkErrorEnum", + "AudienceErrorEnum", + "AudienceInsightsErrorEnum", + "AuthenticationErrorEnum", + "AuthorizationErrorEnum", + "AutomaticallyCreatedAssetRemovalErrorEnum", + "BatchJobErrorEnum", + "BenchmarksErrorEnum", + "BiddingErrorEnum", + "BiddingStrategyErrorEnum", + "BillingSetupErrorEnum", + "BrandGuidelinesMigrationErrorEnum", + "BudgetPerDayMinimumErrorDetails", + "CampaignBudgetErrorEnum", + "CampaignConversionGoalErrorEnum", + "CampaignCriterionErrorEnum", + "CampaignCustomizerErrorEnum", + "CampaignDraftErrorEnum", + "CampaignErrorEnum", + "CampaignExperimentErrorEnum", + "CampaignFeedErrorEnum", + "CampaignGoalConfigErrorEnum", + "CampaignLifecycleGoalErrorEnum", + "CampaignSharedSetErrorEnum", + "ChangeEventErrorEnum", + "ChangeStatusErrorEnum", + "ClickViewErrorEnum", + "CollectionSizeErrorEnum", + "ContextErrorEnum", + "ConversionActionErrorEnum", + "ConversionAdjustmentUploadErrorEnum", + "ConversionCustomVariableErrorEnum", + "ConversionGoalCampaignConfigErrorEnum", + "ConversionUploadErrorEnum", + "ConversionValueRuleErrorEnum", + "ConversionValueRuleSetErrorEnum", + "CountryCodeErrorEnum", + "CriterionErrorEnum", + "CurrencyCodeErrorEnum", + "CurrencyErrorEnum", + "CustomAudienceErrorEnum", + "CustomConversionGoalErrorEnum", + "CustomInterestErrorEnum", + "CustomerClientLinkErrorEnum", + "CustomerCustomizerErrorEnum", + "CustomerErrorEnum", + "CustomerFeedErrorEnum", + "CustomerLifecycleGoalErrorEnum", + "CustomerManagerLinkErrorEnum", + "CustomerSkAdNetworkConversionValueSchemaErrorEnum", + "CustomerUserAccessErrorEnum", + "CustomizerAttributeErrorEnum", + "DataLinkErrorEnum", + "DatabaseErrorEnum", + "DateErrorEnum", + "DateRangeErrorEnum", + "DistinctErrorEnum", + "EnumErrorEnum", + "ErrorCode", + "ErrorDetails", + "ErrorLocation", + "ExperimentArmErrorEnum", + "ExperimentErrorEnum", + "ExtensionFeedItemErrorEnum", + "ExtensionSettingErrorEnum", + "FeedAttributeReferenceErrorEnum", + "FeedErrorEnum", + "FeedItemErrorEnum", + "FeedItemSetErrorEnum", + "FeedItemSetLinkErrorEnum", + "FeedItemTargetErrorEnum", + "FeedItemValidationErrorEnum", + "FeedMappingErrorEnum", + "FieldErrorEnum", + "FieldMaskErrorEnum", + "FinalUrlExpansionAssetViewErrorEnum", + "FunctionErrorEnum", + "FunctionParsingErrorEnum", + "GeoTargetConstantSuggestionErrorEnum", + "GoalErrorEnum", + "GoogleAdsError", + "GoogleAdsFailure", + "HeaderErrorEnum", + "IdErrorEnum", + "IdentityVerificationErrorEnum", + "ImageErrorEnum", + "IncentiveErrorEnum", + "InternalErrorEnum", + "InvoiceErrorEnum", + "KeywordPlanAdGroupErrorEnum", + "KeywordPlanAdGroupKeywordErrorEnum", + "KeywordPlanCampaignErrorEnum", + "KeywordPlanCampaignKeywordErrorEnum", + "KeywordPlanErrorEnum", + "KeywordPlanIdeaErrorEnum", + "LabelErrorEnum", + "LanguageCodeErrorEnum", + "ListOperationErrorEnum", + "ManagerLinkErrorEnum", + "MediaBundleErrorEnum", + "MediaFileErrorEnum", + "MediaUploadErrorEnum", + "MerchantCenterErrorEnum", + "MultiplierErrorEnum", + "MutateErrorEnum", + "NewResourceCreationErrorEnum", + "NotAllowlistedErrorEnum", + "NotEmptyErrorEnum", + "NullErrorEnum", + "OfflineUserDataJobErrorEnum", + "OperationAccessDeniedErrorEnum", + "OperatorErrorEnum", + "PartialFailureErrorEnum", + "PaymentsAccountErrorEnum", + "PolicyFindingDetails", + "PolicyFindingErrorEnum", + "PolicyValidationParameterErrorEnum", + "PolicyViolationDetails", + "PolicyViolationErrorEnum", + "ProductLinkErrorEnum", + "ProductLinkInvitationErrorEnum", + "QueryErrorEnum", + "QuotaErrorDetails", + "QuotaErrorEnum", + "RangeErrorEnum", + "ReachPlanErrorEnum", + "RecommendationErrorEnum", + "RecommendationSubscriptionErrorEnum", + "RegionCodeErrorEnum", + "RequestErrorEnum", + "ResourceAccessDeniedErrorEnum", + "ResourceCountDetails", + "ResourceCountLimitExceededErrorEnum", + "SearchTermInsightErrorEnum", + "SettingErrorEnum", + "ShareablePreviewErrorEnum", + "SharedCriterionErrorEnum", + "SharedSetErrorEnum", + "ShoppingProductErrorEnum", + "SizeLimitErrorEnum", + "SmartCampaignErrorEnum", + "StringFormatErrorEnum", + "StringLengthErrorEnum", + "ThirdPartyAppAnalyticsLinkErrorEnum", + "TimeZoneErrorEnum", + "UrlFieldErrorEnum", + "UserDataErrorEnum", + "UserListCustomerTypeErrorEnum", + "UserListErrorEnum", + "VideoCampaignErrorEnum", + "YoutubeVideoRegistrationErrorEnum", +) diff --git a/google/ads/googleads/v19/errors/services/__init__.py b/google/ads/googleads/v23/errors/services/__init__.py similarity index 100% rename from google/ads/googleads/v19/errors/services/__init__.py rename to google/ads/googleads/v23/errors/services/__init__.py diff --git a/google/ads/googleads/v23/errors/types/__init__.py b/google/ads/googleads/v23/errors/types/__init__.py new file mode 100644 index 000000000..40c683a65 --- /dev/null +++ b/google/ads/googleads/v23/errors/types/__init__.py @@ -0,0 +1,700 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .access_invitation_error import ( + AccessInvitationErrorEnum, +) +from .account_budget_proposal_error import ( + AccountBudgetProposalErrorEnum, +) +from .account_link_error import ( + AccountLinkErrorEnum, +) +from .ad_customizer_error import ( + AdCustomizerErrorEnum, +) +from .ad_error import ( + AdErrorEnum, +) +from .ad_group_ad_error import ( + AdGroupAdErrorEnum, +) +from .ad_group_bid_modifier_error import ( + AdGroupBidModifierErrorEnum, +) +from .ad_group_criterion_customizer_error import ( + AdGroupCriterionCustomizerErrorEnum, +) +from .ad_group_criterion_error import ( + AdGroupCriterionErrorEnum, +) +from .ad_group_customizer_error import ( + AdGroupCustomizerErrorEnum, +) +from .ad_group_error import ( + AdGroupErrorEnum, +) +from .ad_group_feed_error import ( + AdGroupFeedErrorEnum, +) +from .ad_parameter_error import ( + AdParameterErrorEnum, +) +from .ad_sharing_error import ( + AdSharingErrorEnum, +) +from .adx_error import ( + AdxErrorEnum, +) +from .asset_error import ( + AssetErrorEnum, +) +from .asset_generation_error import ( + AssetGenerationErrorEnum, +) +from .asset_group_asset_error import ( + AssetGroupAssetErrorEnum, +) +from .asset_group_error import ( + AssetGroupErrorEnum, +) +from .asset_group_listing_group_filter_error import ( + AssetGroupListingGroupFilterErrorEnum, +) +from .asset_group_signal_error import ( + AssetGroupSignalErrorEnum, +) +from .asset_link_error import ( + AssetLinkErrorEnum, +) +from .asset_set_asset_error import ( + AssetSetAssetErrorEnum, +) +from .asset_set_error import ( + AssetSetErrorEnum, +) +from .asset_set_link_error import ( + AssetSetLinkErrorEnum, +) +from .audience_error import ( + AudienceErrorEnum, +) +from .audience_insights_error import ( + AudienceInsightsErrorEnum, +) +from .authentication_error import ( + AuthenticationErrorEnum, +) +from .authorization_error import ( + AuthorizationErrorEnum, +) +from .automatically_created_asset_removal_error import ( + AutomaticallyCreatedAssetRemovalErrorEnum, +) +from .batch_job_error import ( + BatchJobErrorEnum, +) +from .benchmarks_error import ( + BenchmarksErrorEnum, +) +from .bidding_error import ( + BiddingErrorEnum, +) +from .bidding_strategy_error import ( + BiddingStrategyErrorEnum, +) +from .billing_setup_error import ( + BillingSetupErrorEnum, +) +from .brand_guidelines_migration_error import ( + BrandGuidelinesMigrationErrorEnum, +) +from .campaign_budget_error import ( + CampaignBudgetErrorEnum, +) +from .campaign_conversion_goal_error import ( + CampaignConversionGoalErrorEnum, +) +from .campaign_criterion_error import ( + CampaignCriterionErrorEnum, +) +from .campaign_customizer_error import ( + CampaignCustomizerErrorEnum, +) +from .campaign_draft_error import ( + CampaignDraftErrorEnum, +) +from .campaign_error import ( + CampaignErrorEnum, +) +from .campaign_experiment_error import ( + CampaignExperimentErrorEnum, +) +from .campaign_feed_error import ( + CampaignFeedErrorEnum, +) +from .campaign_goal_config_error import ( + CampaignGoalConfigErrorEnum, +) +from .campaign_lifecycle_goal_error import ( + CampaignLifecycleGoalErrorEnum, +) +from .campaign_shared_set_error import ( + CampaignSharedSetErrorEnum, +) +from .change_event_error import ( + ChangeEventErrorEnum, +) +from .change_status_error import ( + ChangeStatusErrorEnum, +) +from .click_view_error import ( + ClickViewErrorEnum, +) +from .collection_size_error import ( + CollectionSizeErrorEnum, +) +from .context_error import ( + ContextErrorEnum, +) +from .conversion_action_error import ( + ConversionActionErrorEnum, +) +from .conversion_adjustment_upload_error import ( + ConversionAdjustmentUploadErrorEnum, +) +from .conversion_custom_variable_error import ( + ConversionCustomVariableErrorEnum, +) +from .conversion_goal_campaign_config_error import ( + ConversionGoalCampaignConfigErrorEnum, +) +from .conversion_upload_error import ( + ConversionUploadErrorEnum, +) +from .conversion_value_rule_error import ( + ConversionValueRuleErrorEnum, +) +from .conversion_value_rule_set_error import ( + ConversionValueRuleSetErrorEnum, +) +from .country_code_error import ( + CountryCodeErrorEnum, +) +from .criterion_error import ( + CriterionErrorEnum, +) +from .currency_code_error import ( + CurrencyCodeErrorEnum, +) +from .currency_error import ( + CurrencyErrorEnum, +) +from .custom_audience_error import ( + CustomAudienceErrorEnum, +) +from .custom_conversion_goal_error import ( + CustomConversionGoalErrorEnum, +) +from .custom_interest_error import ( + CustomInterestErrorEnum, +) +from .customer_client_link_error import ( + CustomerClientLinkErrorEnum, +) +from .customer_customizer_error import ( + CustomerCustomizerErrorEnum, +) +from .customer_error import ( + CustomerErrorEnum, +) +from .customer_feed_error import ( + CustomerFeedErrorEnum, +) +from .customer_lifecycle_goal_error import ( + CustomerLifecycleGoalErrorEnum, +) +from .customer_manager_link_error import ( + CustomerManagerLinkErrorEnum, +) +from .customer_sk_ad_network_conversion_value_schema_error import ( + CustomerSkAdNetworkConversionValueSchemaErrorEnum, +) +from .customer_user_access_error import ( + CustomerUserAccessErrorEnum, +) +from .customizer_attribute_error import ( + CustomizerAttributeErrorEnum, +) +from .data_link_error import ( + DataLinkErrorEnum, +) +from .database_error import ( + DatabaseErrorEnum, +) +from .date_error import ( + DateErrorEnum, +) +from .date_range_error import ( + DateRangeErrorEnum, +) +from .distinct_error import ( + DistinctErrorEnum, +) +from .enum_error import ( + EnumErrorEnum, +) +from .errors import ( + BudgetPerDayMinimumErrorDetails, + ErrorCode, + ErrorDetails, + ErrorLocation, + GoogleAdsError, + GoogleAdsFailure, + PolicyFindingDetails, + PolicyViolationDetails, + QuotaErrorDetails, + ResourceCountDetails, +) +from .experiment_arm_error import ( + ExperimentArmErrorEnum, +) +from .experiment_error import ( + ExperimentErrorEnum, +) +from .extension_feed_item_error import ( + ExtensionFeedItemErrorEnum, +) +from .extension_setting_error import ( + ExtensionSettingErrorEnum, +) +from .feed_attribute_reference_error import ( + FeedAttributeReferenceErrorEnum, +) +from .feed_error import ( + FeedErrorEnum, +) +from .feed_item_error import ( + FeedItemErrorEnum, +) +from .feed_item_set_error import ( + FeedItemSetErrorEnum, +) +from .feed_item_set_link_error import ( + FeedItemSetLinkErrorEnum, +) +from .feed_item_target_error import ( + FeedItemTargetErrorEnum, +) +from .feed_item_validation_error import ( + FeedItemValidationErrorEnum, +) +from .feed_mapping_error import ( + FeedMappingErrorEnum, +) +from .field_error import ( + FieldErrorEnum, +) +from .field_mask_error import ( + FieldMaskErrorEnum, +) +from .final_url_expansion_asset_view_error import ( + FinalUrlExpansionAssetViewErrorEnum, +) +from .function_error import ( + FunctionErrorEnum, +) +from .function_parsing_error import ( + FunctionParsingErrorEnum, +) +from .geo_target_constant_suggestion_error import ( + GeoTargetConstantSuggestionErrorEnum, +) +from .goal_error import ( + GoalErrorEnum, +) +from .header_error import ( + HeaderErrorEnum, +) +from .id_error import ( + IdErrorEnum, +) +from .identity_verification_error import ( + IdentityVerificationErrorEnum, +) +from .image_error import ( + ImageErrorEnum, +) +from .incentive_error import ( + IncentiveErrorEnum, +) +from .internal_error import ( + InternalErrorEnum, +) +from .invoice_error import ( + InvoiceErrorEnum, +) +from .keyword_plan_ad_group_error import ( + KeywordPlanAdGroupErrorEnum, +) +from .keyword_plan_ad_group_keyword_error import ( + KeywordPlanAdGroupKeywordErrorEnum, +) +from .keyword_plan_campaign_error import ( + KeywordPlanCampaignErrorEnum, +) +from .keyword_plan_campaign_keyword_error import ( + KeywordPlanCampaignKeywordErrorEnum, +) +from .keyword_plan_error import ( + KeywordPlanErrorEnum, +) +from .keyword_plan_idea_error import ( + KeywordPlanIdeaErrorEnum, +) +from .label_error import ( + LabelErrorEnum, +) +from .language_code_error import ( + LanguageCodeErrorEnum, +) +from .list_operation_error import ( + ListOperationErrorEnum, +) +from .manager_link_error import ( + ManagerLinkErrorEnum, +) +from .media_bundle_error import ( + MediaBundleErrorEnum, +) +from .media_file_error import ( + MediaFileErrorEnum, +) +from .media_upload_error import ( + MediaUploadErrorEnum, +) +from .merchant_center_error import ( + MerchantCenterErrorEnum, +) +from .multiplier_error import ( + MultiplierErrorEnum, +) +from .mutate_error import ( + MutateErrorEnum, +) +from .new_resource_creation_error import ( + NewResourceCreationErrorEnum, +) +from .not_allowlisted_error import ( + NotAllowlistedErrorEnum, +) +from .not_empty_error import ( + NotEmptyErrorEnum, +) +from .null_error import ( + NullErrorEnum, +) +from .offline_user_data_job_error import ( + OfflineUserDataJobErrorEnum, +) +from .operation_access_denied_error import ( + OperationAccessDeniedErrorEnum, +) +from .operator_error import ( + OperatorErrorEnum, +) +from .partial_failure_error import ( + PartialFailureErrorEnum, +) +from .payments_account_error import ( + PaymentsAccountErrorEnum, +) +from .policy_finding_error import ( + PolicyFindingErrorEnum, +) +from .policy_validation_parameter_error import ( + PolicyValidationParameterErrorEnum, +) +from .policy_violation_error import ( + PolicyViolationErrorEnum, +) +from .product_link_error import ( + ProductLinkErrorEnum, +) +from .product_link_invitation_error import ( + ProductLinkInvitationErrorEnum, +) +from .query_error import ( + QueryErrorEnum, +) +from .quota_error import ( + QuotaErrorEnum, +) +from .range_error import ( + RangeErrorEnum, +) +from .reach_plan_error import ( + ReachPlanErrorEnum, +) +from .recommendation_error import ( + RecommendationErrorEnum, +) +from .recommendation_subscription_error import ( + RecommendationSubscriptionErrorEnum, +) +from .region_code_error import ( + RegionCodeErrorEnum, +) +from .request_error import ( + RequestErrorEnum, +) +from .resource_access_denied_error import ( + ResourceAccessDeniedErrorEnum, +) +from .resource_count_limit_exceeded_error import ( + ResourceCountLimitExceededErrorEnum, +) +from .search_term_insight_error import ( + SearchTermInsightErrorEnum, +) +from .setting_error import ( + SettingErrorEnum, +) +from .shareable_preview_error import ( + ShareablePreviewErrorEnum, +) +from .shared_criterion_error import ( + SharedCriterionErrorEnum, +) +from .shared_set_error import ( + SharedSetErrorEnum, +) +from .shopping_product_error import ( + ShoppingProductErrorEnum, +) +from .size_limit_error import ( + SizeLimitErrorEnum, +) +from .smart_campaign_error import ( + SmartCampaignErrorEnum, +) +from .string_format_error import ( + StringFormatErrorEnum, +) +from .string_length_error import ( + StringLengthErrorEnum, +) +from .third_party_app_analytics_link_error import ( + ThirdPartyAppAnalyticsLinkErrorEnum, +) +from .time_zone_error import ( + TimeZoneErrorEnum, +) +from .url_field_error import ( + UrlFieldErrorEnum, +) +from .user_data_error import ( + UserDataErrorEnum, +) +from .user_list_customer_type_error import ( + UserListCustomerTypeErrorEnum, +) +from .user_list_error import ( + UserListErrorEnum, +) +from .video_campaign_error import ( + VideoCampaignErrorEnum, +) +from .youtube_video_registration_error import ( + YoutubeVideoRegistrationErrorEnum, +) + +__all__ = ( + "AccessInvitationErrorEnum", + "AccountBudgetProposalErrorEnum", + "AccountLinkErrorEnum", + "AdCustomizerErrorEnum", + "AdErrorEnum", + "AdGroupAdErrorEnum", + "AdGroupBidModifierErrorEnum", + "AdGroupCriterionCustomizerErrorEnum", + "AdGroupCriterionErrorEnum", + "AdGroupCustomizerErrorEnum", + "AdGroupErrorEnum", + "AdGroupFeedErrorEnum", + "AdParameterErrorEnum", + "AdSharingErrorEnum", + "AdxErrorEnum", + "AssetErrorEnum", + "AssetGenerationErrorEnum", + "AssetGroupAssetErrorEnum", + "AssetGroupErrorEnum", + "AssetGroupListingGroupFilterErrorEnum", + "AssetGroupSignalErrorEnum", + "AssetLinkErrorEnum", + "AssetSetAssetErrorEnum", + "AssetSetErrorEnum", + "AssetSetLinkErrorEnum", + "AudienceErrorEnum", + "AudienceInsightsErrorEnum", + "AuthenticationErrorEnum", + "AuthorizationErrorEnum", + "AutomaticallyCreatedAssetRemovalErrorEnum", + "BatchJobErrorEnum", + "BenchmarksErrorEnum", + "BiddingErrorEnum", + "BiddingStrategyErrorEnum", + "BillingSetupErrorEnum", + "BrandGuidelinesMigrationErrorEnum", + "CampaignBudgetErrorEnum", + "CampaignConversionGoalErrorEnum", + "CampaignCriterionErrorEnum", + "CampaignCustomizerErrorEnum", + "CampaignDraftErrorEnum", + "CampaignErrorEnum", + "CampaignExperimentErrorEnum", + "CampaignFeedErrorEnum", + "CampaignGoalConfigErrorEnum", + "CampaignLifecycleGoalErrorEnum", + "CampaignSharedSetErrorEnum", + "ChangeEventErrorEnum", + "ChangeStatusErrorEnum", + "ClickViewErrorEnum", + "CollectionSizeErrorEnum", + "ContextErrorEnum", + "ConversionActionErrorEnum", + "ConversionAdjustmentUploadErrorEnum", + "ConversionCustomVariableErrorEnum", + "ConversionGoalCampaignConfigErrorEnum", + "ConversionUploadErrorEnum", + "ConversionValueRuleErrorEnum", + "ConversionValueRuleSetErrorEnum", + "CountryCodeErrorEnum", + "CriterionErrorEnum", + "CurrencyCodeErrorEnum", + "CurrencyErrorEnum", + "CustomAudienceErrorEnum", + "CustomConversionGoalErrorEnum", + "CustomInterestErrorEnum", + "CustomerClientLinkErrorEnum", + "CustomerCustomizerErrorEnum", + "CustomerErrorEnum", + "CustomerFeedErrorEnum", + "CustomerLifecycleGoalErrorEnum", + "CustomerManagerLinkErrorEnum", + "CustomerSkAdNetworkConversionValueSchemaErrorEnum", + "CustomerUserAccessErrorEnum", + "CustomizerAttributeErrorEnum", + "DataLinkErrorEnum", + "DatabaseErrorEnum", + "DateErrorEnum", + "DateRangeErrorEnum", + "DistinctErrorEnum", + "EnumErrorEnum", + "BudgetPerDayMinimumErrorDetails", + "ErrorCode", + "ErrorDetails", + "ErrorLocation", + "GoogleAdsError", + "GoogleAdsFailure", + "PolicyFindingDetails", + "PolicyViolationDetails", + "QuotaErrorDetails", + "ResourceCountDetails", + "ExperimentArmErrorEnum", + "ExperimentErrorEnum", + "ExtensionFeedItemErrorEnum", + "ExtensionSettingErrorEnum", + "FeedAttributeReferenceErrorEnum", + "FeedErrorEnum", + "FeedItemErrorEnum", + "FeedItemSetErrorEnum", + "FeedItemSetLinkErrorEnum", + "FeedItemTargetErrorEnum", + "FeedItemValidationErrorEnum", + "FeedMappingErrorEnum", + "FieldErrorEnum", + "FieldMaskErrorEnum", + "FinalUrlExpansionAssetViewErrorEnum", + "FunctionErrorEnum", + "FunctionParsingErrorEnum", + "GeoTargetConstantSuggestionErrorEnum", + "GoalErrorEnum", + "HeaderErrorEnum", + "IdErrorEnum", + "IdentityVerificationErrorEnum", + "ImageErrorEnum", + "IncentiveErrorEnum", + "InternalErrorEnum", + "InvoiceErrorEnum", + "KeywordPlanAdGroupErrorEnum", + "KeywordPlanAdGroupKeywordErrorEnum", + "KeywordPlanCampaignErrorEnum", + "KeywordPlanCampaignKeywordErrorEnum", + "KeywordPlanErrorEnum", + "KeywordPlanIdeaErrorEnum", + "LabelErrorEnum", + "LanguageCodeErrorEnum", + "ListOperationErrorEnum", + "ManagerLinkErrorEnum", + "MediaBundleErrorEnum", + "MediaFileErrorEnum", + "MediaUploadErrorEnum", + "MerchantCenterErrorEnum", + "MultiplierErrorEnum", + "MutateErrorEnum", + "NewResourceCreationErrorEnum", + "NotAllowlistedErrorEnum", + "NotEmptyErrorEnum", + "NullErrorEnum", + "OfflineUserDataJobErrorEnum", + "OperationAccessDeniedErrorEnum", + "OperatorErrorEnum", + "PartialFailureErrorEnum", + "PaymentsAccountErrorEnum", + "PolicyFindingErrorEnum", + "PolicyValidationParameterErrorEnum", + "PolicyViolationErrorEnum", + "ProductLinkErrorEnum", + "ProductLinkInvitationErrorEnum", + "QueryErrorEnum", + "QuotaErrorEnum", + "RangeErrorEnum", + "ReachPlanErrorEnum", + "RecommendationErrorEnum", + "RecommendationSubscriptionErrorEnum", + "RegionCodeErrorEnum", + "RequestErrorEnum", + "ResourceAccessDeniedErrorEnum", + "ResourceCountLimitExceededErrorEnum", + "SearchTermInsightErrorEnum", + "SettingErrorEnum", + "ShareablePreviewErrorEnum", + "SharedCriterionErrorEnum", + "SharedSetErrorEnum", + "ShoppingProductErrorEnum", + "SizeLimitErrorEnum", + "SmartCampaignErrorEnum", + "StringFormatErrorEnum", + "StringLengthErrorEnum", + "ThirdPartyAppAnalyticsLinkErrorEnum", + "TimeZoneErrorEnum", + "UrlFieldErrorEnum", + "UserDataErrorEnum", + "UserListCustomerTypeErrorEnum", + "UserListErrorEnum", + "VideoCampaignErrorEnum", + "YoutubeVideoRegistrationErrorEnum", +) diff --git a/google/ads/googleads/v19/errors/types/access_invitation_error.py b/google/ads/googleads/v23/errors/types/access_invitation_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/access_invitation_error.py rename to google/ads/googleads/v23/errors/types/access_invitation_error.py index d077b94f0..cc022c4af 100644 --- a/google/ads/googleads/v19/errors/types/access_invitation_error.py +++ b/google/ads/googleads/v23/errors/types/access_invitation_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AccessInvitationErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/account_budget_proposal_error.py b/google/ads/googleads/v23/errors/types/account_budget_proposal_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/account_budget_proposal_error.py rename to google/ads/googleads/v23/errors/types/account_budget_proposal_error.py index 51baad95c..88b6920d3 100644 --- a/google/ads/googleads/v19/errors/types/account_budget_proposal_error.py +++ b/google/ads/googleads/v23/errors/types/account_budget_proposal_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AccountBudgetProposalErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/account_link_error.py b/google/ads/googleads/v23/errors/types/account_link_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/account_link_error.py rename to google/ads/googleads/v23/errors/types/account_link_error.py index 2953836db..765e786fc 100644 --- a/google/ads/googleads/v19/errors/types/account_link_error.py +++ b/google/ads/googleads/v23/errors/types/account_link_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AccountLinkErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/ad_customizer_error.py b/google/ads/googleads/v23/errors/types/ad_customizer_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/ad_customizer_error.py rename to google/ads/googleads/v23/errors/types/ad_customizer_error.py index e23f8ccdb..24992e248 100644 --- a/google/ads/googleads/v19/errors/types/ad_customizer_error.py +++ b/google/ads/googleads/v23/errors/types/ad_customizer_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AdCustomizerErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/ad_error.py b/google/ads/googleads/v23/errors/types/ad_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/ad_error.py rename to google/ads/googleads/v23/errors/types/ad_error.py index c39d4c35e..f0c9f4399 100644 --- a/google/ads/googleads/v19/errors/types/ad_error.py +++ b/google/ads/googleads/v23/errors/types/ad_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AdErrorEnum", }, @@ -446,6 +446,10 @@ class AdError(proto.Enum): DUPLICATE_IMAGE_ACROSS_CAROUSEL_CARDS (156): Images must be unique between different carousel card assets. + INVALID_YOUTUBE_VIDEO_ASSET_ID_FOR_VIDEO_ADS_SEQUENCING (157): + For video ads sequencing, YouTube video asset ID has to be + defined in + ``campaign.video_campaign_settings.video_ad_sequence.steps.asset_id``. """ UNSPECIFIED = 0 @@ -602,6 +606,7 @@ class AdError(proto.Enum): MISSING_REQUIRED_IMAGE_ASPECT_RATIO = 153 MISMATCHED_ASPECT_RATIOS = 155 DUPLICATE_IMAGE_ACROSS_CAROUSEL_CARDS = 156 + INVALID_YOUTUBE_VIDEO_ASSET_ID_FOR_VIDEO_ADS_SEQUENCING = 157 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/ad_group_ad_error.py b/google/ads/googleads/v23/errors/types/ad_group_ad_error.py similarity index 93% rename from google/ads/googleads/v19/errors/types/ad_group_ad_error.py rename to google/ads/googleads/v23/errors/types/ad_group_ad_error.py index 36e6c7a1b..7a31a6c94 100644 --- a/google/ads/googleads/v19/errors/types/ad_group_ad_error.py +++ b/google/ads/googleads/v23/errors/types/ad_group_ad_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAdErrorEnum", }, @@ -70,6 +70,8 @@ class AdGroupAdError(proto.Enum): CANNOT_UPDATE_DEPRECATED_ADS (12): An ad of this type is deprecated and cannot be updated. Only removals are permitted. + AD_SHARING_NOT_ALLOWED (13): + Ad sharing is not allowed. """ UNSPECIFIED = 0 @@ -85,6 +87,7 @@ class AdGroupAdError(proto.Enum): AD_TYPE_CANNOT_BE_PAUSED = 10 AD_TYPE_CANNOT_BE_REMOVED = 11 CANNOT_UPDATE_DEPRECATED_ADS = 12 + AD_SHARING_NOT_ALLOWED = 13 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/ad_group_bid_modifier_error.py b/google/ads/googleads/v23/errors/types/ad_group_bid_modifier_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/ad_group_bid_modifier_error.py rename to google/ads/googleads/v23/errors/types/ad_group_bid_modifier_error.py index 91a1f109e..c0b5e4961 100644 --- a/google/ads/googleads/v19/errors/types/ad_group_bid_modifier_error.py +++ b/google/ads/googleads/v23/errors/types/ad_group_bid_modifier_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AdGroupBidModifierErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/ad_group_criterion_customizer_error.py b/google/ads/googleads/v23/errors/types/ad_group_criterion_customizer_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/ad_group_criterion_customizer_error.py rename to google/ads/googleads/v23/errors/types/ad_group_criterion_customizer_error.py index 63be2d6d7..a4c010cd4 100644 --- a/google/ads/googleads/v19/errors/types/ad_group_criterion_customizer_error.py +++ b/google/ads/googleads/v23/errors/types/ad_group_criterion_customizer_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCriterionCustomizerErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/ad_group_criterion_error.py b/google/ads/googleads/v23/errors/types/ad_group_criterion_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/ad_group_criterion_error.py rename to google/ads/googleads/v23/errors/types/ad_group_criterion_error.py index a9edf34cd..72d00d885 100644 --- a/google/ads/googleads/v19/errors/types/ad_group_criterion_error.py +++ b/google/ads/googleads/v23/errors/types/ad_group_criterion_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCriterionErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/ad_group_customizer_error.py b/google/ads/googleads/v23/errors/types/ad_group_customizer_error.py similarity index 93% rename from google/ads/googleads/v19/errors/types/ad_group_customizer_error.py rename to google/ads/googleads/v23/errors/types/ad_group_customizer_error.py index 39ef1130f..35dcaa06c 100644 --- a/google/ads/googleads/v19/errors/types/ad_group_customizer_error.py +++ b/google/ads/googleads/v23/errors/types/ad_group_customizer_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCustomizerErrorEnum", }, diff --git a/google/ads/googleads/v23/errors/types/ad_group_error.py b/google/ads/googleads/v23/errors/types/ad_group_error.py new file mode 100644 index 000000000..65c0465b8 --- /dev/null +++ b/google/ads/googleads/v23/errors/types/ad_group_error.py @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", + manifest={ + "AdGroupErrorEnum", + }, +) + + +class AdGroupErrorEnum(proto.Message): + r"""Container for enum describing possible ad group errors.""" + + class AdGroupError(proto.Enum): + r"""Enum describing possible ad group errors. + + Values: + UNSPECIFIED (0): + Enum unspecified. + UNKNOWN (1): + The received error code is not known in this + version. + DUPLICATE_ADGROUP_NAME (2): + AdGroup with the same name already exists for + the campaign. + INVALID_ADGROUP_NAME (3): + AdGroup name is not valid. + ADVERTISER_NOT_ON_CONTENT_NETWORK (5): + Advertiser is not allowed to target sites or + set site bids that are not on the Google Search + Network. + BID_TOO_BIG (6): + Bid amount is too big. + BID_TYPE_AND_BIDDING_STRATEGY_MISMATCH (7): + AdGroup bid does not match the campaign's + bidding strategy. + MISSING_ADGROUP_NAME (8): + AdGroup name is required for Add. + ADGROUP_LABEL_DOES_NOT_EXIST (9): + No link found between the ad group and the + label. + ADGROUP_LABEL_ALREADY_EXISTS (10): + The label has already been attached to the ad + group. + INVALID_CONTENT_BID_CRITERION_TYPE_GROUP (11): + The CriterionTypeGroup is not supported for + the content bid dimension. + AD_GROUP_TYPE_NOT_VALID_FOR_ADVERTISING_CHANNEL_TYPE (12): + The ad group type is not compatible with the + campaign channel type. + ADGROUP_TYPE_NOT_SUPPORTED_FOR_CAMPAIGN_SALES_COUNTRY (13): + The ad group type is not supported in the + country of sale of the campaign. + CANNOT_ADD_ADGROUP_OF_TYPE_DSA_TO_CAMPAIGN_WITHOUT_DSA_SETTING (14): + Ad groups of AdGroupType.SEARCH_DYNAMIC_ADS can only be + added to campaigns that have DynamicSearchAdsSetting + attached. + PROMOTED_HOTEL_AD_GROUPS_NOT_AVAILABLE_FOR_CUSTOMER (15): + Promoted hotels ad groups are only available + to customers on the allow-list. + INVALID_EXCLUDED_PARENT_ASSET_FIELD_TYPE (16): + The field type cannot be excluded because an + active ad group-asset link of this type exists. + INVALID_EXCLUDED_PARENT_ASSET_SET_TYPE (17): + The asset set type is invalid for setting the + excluded_parent_asset_set_types field. + CANNOT_ADD_AD_GROUP_FOR_CAMPAIGN_TYPE (18): + Cannot add ad groups for the campaign type. + INVALID_STATUS (19): + Invalid status for the ad group. + INVALID_STEP_ID_FOR_VIDEO_ADS_SEQUENCING (20): + For video ads sequencing, AdGroup ``step_id`` has to use a + ``step_id`` defined in + ``campaign.video_campaign_settings.video_ad_sequence``. + INVALID_AD_GROUP_TYPE_FOR_VIDEO_ADS_SEQUENCING (21): + For video ads sequencing, AdGroup type has to use a type + defined in + ``campaign.video_campaign_settings.video_ad_sequence``. + DUPLICATE_STEP_ID (22): + Only one AdGroup is allowed for each step ID + in video ads sequencing. + INVALID_VERTICAL_ADS_FORMAT_SETTING (23): + At least one Vertical Ads format must be + enabled for a campaign under Travel Ads in + Search Campaigns. + VERTICAL_ADS_FORMAT_SETTING_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_AI_MAX (24): + AI max setting must be enabled to enable + Vertical Ads formats for a campaign under Travel + Ads in Search Campaigns. + VERTICAL_ADS_FORMAT_SETTING_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_ENABLED_TRAVEL_FEED (25): + An enabled travel feed must be linked to + enable Vertical Ads formats for a campaign under + Travel Ads in Search Campaigns. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + DUPLICATE_ADGROUP_NAME = 2 + INVALID_ADGROUP_NAME = 3 + ADVERTISER_NOT_ON_CONTENT_NETWORK = 5 + BID_TOO_BIG = 6 + BID_TYPE_AND_BIDDING_STRATEGY_MISMATCH = 7 + MISSING_ADGROUP_NAME = 8 + ADGROUP_LABEL_DOES_NOT_EXIST = 9 + ADGROUP_LABEL_ALREADY_EXISTS = 10 + INVALID_CONTENT_BID_CRITERION_TYPE_GROUP = 11 + AD_GROUP_TYPE_NOT_VALID_FOR_ADVERTISING_CHANNEL_TYPE = 12 + ADGROUP_TYPE_NOT_SUPPORTED_FOR_CAMPAIGN_SALES_COUNTRY = 13 + CANNOT_ADD_ADGROUP_OF_TYPE_DSA_TO_CAMPAIGN_WITHOUT_DSA_SETTING = 14 + PROMOTED_HOTEL_AD_GROUPS_NOT_AVAILABLE_FOR_CUSTOMER = 15 + INVALID_EXCLUDED_PARENT_ASSET_FIELD_TYPE = 16 + INVALID_EXCLUDED_PARENT_ASSET_SET_TYPE = 17 + CANNOT_ADD_AD_GROUP_FOR_CAMPAIGN_TYPE = 18 + INVALID_STATUS = 19 + INVALID_STEP_ID_FOR_VIDEO_ADS_SEQUENCING = 20 + INVALID_AD_GROUP_TYPE_FOR_VIDEO_ADS_SEQUENCING = 21 + DUPLICATE_STEP_ID = 22 + INVALID_VERTICAL_ADS_FORMAT_SETTING = 23 + VERTICAL_ADS_FORMAT_SETTING_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_AI_MAX = ( + 24 + ) + VERTICAL_ADS_FORMAT_SETTING_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_ENABLED_TRAVEL_FEED = ( + 25 + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/ad_group_feed_error.py b/google/ads/googleads/v23/errors/types/ad_group_feed_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/ad_group_feed_error.py rename to google/ads/googleads/v23/errors/types/ad_group_feed_error.py index 0471b6869..c86e3591b 100644 --- a/google/ads/googleads/v19/errors/types/ad_group_feed_error.py +++ b/google/ads/googleads/v23/errors/types/ad_group_feed_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AdGroupFeedErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/ad_parameter_error.py b/google/ads/googleads/v23/errors/types/ad_parameter_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/ad_parameter_error.py rename to google/ads/googleads/v23/errors/types/ad_parameter_error.py index 0637785c1..a455094f7 100644 --- a/google/ads/googleads/v19/errors/types/ad_parameter_error.py +++ b/google/ads/googleads/v23/errors/types/ad_parameter_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AdParameterErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/ad_sharing_error.py b/google/ads/googleads/v23/errors/types/ad_sharing_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/ad_sharing_error.py rename to google/ads/googleads/v23/errors/types/ad_sharing_error.py index 2a421b917..695c17833 100644 --- a/google/ads/googleads/v19/errors/types/ad_sharing_error.py +++ b/google/ads/googleads/v23/errors/types/ad_sharing_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AdSharingErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/adx_error.py b/google/ads/googleads/v23/errors/types/adx_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/adx_error.py rename to google/ads/googleads/v23/errors/types/adx_error.py index bedfbe29f..f6db1b8e1 100644 --- a/google/ads/googleads/v19/errors/types/adx_error.py +++ b/google/ads/googleads/v23/errors/types/adx_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AdxErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/asset_error.py b/google/ads/googleads/v23/errors/types/asset_error.py similarity index 88% rename from google/ads/googleads/v19/errors/types/asset_error.py rename to google/ads/googleads/v23/errors/types/asset_error.py index bd0b1ca08..3dc198e6e 100644 --- a/google/ads/googleads/v19/errors/types/asset_error.py +++ b/google/ads/googleads/v23/errors/types/asset_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AssetErrorEnum", }, @@ -145,6 +145,21 @@ class AssetError(proto.Enum): CUSTOMER_NOT_ON_ALLOWLIST_FOR_APP_DEEP_LINK_ASSETS (40): Only customers on the allowlist can create AppDeepLinkAsset. + PROMOTION_BARCODE_CANNOT_CONTAIN_LINKS (41): + Promotion barcode cannot contain links. + PROMOTION_BARCODE_INVALID_FORMAT (42): + Failed to encode promotion barcode: Invalid + format. + UNSUPPORTED_BARCODE_TYPE (43): + Barcode type is not supported. + PROMOTION_QR_CODE_CANNOT_CONTAIN_LINKS (44): + Promotion QR code cannot contain links. + PROMOTION_QR_CODE_INVALID_FORMAT (45): + Failed to encode promotion QR code: Invalid + format. + CUSTOMER_NOT_ON_ALLOWLIST_FOR_MESSAGE_ASSETS (46): + The customer is not in the allow-list for + Business message asset type. """ UNSPECIFIED = 0 @@ -187,6 +202,12 @@ class AssetError(proto.Enum): PAGE_FEED_INVALID_LABEL_TEXT = 38 CUSTOMER_NOT_ON_ALLOWLIST_FOR_WHATSAPP_MESSAGE_ASSETS = 39 CUSTOMER_NOT_ON_ALLOWLIST_FOR_APP_DEEP_LINK_ASSETS = 40 + PROMOTION_BARCODE_CANNOT_CONTAIN_LINKS = 41 + PROMOTION_BARCODE_INVALID_FORMAT = 42 + UNSUPPORTED_BARCODE_TYPE = 43 + PROMOTION_QR_CODE_CANNOT_CONTAIN_LINKS = 44 + PROMOTION_QR_CODE_INVALID_FORMAT = 45 + CUSTOMER_NOT_ON_ALLOWLIST_FOR_MESSAGE_ASSETS = 46 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/errors/types/asset_generation_error.py b/google/ads/googleads/v23/errors/types/asset_generation_error.py new file mode 100644 index 000000000..9eabb34a5 --- /dev/null +++ b/google/ads/googleads/v23/errors/types/asset_generation_error.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", + manifest={ + "AssetGenerationErrorEnum", + }, +) + + +class AssetGenerationErrorEnum(proto.Message): + r"""Container for enum describing GenAI asset generation errors.""" + + class AssetGenerationError(proto.Enum): + r"""Enum describing GenAI asset generation errors. + + Values: + UNSPECIFIED (0): + Enum unspecified. + UNKNOWN (1): + The received error code is not known in this + version. + NO_ASSETS_GENERATED (2): + No assets were generated for the given + request. + FINAL_URL_REQUIRED (3): + A final URL is required but was not provided, + and could not be sourced from the existing + generation context because no existing + generation context was provided. + GENERATION_CONTEXT_MISSING_FINAL_URL (4): + A final URL is required but was not provided, + and could not be sourced from the provided + existing generation context. + FINAL_URL_SENSITIVE (5): + The provided final URL is considered + sensitive, and assets cannot be generated. + FINAL_URL_UNSUPPORTED_LANGUAGE (6): + The language of the provided final URL is not + supported. + FINAL_URL_UNAVAILABLE (7): + The provided final URL was not indexed or + could otherwise not be processed. + CAMPAIGN_TYPE_REQUIRED (8): + Campaign type is required but was not + provided, and could not be sourced from the + existing generation context because no existing + generation context was provided. + UNSUPPORTED_CAMPAIGN_TYPE (9): + The provided campaign type is not supported + for this asset generation operation. + UNSUPPORTED_FIELD_TYPE (10): + The provided field type is not supported for + this asset generation operation. + UNSUPPORTED_FIELD_TYPE_FOR_CAMPAIGN_TYPE (11): + The provided field type is not supported for + the given campaign type. + FREEFORM_PROMPT_UNSUPPORTED_LANGUAGE (12): + The language of the provided freeform prompt + is not supported. + FREEFORM_PROMPT_SENSITIVE (13): + The provided freeform prompt is considered + sensitive, and assets cannot be generated. + INPUT_IMAGE_FILE_SIZE_TOO_LARGE (14): + The provided image file size exceeds the + limit. + INPUT_IMAGE_EMPTY (15): + The provided image is empty. + GENERATION_TYPE_REQUIRED (16): + Exactly one generation type must be provided. + TOO_MANY_KEYWORDS (17): + Too many keywords provided in request. + KEYWORD_INVALID_LENGTH (18): + A provided keyword does not have a valid + length. + NO_VALID_KEYWORDS (19): + All keywords were filtered out. + FREEFORM_PROMPT_INVALID_LENGTH (20): + The provided freeform prompt does not have a + valid length. + FREEFORM_PROMPT_REFERENCES_CHILDREN (21): + The provided freeform prompt references + children. + FREEFORM_PROMPT_REFERENCES_SPECIFIC_PEOPLE (22): + The provided freeform prompt references + specific people. + FREEFORM_PROMPT_VIOLATES_ADS_POLICY (23): + The provided freeform prompt violates Ads + Policy. + FREEFORM_PROMPT_BRAND_CONTENT (24): + The provided freeform prompt contains brand + content. + INPUT_IMAGE_DEPICTS_CHILDREN (25): + The provided image depicts children. + INPUT_IMAGE_CONTAINS_BRAND_CONTENT (26): + The provided image contains brand content. + INPUT_IMAGE_SENSITIVE (27): + The provided image contains sensitive subject + matter. + INPUT_IMAGE_VIOLATES_POLICY (28): + The provided image may violate Google Ads + policies. + ALL_OUTPUT_IMAGES_FILTERED_OUT_CHILDREN_DEPICTION (29): + All output images were filtered out because + they included depictions of children. + ALL_OUTPUT_IMAGES_FILTERED_OUT_SPECIFIC_PEOPLE (30): + All output images were filtered out because + they included depictions of specific people. + ALL_OUTPUT_IMAGES_FILTERED_OUT (31): + All output images were filtered out for a + reason not covered by a more specific error + code. + INPUT_IMAGE_REQUIRED (32): + At least one input image is required for + certain requests. + INPUT_IMAGE_UNSUPPORTED_IMAGE_TYPE (33): + The provided image is of an unsupported type. + CONTEXT_ASSET_GROUP_NOT_FOUND (34): + Asset Group could not be found with the + provided ID. + CONTEXT_AD_GROUP_AD_NOT_FOUND (35): + Ad Group Ad could not be found with the + provided ID combination. + CONTEXT_CAMPAIGN_NOT_FOUND (36): + Could not find Campaign associated with the + provided generation context. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + NO_ASSETS_GENERATED = 2 + FINAL_URL_REQUIRED = 3 + GENERATION_CONTEXT_MISSING_FINAL_URL = 4 + FINAL_URL_SENSITIVE = 5 + FINAL_URL_UNSUPPORTED_LANGUAGE = 6 + FINAL_URL_UNAVAILABLE = 7 + CAMPAIGN_TYPE_REQUIRED = 8 + UNSUPPORTED_CAMPAIGN_TYPE = 9 + UNSUPPORTED_FIELD_TYPE = 10 + UNSUPPORTED_FIELD_TYPE_FOR_CAMPAIGN_TYPE = 11 + FREEFORM_PROMPT_UNSUPPORTED_LANGUAGE = 12 + FREEFORM_PROMPT_SENSITIVE = 13 + INPUT_IMAGE_FILE_SIZE_TOO_LARGE = 14 + INPUT_IMAGE_EMPTY = 15 + GENERATION_TYPE_REQUIRED = 16 + TOO_MANY_KEYWORDS = 17 + KEYWORD_INVALID_LENGTH = 18 + NO_VALID_KEYWORDS = 19 + FREEFORM_PROMPT_INVALID_LENGTH = 20 + FREEFORM_PROMPT_REFERENCES_CHILDREN = 21 + FREEFORM_PROMPT_REFERENCES_SPECIFIC_PEOPLE = 22 + FREEFORM_PROMPT_VIOLATES_ADS_POLICY = 23 + FREEFORM_PROMPT_BRAND_CONTENT = 24 + INPUT_IMAGE_DEPICTS_CHILDREN = 25 + INPUT_IMAGE_CONTAINS_BRAND_CONTENT = 26 + INPUT_IMAGE_SENSITIVE = 27 + INPUT_IMAGE_VIOLATES_POLICY = 28 + ALL_OUTPUT_IMAGES_FILTERED_OUT_CHILDREN_DEPICTION = 29 + ALL_OUTPUT_IMAGES_FILTERED_OUT_SPECIFIC_PEOPLE = 30 + ALL_OUTPUT_IMAGES_FILTERED_OUT = 31 + INPUT_IMAGE_REQUIRED = 32 + INPUT_IMAGE_UNSUPPORTED_IMAGE_TYPE = 33 + CONTEXT_ASSET_GROUP_NOT_FOUND = 34 + CONTEXT_AD_GROUP_AD_NOT_FOUND = 35 + CONTEXT_CAMPAIGN_NOT_FOUND = 36 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/asset_group_asset_error.py b/google/ads/googleads/v23/errors/types/asset_group_asset_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/asset_group_asset_error.py rename to google/ads/googleads/v23/errors/types/asset_group_asset_error.py index 7b4811cd1..e5741b0cd 100644 --- a/google/ads/googleads/v19/errors/types/asset_group_asset_error.py +++ b/google/ads/googleads/v23/errors/types/asset_group_asset_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupAssetErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/asset_group_error.py b/google/ads/googleads/v23/errors/types/asset_group_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/asset_group_error.py rename to google/ads/googleads/v23/errors/types/asset_group_error.py index 39b0bad90..a683629b2 100644 --- a/google/ads/googleads/v19/errors/types/asset_group_error.py +++ b/google/ads/googleads/v23/errors/types/asset_group_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/asset_group_listing_group_filter_error.py b/google/ads/googleads/v23/errors/types/asset_group_listing_group_filter_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/asset_group_listing_group_filter_error.py rename to google/ads/googleads/v23/errors/types/asset_group_listing_group_filter_error.py index 8e11fa662..401257a76 100644 --- a/google/ads/googleads/v19/errors/types/asset_group_listing_group_filter_error.py +++ b/google/ads/googleads/v23/errors/types/asset_group_listing_group_filter_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupListingGroupFilterErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/asset_group_signal_error.py b/google/ads/googleads/v23/errors/types/asset_group_signal_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/asset_group_signal_error.py rename to google/ads/googleads/v23/errors/types/asset_group_signal_error.py index d33fa1128..774ce3e5d 100644 --- a/google/ads/googleads/v19/errors/types/asset_group_signal_error.py +++ b/google/ads/googleads/v23/errors/types/asset_group_signal_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupSignalErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/asset_link_error.py b/google/ads/googleads/v23/errors/types/asset_link_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/asset_link_error.py rename to google/ads/googleads/v23/errors/types/asset_link_error.py index 24a4631c4..e2a524582 100644 --- a/google/ads/googleads/v19/errors/types/asset_link_error.py +++ b/google/ads/googleads/v23/errors/types/asset_link_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AssetLinkErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/asset_set_asset_error.py b/google/ads/googleads/v23/errors/types/asset_set_asset_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/asset_set_asset_error.py rename to google/ads/googleads/v23/errors/types/asset_set_asset_error.py index ad5bbab38..bcfdd5807 100644 --- a/google/ads/googleads/v19/errors/types/asset_set_asset_error.py +++ b/google/ads/googleads/v23/errors/types/asset_set_asset_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AssetSetAssetErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/asset_set_error.py b/google/ads/googleads/v23/errors/types/asset_set_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/asset_set_error.py rename to google/ads/googleads/v23/errors/types/asset_set_error.py index 4b689db08..d26e47c29 100644 --- a/google/ads/googleads/v19/errors/types/asset_set_error.py +++ b/google/ads/googleads/v23/errors/types/asset_set_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AssetSetErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/asset_set_link_error.py b/google/ads/googleads/v23/errors/types/asset_set_link_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/asset_set_link_error.py rename to google/ads/googleads/v23/errors/types/asset_set_link_error.py index 0c916c51c..9a4a71666 100644 --- a/google/ads/googleads/v19/errors/types/asset_set_link_error.py +++ b/google/ads/googleads/v23/errors/types/asset_set_link_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AssetSetLinkErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/audience_error.py b/google/ads/googleads/v23/errors/types/audience_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/audience_error.py rename to google/ads/googleads/v23/errors/types/audience_error.py index 176aaacd8..d17880129 100644 --- a/google/ads/googleads/v19/errors/types/audience_error.py +++ b/google/ads/googleads/v23/errors/types/audience_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AudienceErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/audience_insights_error.py b/google/ads/googleads/v23/errors/types/audience_insights_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/audience_insights_error.py rename to google/ads/googleads/v23/errors/types/audience_insights_error.py index da79431ef..6911c8b4e 100644 --- a/google/ads/googleads/v19/errors/types/audience_insights_error.py +++ b/google/ads/googleads/v23/errors/types/audience_insights_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AudienceInsightsErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/authentication_error.py b/google/ads/googleads/v23/errors/types/authentication_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/authentication_error.py rename to google/ads/googleads/v23/errors/types/authentication_error.py index 62dfec3c7..08c215e04 100644 --- a/google/ads/googleads/v19/errors/types/authentication_error.py +++ b/google/ads/googleads/v23/errors/types/authentication_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AuthenticationErrorEnum", }, @@ -77,6 +77,9 @@ class AuthenticationError(proto.Enum): OAuth token HTTP header is malformed. LOGIN_COOKIE_INVALID (20): Login cookie is not valid. + INVALID_EMAIL_ADDRESS (21): + The email address provided is invalid or does + not exist. USER_ID_INVALID (22): User ID in the header is not a valid ID. TWO_STEP_VERIFICATION_NOT_ENROLLED (23): @@ -122,6 +125,7 @@ class AuthenticationError(proto.Enum): OAUTH_TOKEN_REVOKED = 18 OAUTH_TOKEN_HEADER_INVALID = 19 LOGIN_COOKIE_INVALID = 20 + INVALID_EMAIL_ADDRESS = 21 USER_ID_INVALID = 22 TWO_STEP_VERIFICATION_NOT_ENROLLED = 23 ADVANCED_PROTECTION_NOT_ENROLLED = 24 diff --git a/google/ads/googleads/v19/errors/types/authorization_error.py b/google/ads/googleads/v23/errors/types/authorization_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/authorization_error.py rename to google/ads/googleads/v23/errors/types/authorization_error.py index 1ee5eeeb4..21a0709fb 100644 --- a/google/ads/googleads/v19/errors/types/authorization_error.py +++ b/google/ads/googleads/v23/errors/types/authorization_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AuthorizationErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/automatically_created_asset_removal_error.py b/google/ads/googleads/v23/errors/types/automatically_created_asset_removal_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/automatically_created_asset_removal_error.py rename to google/ads/googleads/v23/errors/types/automatically_created_asset_removal_error.py index fd1d7da77..6db9e1ae9 100644 --- a/google/ads/googleads/v19/errors/types/automatically_created_asset_removal_error.py +++ b/google/ads/googleads/v23/errors/types/automatically_created_asset_removal_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "AutomaticallyCreatedAssetRemovalErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/batch_job_error.py b/google/ads/googleads/v23/errors/types/batch_job_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/batch_job_error.py rename to google/ads/googleads/v23/errors/types/batch_job_error.py index 04e60e70f..8657bc383 100644 --- a/google/ads/googleads/v19/errors/types/batch_job_error.py +++ b/google/ads/googleads/v23/errors/types/batch_job_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "BatchJobErrorEnum", }, diff --git a/google/ads/googleads/v23/errors/types/benchmarks_error.py b/google/ads/googleads/v23/errors/types/benchmarks_error.py new file mode 100644 index 000000000..d32efa702 --- /dev/null +++ b/google/ads/googleads/v23/errors/types/benchmarks_error.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", + manifest={ + "BenchmarksErrorEnum", + }, +) + + +class BenchmarksErrorEnum(proto.Message): + r"""Container for enum describing possible errors returned from + the BenchmarksService. + + """ + + class BenchmarksError(proto.Enum): + r"""Enum describing possible errors from BenchmarksService. + + Values: + UNSPECIFIED (0): + Enum unspecified. + UNKNOWN (1): + The received error code is not known in this + version. + MAX_QUERY_COMPLEXITY_EXCEEDED (2): + The combination of inputs to generate + benchmarks is too complex. To reduce complexity, + try selecting a more granular benchmarks source, + a smaller date range, or a smaller set of + products. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + MAX_QUERY_COMPLEXITY_EXCEEDED = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/bidding_error.py b/google/ads/googleads/v23/errors/types/bidding_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/bidding_error.py rename to google/ads/googleads/v23/errors/types/bidding_error.py index de78b6577..965e22d00 100644 --- a/google/ads/googleads/v19/errors/types/bidding_error.py +++ b/google/ads/googleads/v23/errors/types/bidding_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "BiddingErrorEnum", }, @@ -110,6 +110,8 @@ class BiddingError(proto.Enum): be removed at the same time. CPC_BID_FLOOR_MICROS_GREATER_THAN_CPC_BID_CEILING_MICROS (41): cpc_bid_floor_micros is greater than cpc_bid_ceiling_micros. + TARGET_ROAS_TOLERANCE_PERCENT_MILLIS_MUST_BE_INTEGER (42): + target_roas_tolerance_percent_millis must be integer. """ UNSPECIFIED = 0 @@ -144,6 +146,7 @@ class BiddingError(proto.Enum): ) BIDDING_STRATEGY_AND_BUDGET_MUST_BE_REMOVED_TOGETHER = 40 CPC_BID_FLOOR_MICROS_GREATER_THAN_CPC_BID_CEILING_MICROS = 41 + TARGET_ROAS_TOLERANCE_PERCENT_MILLIS_MUST_BE_INTEGER = 42 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/bidding_strategy_error.py b/google/ads/googleads/v23/errors/types/bidding_strategy_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/bidding_strategy_error.py rename to google/ads/googleads/v23/errors/types/bidding_strategy_error.py index 49d4c6f0f..c93dfd725 100644 --- a/google/ads/googleads/v19/errors/types/bidding_strategy_error.py +++ b/google/ads/googleads/v23/errors/types/bidding_strategy_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "BiddingStrategyErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/billing_setup_error.py b/google/ads/googleads/v23/errors/types/billing_setup_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/billing_setup_error.py rename to google/ads/googleads/v23/errors/types/billing_setup_error.py index 500d5d72e..c2513b146 100644 --- a/google/ads/googleads/v19/errors/types/billing_setup_error.py +++ b/google/ads/googleads/v23/errors/types/billing_setup_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "BillingSetupErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/brand_guidelines_migration_error.py b/google/ads/googleads/v23/errors/types/brand_guidelines_migration_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/brand_guidelines_migration_error.py rename to google/ads/googleads/v23/errors/types/brand_guidelines_migration_error.py index cd414bf97..80aa79993 100644 --- a/google/ads/googleads/v19/errors/types/brand_guidelines_migration_error.py +++ b/google/ads/googleads/v23/errors/types/brand_guidelines_migration_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "BrandGuidelinesMigrationErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/campaign_budget_error.py b/google/ads/googleads/v23/errors/types/campaign_budget_error.py similarity index 92% rename from google/ads/googleads/v19/errors/types/campaign_budget_error.py rename to google/ads/googleads/v23/errors/types/campaign_budget_error.py index 04d2817fa..05ebe4e05 100644 --- a/google/ads/googleads/v19/errors/types/campaign_budget_error.py +++ b/google/ads/googleads/v23/errors/types/campaign_budget_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CampaignBudgetErrorEnum", }, @@ -99,6 +99,11 @@ class CampaignBudgetError(proto.Enum): BUDGET_AMOUNT_MUST_BE_UNSET_FOR_CUSTOM_BUDGET_PERIOD (21): Budget amount must be unset when BudgetPeriod is CUSTOM. + BUDGET_BELOW_PER_DAY_MINIMUM (22): + Budget amount or total amount must be above this campaign's + per-day minimum. See the error's + details.budget_per_day_minimum_error_details field for more + information. """ UNSPECIFIED = 0 @@ -124,6 +129,7 @@ class CampaignBudgetError(proto.Enum): INVALID_PERIOD = 19 CANNOT_USE_ACCELERATED_DELIVERY_MODE = 20 BUDGET_AMOUNT_MUST_BE_UNSET_FOR_CUSTOM_BUDGET_PERIOD = 21 + BUDGET_BELOW_PER_DAY_MINIMUM = 22 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/campaign_conversion_goal_error.py b/google/ads/googleads/v23/errors/types/campaign_conversion_goal_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/campaign_conversion_goal_error.py rename to google/ads/googleads/v23/errors/types/campaign_conversion_goal_error.py index 8e0f03bc5..b5af96426 100644 --- a/google/ads/googleads/v19/errors/types/campaign_conversion_goal_error.py +++ b/google/ads/googleads/v23/errors/types/campaign_conversion_goal_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CampaignConversionGoalErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/campaign_criterion_error.py b/google/ads/googleads/v23/errors/types/campaign_criterion_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/campaign_criterion_error.py rename to google/ads/googleads/v23/errors/types/campaign_criterion_error.py index 8b7525ed0..bd4a896fd 100644 --- a/google/ads/googleads/v19/errors/types/campaign_criterion_error.py +++ b/google/ads/googleads/v23/errors/types/campaign_criterion_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CampaignCriterionErrorEnum", }, @@ -130,6 +130,8 @@ class CampaignCriterionError(proto.Enum): countries and territories and the campaign has more top-level location exclusions than the limit allows, then this error is returned. + INVALID_VIDEO_LINEUP_ID (28): + Video lineup ID does not exist. """ UNSPECIFIED = 0 @@ -164,6 +166,7 @@ class CampaignCriterionError(proto.Enum): LOCAL_SERVICE_ID_NOT_FOUND_FOR_CATEGORY = 25 CANNOT_ATTACH_BRAND_LIST_TO_NON_QUALIFIED_SEARCH_CAMPAIGN = 26 CANNOT_REMOVE_ALL_LOCATIONS_DUE_TO_TOO_MANY_COUNTRY_EXCLUSIONS = 27 + INVALID_VIDEO_LINEUP_ID = 28 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/campaign_customizer_error.py b/google/ads/googleads/v23/errors/types/campaign_customizer_error.py similarity index 93% rename from google/ads/googleads/v19/errors/types/campaign_customizer_error.py rename to google/ads/googleads/v23/errors/types/campaign_customizer_error.py index 3b0138aa4..b22efcadc 100644 --- a/google/ads/googleads/v19/errors/types/campaign_customizer_error.py +++ b/google/ads/googleads/v23/errors/types/campaign_customizer_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CampaignCustomizerErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/campaign_draft_error.py b/google/ads/googleads/v23/errors/types/campaign_draft_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/campaign_draft_error.py rename to google/ads/googleads/v23/errors/types/campaign_draft_error.py index da025bea3..e6377af69 100644 --- a/google/ads/googleads/v19/errors/types/campaign_draft_error.py +++ b/google/ads/googleads/v23/errors/types/campaign_draft_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CampaignDraftErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/campaign_error.py b/google/ads/googleads/v23/errors/types/campaign_error.py similarity index 91% rename from google/ads/googleads/v19/errors/types/campaign_error.py rename to google/ads/googleads/v23/errors/types/campaign_error.py index 580d0d39f..3b6adf24c 100644 --- a/google/ads/googleads/v19/errors/types/campaign_error.py +++ b/google/ads/googleads/v23/errors/types/campaign_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CampaignErrorEnum", }, @@ -342,6 +342,32 @@ class CampaignError(proto.Enum): CUSTOMER_NOT_ALLOWLISTED_FOR_BRAND_GUIDELINES (104): This customer is not allowlisted for enabling Brand Guidelines. + THIRD_PARTY_INTEGRATION_PARTNER_NOT_ALLOWED (105): + Using campaign third-party integration + partners that are not set at the customer level + is not allowed. + THIRD_PARTY_INTEGRATION_PARTNER_SHARE_COST_NOT_ALLOWED (106): + Campaign third-party integration partners are + not allowed to share cost if it is not enabled + at the customer level. + DUPLICATE_INTERACTION_TYPE (107): + Each ``previous_step_interaction_type`` can be used at most + once for the same ``previous_step_id`` + INVALID_INTERACTION_TYPE (108): + Previous step interaction type cannot happen for previous + step AdGroup type. For example, ``SKIP`` interaction type is + not valid for non-skippable formats. + VIDEO_SEQUENCE_ERROR_SEQUENCE_DEFINITION_REQUIRED (109): + Campaign video ads sequence is required for + ``VIDEO_SEQUENCE`` advertising channel sub type. + AI_MAX_MUST_BE_ENABLED (110): + This feature is only available for campaigns + with AI Max enabled. + DURATION_TOO_LONG_FOR_TOTAL_BUDGET (111): + Duration too long for total budget. + END_DATE_TIME_REQUIRED_FOR_TOTAL_BUDGET (112): + Campaigns with total budgets must have end + date/time specified. """ UNSPECIFIED = 0 @@ -442,6 +468,14 @@ class CampaignError(proto.Enum): BRAND_GUIDELINES_UNSUPPORTED_CHANNEL = 102 CANNOT_ENABLE_BRAND_GUIDELINES_FOR_TRAVEL_GOALS = 103 CUSTOMER_NOT_ALLOWLISTED_FOR_BRAND_GUIDELINES = 104 + THIRD_PARTY_INTEGRATION_PARTNER_NOT_ALLOWED = 105 + THIRD_PARTY_INTEGRATION_PARTNER_SHARE_COST_NOT_ALLOWED = 106 + DUPLICATE_INTERACTION_TYPE = 107 + INVALID_INTERACTION_TYPE = 108 + VIDEO_SEQUENCE_ERROR_SEQUENCE_DEFINITION_REQUIRED = 109 + AI_MAX_MUST_BE_ENABLED = 110 + DURATION_TOO_LONG_FOR_TOTAL_BUDGET = 111 + END_DATE_TIME_REQUIRED_FOR_TOTAL_BUDGET = 112 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/campaign_experiment_error.py b/google/ads/googleads/v23/errors/types/campaign_experiment_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/campaign_experiment_error.py rename to google/ads/googleads/v23/errors/types/campaign_experiment_error.py index 993ca716b..f0ef7013e 100644 --- a/google/ads/googleads/v19/errors/types/campaign_experiment_error.py +++ b/google/ads/googleads/v23/errors/types/campaign_experiment_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CampaignExperimentErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/campaign_feed_error.py b/google/ads/googleads/v23/errors/types/campaign_feed_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/campaign_feed_error.py rename to google/ads/googleads/v23/errors/types/campaign_feed_error.py index aaeb9ebfc..80cad361e 100644 --- a/google/ads/googleads/v19/errors/types/campaign_feed_error.py +++ b/google/ads/googleads/v23/errors/types/campaign_feed_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CampaignFeedErrorEnum", }, diff --git a/google/ads/googleads/v23/errors/types/campaign_goal_config_error.py b/google/ads/googleads/v23/errors/types/campaign_goal_config_error.py new file mode 100644 index 000000000..28511a871 --- /dev/null +++ b/google/ads/googleads/v23/errors/types/campaign_goal_config_error.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", + manifest={ + "CampaignGoalConfigErrorEnum", + }, +) + + +class CampaignGoalConfigErrorEnum(proto.Message): + r"""Container for enum describing possible campaign goal config + errors. + + """ + + class CampaignGoalConfigError(proto.Enum): + r"""Enum describing possible campaign goal config errors. + + Values: + UNSPECIFIED (0): + Enum unspecified. + UNKNOWN (1): + The received error code is not known in this + version. + GOAL_NOT_FOUND (3): + Goal is either removed or does not exist for + this account. + CAMPAIGN_NOT_FOUND (4): + Campaign is either removed or does not exist. + HIGH_LIFETIME_VALUE_PRESENT_BUT_VALUE_ABSENT (9): + If high lifetime value is present then value + should be present. + HIGH_LIFETIME_VALUE_LESS_THAN_OR_EQUAL_TO_VALUE (10): + High lifetime value should be greater than + value. + CUSTOMER_LIFECYCLE_OPTIMIZATION_CAMPAIGN_TYPE_NOT_SUPPORTED (11): + When using customer lifecycle optimization + goal, campaign type should be supported. + CUSTOMER_NOT_ALLOWLISTED_FOR_RETENTION_ONLY (12): + Customer must be allowlisted to use retention + only goal. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + GOAL_NOT_FOUND = 3 + CAMPAIGN_NOT_FOUND = 4 + HIGH_LIFETIME_VALUE_PRESENT_BUT_VALUE_ABSENT = 9 + HIGH_LIFETIME_VALUE_LESS_THAN_OR_EQUAL_TO_VALUE = 10 + CUSTOMER_LIFECYCLE_OPTIMIZATION_CAMPAIGN_TYPE_NOT_SUPPORTED = 11 + CUSTOMER_NOT_ALLOWLISTED_FOR_RETENTION_ONLY = 12 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/campaign_lifecycle_goal_error.py b/google/ads/googleads/v23/errors/types/campaign_lifecycle_goal_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/campaign_lifecycle_goal_error.py rename to google/ads/googleads/v23/errors/types/campaign_lifecycle_goal_error.py index 6c44e4c0d..5df415aea 100644 --- a/google/ads/googleads/v19/errors/types/campaign_lifecycle_goal_error.py +++ b/google/ads/googleads/v23/errors/types/campaign_lifecycle_goal_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CampaignLifecycleGoalErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/campaign_shared_set_error.py b/google/ads/googleads/v23/errors/types/campaign_shared_set_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/campaign_shared_set_error.py rename to google/ads/googleads/v23/errors/types/campaign_shared_set_error.py index 5ba9a32fd..c3c739cfb 100644 --- a/google/ads/googleads/v19/errors/types/campaign_shared_set_error.py +++ b/google/ads/googleads/v23/errors/types/campaign_shared_set_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CampaignSharedSetErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/change_event_error.py b/google/ads/googleads/v23/errors/types/change_event_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/change_event_error.py rename to google/ads/googleads/v23/errors/types/change_event_error.py index 9459048ab..936083cea 100644 --- a/google/ads/googleads/v19/errors/types/change_event_error.py +++ b/google/ads/googleads/v23/errors/types/change_event_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ChangeEventErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/change_status_error.py b/google/ads/googleads/v23/errors/types/change_status_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/change_status_error.py rename to google/ads/googleads/v23/errors/types/change_status_error.py index 5697d11d4..a673b282c 100644 --- a/google/ads/googleads/v19/errors/types/change_status_error.py +++ b/google/ads/googleads/v23/errors/types/change_status_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ChangeStatusErrorEnum", }, diff --git a/google/ads/googleads/v23/errors/types/click_view_error.py b/google/ads/googleads/v23/errors/types/click_view_error.py new file mode 100644 index 000000000..b46f37564 --- /dev/null +++ b/google/ads/googleads/v23/errors/types/click_view_error.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", + manifest={ + "ClickViewErrorEnum", + }, +) + + +class ClickViewErrorEnum(proto.Message): + r"""Container for enum describing possible click view errors.""" + + class ClickViewError(proto.Enum): + r"""Enum describing possible click view errors. + + Values: + UNSPECIFIED (0): + Enum unspecified. + UNKNOWN (1): + The received error code is not known in this + version. + EXPECTED_FILTER_ON_A_SINGLE_DAY (2): + Missing filter on a single day. + DATE_TOO_OLD (3): + The requested date is too old. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + EXPECTED_FILTER_ON_A_SINGLE_DAY = 2 + DATE_TOO_OLD = 3 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/collection_size_error.py b/google/ads/googleads/v23/errors/types/collection_size_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/collection_size_error.py rename to google/ads/googleads/v23/errors/types/collection_size_error.py index 5e7f57c39..40604ce85 100644 --- a/google/ads/googleads/v19/errors/types/collection_size_error.py +++ b/google/ads/googleads/v23/errors/types/collection_size_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CollectionSizeErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/context_error.py b/google/ads/googleads/v23/errors/types/context_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/context_error.py rename to google/ads/googleads/v23/errors/types/context_error.py index 84a3a7618..f82dc3904 100644 --- a/google/ads/googleads/v19/errors/types/context_error.py +++ b/google/ads/googleads/v23/errors/types/context_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ContextErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/conversion_action_error.py b/google/ads/googleads/v23/errors/types/conversion_action_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/conversion_action_error.py rename to google/ads/googleads/v23/errors/types/conversion_action_error.py index 5fc2ac644..62f73ae8d 100644 --- a/google/ads/googleads/v19/errors/types/conversion_action_error.py +++ b/google/ads/googleads/v23/errors/types/conversion_action_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ConversionActionErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/conversion_adjustment_upload_error.py b/google/ads/googleads/v23/errors/types/conversion_adjustment_upload_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/conversion_adjustment_upload_error.py rename to google/ads/googleads/v23/errors/types/conversion_adjustment_upload_error.py index 88fbc6cb4..8e358088d 100644 --- a/google/ads/googleads/v19/errors/types/conversion_adjustment_upload_error.py +++ b/google/ads/googleads/v23/errors/types/conversion_adjustment_upload_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ConversionAdjustmentUploadErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/conversion_custom_variable_error.py b/google/ads/googleads/v23/errors/types/conversion_custom_variable_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/conversion_custom_variable_error.py rename to google/ads/googleads/v23/errors/types/conversion_custom_variable_error.py index debb21e69..26a161e3b 100644 --- a/google/ads/googleads/v19/errors/types/conversion_custom_variable_error.py +++ b/google/ads/googleads/v23/errors/types/conversion_custom_variable_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ConversionCustomVariableErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/conversion_goal_campaign_config_error.py b/google/ads/googleads/v23/errors/types/conversion_goal_campaign_config_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/conversion_goal_campaign_config_error.py rename to google/ads/googleads/v23/errors/types/conversion_goal_campaign_config_error.py index 41c2024e8..a5004a3b1 100644 --- a/google/ads/googleads/v19/errors/types/conversion_goal_campaign_config_error.py +++ b/google/ads/googleads/v23/errors/types/conversion_goal_campaign_config_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ConversionGoalCampaignConfigErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/conversion_upload_error.py b/google/ads/googleads/v23/errors/types/conversion_upload_error.py similarity index 99% rename from google/ads/googleads/v19/errors/types/conversion_upload_error.py rename to google/ads/googleads/v23/errors/types/conversion_upload_error.py index 70df02d70..f62c8a41e 100644 --- a/google/ads/googleads/v19/errors/types/conversion_upload_error.py +++ b/google/ads/googleads/v23/errors/types/conversion_upload_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ConversionUploadErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/conversion_value_rule_error.py b/google/ads/googleads/v23/errors/types/conversion_value_rule_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/conversion_value_rule_error.py rename to google/ads/googleads/v23/errors/types/conversion_value_rule_error.py index a65bf1e87..6dd0e743c 100644 --- a/google/ads/googleads/v19/errors/types/conversion_value_rule_error.py +++ b/google/ads/googleads/v23/errors/types/conversion_value_rule_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ConversionValueRuleErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/conversion_value_rule_set_error.py b/google/ads/googleads/v23/errors/types/conversion_value_rule_set_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/conversion_value_rule_set_error.py rename to google/ads/googleads/v23/errors/types/conversion_value_rule_set_error.py index e1ec2cc12..fe6af276e 100644 --- a/google/ads/googleads/v19/errors/types/conversion_value_rule_set_error.py +++ b/google/ads/googleads/v23/errors/types/conversion_value_rule_set_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ConversionValueRuleSetErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/country_code_error.py b/google/ads/googleads/v23/errors/types/country_code_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/country_code_error.py rename to google/ads/googleads/v23/errors/types/country_code_error.py index de05327e9..d22684a1f 100644 --- a/google/ads/googleads/v19/errors/types/country_code_error.py +++ b/google/ads/googleads/v23/errors/types/country_code_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CountryCodeErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/criterion_error.py b/google/ads/googleads/v23/errors/types/criterion_error.py similarity index 89% rename from google/ads/googleads/v19/errors/types/criterion_error.py rename to google/ads/googleads/v23/errors/types/criterion_error.py index 26bc8e9ec..bc551c938 100644 --- a/google/ads/googleads/v19/errors/types/criterion_error.py +++ b/google/ads/googleads/v23/errors/types/criterion_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CriterionErrorEnum", }, @@ -337,9 +337,15 @@ class CriterionError(proto.Enum): CANNOT_SET_BIDS_ON_LISTING_GROUP_SUBDIVISION (105): Listing group SUBDIVISION nodes cannot have bids. + LISTING_GROUP_ERROR_IN_ANOTHER_OPERATION (169): + Product group operation is invalid because + another operation targeting the same AdGroupId + is failing. INVALID_LISTING_GROUP_HIERARCHY (106): Ad group is invalid due to the listing groups it contains. + LISTING_GROUP_TREE_WAS_INVALID_BEFORE_MUTATION (170): + Tree was invalid before the mutation. LISTING_GROUP_UNIT_CANNOT_HAVE_CHILDREN (107): Listing group unit cannot have children. LISTING_GROUP_SUBDIVISION_REQUIRES_OTHERS_CASE (108): @@ -467,10 +473,50 @@ class CriterionError(proto.Enum): LOCATION_TARGETING_NOT_ELIGIBLE_FOR_RESTRICTED_CAMPAIGN (166): Cannot positively target locations outside of restricted area for campaign. + ONLY_INCLUSION_BRAND_LIST_ALLOWED_FOR_AD_GROUPS (171): + Ad group level brand list criteria only + support inclusionary targeting. Negative + targeting at this level is not supported. + CANNOT_ADD_REMOVED_PLACEMENT_LIST_SHARED_SET (172): + Cannot create a placement list with deleted + shared set. + PLACEMENT_LIST_SHARED_SET_DOES_NOT_EXIST (173): + The placement_list.shared_set_id references a shared set + that does not exist. + AI_MAX_MUST_BE_ENABLED (174): + This feature is only available for AI Max + campaigns. + NOT_AVAILABLE_FOR_AI_MAX_CAMPAIGNS (175): + This feature is not available for AI Max + campaigns. MISSING_EU_POLITICAL_ADVERTISING_SELF_DECLARATION (176): The operation failed because the campaign is missing the self-declaration on political advertising status in the EU. + INVALID_CAMPAIGN_TYPE_FOR_THIRD_PARTY_PARTNER_DATA_LIST (177): + Targeting this UserList is not allowed for + this campaign type. + CANNOT_ADD_USER_LIST_PENDING_PRIVACY_REVIEW (178): + The user list cannot be used while it is + pending privacy review. + VERTICAL_ADS_ITEM_GROUP_RULE_LIST_DOES_NOT_EXIST (179): + The referenced Vertical Ads item group rule + list shared set does not exist. + CANNOT_ADD_REMOVED_VERTICAL_ADS_ITEM_GROUP_RULE_LIST_SHARED_SET (180): + Cannot add Vertical Ads Item Group Rule List + with deleted shared set. + VERTICAL_ADS_ITEM_GROUP_RULE_LIST_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_ENABLED_TRAVEL_FEED (181): + Vertical Ads Item Group Rule List is not + supported for campaigns that do not have an + active travel feed. + VERTICAL_ADS_ITEM_GROUP_RULE_LIST_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_AI_MAX (182): + Vertical Ads Item Group Rule List is not + supported for campaigns that do not have AI max + enabled. + VERTICAL_ADS_ITEM_GROUP_RULE_NOT_SUPPORTED_FOR_THE_VERTICAL_TYPE (183): + The dimension of the Vertical Ads Item Group + Rule criterion is not supported for the shared + set vertical type. """ UNSPECIFIED = 0 @@ -583,7 +629,9 @@ class CriterionError(proto.Enum): DUPLICATE_LISTING_DIMENSION_TYPE = 103 DUPLICATE_LISTING_DIMENSION_VALUE = 104 CANNOT_SET_BIDS_ON_LISTING_GROUP_SUBDIVISION = 105 + LISTING_GROUP_ERROR_IN_ANOTHER_OPERATION = 169 INVALID_LISTING_GROUP_HIERARCHY = 106 + LISTING_GROUP_TREE_WAS_INVALID_BEFORE_MUTATION = 170 LISTING_GROUP_UNIT_CANNOT_HAVE_CHILDREN = 107 LISTING_GROUP_SUBDIVISION_REQUIRES_OTHERS_CASE = 108 LISTING_GROUP_REQUIRES_SAME_DIMENSION_TYPE_AS_SIBLINGS = 109 @@ -624,7 +672,23 @@ class CriterionError(proto.Enum): CANNOT_ADD_REMOVED_BRAND_SHARED_SET = 157 ONLY_EXCLUSION_BRAND_LIST_ALLOWED_FOR_CAMPAIGN_TYPE = 158 LOCATION_TARGETING_NOT_ELIGIBLE_FOR_RESTRICTED_CAMPAIGN = 166 + ONLY_INCLUSION_BRAND_LIST_ALLOWED_FOR_AD_GROUPS = 171 + CANNOT_ADD_REMOVED_PLACEMENT_LIST_SHARED_SET = 172 + PLACEMENT_LIST_SHARED_SET_DOES_NOT_EXIST = 173 + AI_MAX_MUST_BE_ENABLED = 174 + NOT_AVAILABLE_FOR_AI_MAX_CAMPAIGNS = 175 MISSING_EU_POLITICAL_ADVERTISING_SELF_DECLARATION = 176 + INVALID_CAMPAIGN_TYPE_FOR_THIRD_PARTY_PARTNER_DATA_LIST = 177 + CANNOT_ADD_USER_LIST_PENDING_PRIVACY_REVIEW = 178 + VERTICAL_ADS_ITEM_GROUP_RULE_LIST_DOES_NOT_EXIST = 179 + CANNOT_ADD_REMOVED_VERTICAL_ADS_ITEM_GROUP_RULE_LIST_SHARED_SET = 180 + VERTICAL_ADS_ITEM_GROUP_RULE_LIST_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_ENABLED_TRAVEL_FEED = ( + 181 + ) + VERTICAL_ADS_ITEM_GROUP_RULE_LIST_NOT_SUPPORTED_FOR_CAMPAIGNS_WITHOUT_AI_MAX = ( + 182 + ) + VERTICAL_ADS_ITEM_GROUP_RULE_NOT_SUPPORTED_FOR_THE_VERTICAL_TYPE = 183 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/currency_code_error.py b/google/ads/googleads/v23/errors/types/currency_code_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/currency_code_error.py rename to google/ads/googleads/v23/errors/types/currency_code_error.py index 098bf2d5b..2e0114829 100644 --- a/google/ads/googleads/v19/errors/types/currency_code_error.py +++ b/google/ads/googleads/v23/errors/types/currency_code_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CurrencyCodeErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/currency_error.py b/google/ads/googleads/v23/errors/types/currency_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/currency_error.py rename to google/ads/googleads/v23/errors/types/currency_error.py index 7b1dbe487..adad5a2ed 100644 --- a/google/ads/googleads/v19/errors/types/currency_error.py +++ b/google/ads/googleads/v23/errors/types/currency_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CurrencyErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/custom_audience_error.py b/google/ads/googleads/v23/errors/types/custom_audience_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/custom_audience_error.py rename to google/ads/googleads/v23/errors/types/custom_audience_error.py index 325b02456..2e31f2829 100644 --- a/google/ads/googleads/v19/errors/types/custom_audience_error.py +++ b/google/ads/googleads/v23/errors/types/custom_audience_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomAudienceErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/custom_conversion_goal_error.py b/google/ads/googleads/v23/errors/types/custom_conversion_goal_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/custom_conversion_goal_error.py rename to google/ads/googleads/v23/errors/types/custom_conversion_goal_error.py index 353aa8f56..41856d97c 100644 --- a/google/ads/googleads/v19/errors/types/custom_conversion_goal_error.py +++ b/google/ads/googleads/v23/errors/types/custom_conversion_goal_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomConversionGoalErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/custom_interest_error.py b/google/ads/googleads/v23/errors/types/custom_interest_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/custom_interest_error.py rename to google/ads/googleads/v23/errors/types/custom_interest_error.py index 4341ceb2a..aa8ab105c 100644 --- a/google/ads/googleads/v19/errors/types/custom_interest_error.py +++ b/google/ads/googleads/v23/errors/types/custom_interest_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomInterestErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/customer_client_link_error.py b/google/ads/googleads/v23/errors/types/customer_client_link_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/customer_client_link_error.py rename to google/ads/googleads/v23/errors/types/customer_client_link_error.py index 49e909a61..ba7229fa8 100644 --- a/google/ads/googleads/v19/errors/types/customer_client_link_error.py +++ b/google/ads/googleads/v23/errors/types/customer_client_link_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomerClientLinkErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/customer_customizer_error.py b/google/ads/googleads/v23/errors/types/customer_customizer_error.py similarity index 93% rename from google/ads/googleads/v19/errors/types/customer_customizer_error.py rename to google/ads/googleads/v23/errors/types/customer_customizer_error.py index e04e4551c..a86caedb7 100644 --- a/google/ads/googleads/v19/errors/types/customer_customizer_error.py +++ b/google/ads/googleads/v23/errors/types/customer_customizer_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomerCustomizerErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/customer_error.py b/google/ads/googleads/v23/errors/types/customer_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/customer_error.py rename to google/ads/googleads/v23/errors/types/customer_error.py index b7e460b5a..27a0ec2cb 100644 --- a/google/ads/googleads/v19/errors/types/customer_error.py +++ b/google/ads/googleads/v23/errors/types/customer_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomerErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/customer_feed_error.py b/google/ads/googleads/v23/errors/types/customer_feed_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/customer_feed_error.py rename to google/ads/googleads/v23/errors/types/customer_feed_error.py index d74f36bdd..75d5191e1 100644 --- a/google/ads/googleads/v19/errors/types/customer_feed_error.py +++ b/google/ads/googleads/v23/errors/types/customer_feed_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomerFeedErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/customer_lifecycle_goal_error.py b/google/ads/googleads/v23/errors/types/customer_lifecycle_goal_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/customer_lifecycle_goal_error.py rename to google/ads/googleads/v23/errors/types/customer_lifecycle_goal_error.py index 7db13e48a..bc46bdce0 100644 --- a/google/ads/googleads/v19/errors/types/customer_lifecycle_goal_error.py +++ b/google/ads/googleads/v23/errors/types/customer_lifecycle_goal_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomerLifecycleGoalErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/customer_manager_link_error.py b/google/ads/googleads/v23/errors/types/customer_manager_link_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/customer_manager_link_error.py rename to google/ads/googleads/v23/errors/types/customer_manager_link_error.py index d70ee3852..93fb5fffa 100644 --- a/google/ads/googleads/v19/errors/types/customer_manager_link_error.py +++ b/google/ads/googleads/v23/errors/types/customer_manager_link_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomerManagerLinkErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/customer_sk_ad_network_conversion_value_schema_error.py b/google/ads/googleads/v23/errors/types/customer_sk_ad_network_conversion_value_schema_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/customer_sk_ad_network_conversion_value_schema_error.py rename to google/ads/googleads/v23/errors/types/customer_sk_ad_network_conversion_value_schema_error.py index ddeb9ff58..1afefaf4b 100644 --- a/google/ads/googleads/v19/errors/types/customer_sk_ad_network_conversion_value_schema_error.py +++ b/google/ads/googleads/v23/errors/types/customer_sk_ad_network_conversion_value_schema_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomerSkAdNetworkConversionValueSchemaErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/customer_user_access_error.py b/google/ads/googleads/v23/errors/types/customer_user_access_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/customer_user_access_error.py rename to google/ads/googleads/v23/errors/types/customer_user_access_error.py index 858037046..4b8e61d71 100644 --- a/google/ads/googleads/v19/errors/types/customer_user_access_error.py +++ b/google/ads/googleads/v23/errors/types/customer_user_access_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomerUserAccessErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/customizer_attribute_error.py b/google/ads/googleads/v23/errors/types/customizer_attribute_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/customizer_attribute_error.py rename to google/ads/googleads/v23/errors/types/customizer_attribute_error.py index 35eb91480..e00dcd966 100644 --- a/google/ads/googleads/v19/errors/types/customizer_attribute_error.py +++ b/google/ads/googleads/v23/errors/types/customizer_attribute_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "CustomizerAttributeErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/data_link_error.py b/google/ads/googleads/v23/errors/types/data_link_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/data_link_error.py rename to google/ads/googleads/v23/errors/types/data_link_error.py index 8b8ccf98f..438f6a32e 100644 --- a/google/ads/googleads/v19/errors/types/data_link_error.py +++ b/google/ads/googleads/v23/errors/types/data_link_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "DataLinkErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/database_error.py b/google/ads/googleads/v23/errors/types/database_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/database_error.py rename to google/ads/googleads/v23/errors/types/database_error.py index 73e3fd1fd..3cb05f364 100644 --- a/google/ads/googleads/v19/errors/types/database_error.py +++ b/google/ads/googleads/v23/errors/types/database_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "DatabaseErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/date_error.py b/google/ads/googleads/v23/errors/types/date_error.py similarity index 82% rename from google/ads/googleads/v19/errors/types/date_error.py rename to google/ads/googleads/v23/errors/types/date_error.py index 36981fd44..1813bd1ce 100644 --- a/google/ads/googleads/v19/errors/types/date_error.py +++ b/google/ads/googleads/v23/errors/types/date_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "DateErrorEnum", }, @@ -57,7 +57,7 @@ class DateError(proto.Enum): yyyy-mm-dd hh:mm:ss. INVALID_STRING_DATE_TIME_SECONDS_WITH_OFFSET (12): The string date time's format should be yyyy-mm-dd - hh:mm:ss+|-hh:mm. + hh:mm:ss+\|-hh:mm. EARLIER_THAN_MINIMUM_DATE (7): Date is before allowed minimum. LATER_THAN_MAXIMUM_DATE (8): @@ -66,6 +66,12 @@ class DateError(proto.Enum): Date range bounds are not in order. DATE_RANGE_MINIMUM_AND_MAXIMUM_DATES_BOTH_NULL (10): Both dates in range are null. + DATE_RANGE_ERROR_START_TIME_MUST_BE_THE_START_OF_A_DAY (13): + This campaign type doesn't support a start + date time that isn't the start of the day. + DATE_RANGE_ERROR_END_TIME_MUST_BE_THE_END_OF_A_DAY (14): + This campaign type doesn't support an end + date time that isn't the end of the day. """ UNSPECIFIED = 0 @@ -80,6 +86,8 @@ class DateError(proto.Enum): LATER_THAN_MAXIMUM_DATE = 8 DATE_RANGE_MINIMUM_DATE_LATER_THAN_MAXIMUM_DATE = 9 DATE_RANGE_MINIMUM_AND_MAXIMUM_DATES_BOTH_NULL = 10 + DATE_RANGE_ERROR_START_TIME_MUST_BE_THE_START_OF_A_DAY = 13 + DATE_RANGE_ERROR_END_TIME_MUST_BE_THE_END_OF_A_DAY = 14 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/date_range_error.py b/google/ads/googleads/v23/errors/types/date_range_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/date_range_error.py rename to google/ads/googleads/v23/errors/types/date_range_error.py index bc00f84ff..dd7a69093 100644 --- a/google/ads/googleads/v19/errors/types/date_range_error.py +++ b/google/ads/googleads/v23/errors/types/date_range_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "DateRangeErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/distinct_error.py b/google/ads/googleads/v23/errors/types/distinct_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/distinct_error.py rename to google/ads/googleads/v23/errors/types/distinct_error.py index dcf26147a..17c8439f0 100644 --- a/google/ads/googleads/v19/errors/types/distinct_error.py +++ b/google/ads/googleads/v23/errors/types/distinct_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "DistinctErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/enum_error.py b/google/ads/googleads/v23/errors/types/enum_error.py similarity index 93% rename from google/ads/googleads/v19/errors/types/enum_error.py rename to google/ads/googleads/v23/errors/types/enum_error.py index d46e63e7b..ad26de303 100644 --- a/google/ads/googleads/v19/errors/types/enum_error.py +++ b/google/ads/googleads/v23/errors/types/enum_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "EnumErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/errors.py b/google/ads/googleads/v23/errors/types/errors.py similarity index 77% rename from google/ads/googleads/v19/errors/types/errors.py rename to google/ads/googleads/v23/errors/types/errors.py index 0f7cc9446..d816e92c8 100644 --- a/google/ads/googleads/v19/errors/types/errors.py +++ b/google/ads/googleads/v23/errors/types/errors.py @@ -19,475 +19,494 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import policy -from google.ads.googleads.v19.common.types import value -from google.ads.googleads.v19.enums.types import resource_limit_type -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.common.types import policy +from google.ads.googleads.v23.common.types import value +from google.ads.googleads.v23.enums.types import resource_limit_type +from google.ads.googleads.v23.errors.types import ( access_invitation_error as gage_access_invitation_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( account_budget_proposal_error as gage_account_budget_proposal_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( account_link_error as gage_account_link_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( ad_customizer_error as gage_ad_customizer_error, ) -from google.ads.googleads.v19.errors.types import ad_error as gage_ad_error -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ad_error as gage_ad_error +from google.ads.googleads.v23.errors.types import ( ad_group_ad_error as gage_ad_group_ad_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( ad_group_bid_modifier_error as gage_ad_group_bid_modifier_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( ad_group_criterion_customizer_error as gage_ad_group_criterion_customizer_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( ad_group_criterion_error as gage_ad_group_criterion_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( ad_group_customizer_error as gage_ad_group_customizer_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( ad_group_error as gage_ad_group_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( ad_group_feed_error as gage_ad_group_feed_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( ad_parameter_error as gage_ad_parameter_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( ad_sharing_error as gage_ad_sharing_error, ) -from google.ads.googleads.v19.errors.types import adx_error as gage_adx_error -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import adx_error as gage_adx_error +from google.ads.googleads.v23.errors.types import ( asset_error as gage_asset_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( + asset_generation_error as gage_asset_generation_error, +) +from google.ads.googleads.v23.errors.types import ( asset_group_asset_error as gage_asset_group_asset_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( asset_group_error as gage_asset_group_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( asset_group_listing_group_filter_error as gage_asset_group_listing_group_filter_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( asset_group_signal_error as gage_asset_group_signal_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( asset_link_error as gage_asset_link_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( asset_set_asset_error as gage_asset_set_asset_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( asset_set_error as gage_asset_set_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( asset_set_link_error as gage_asset_set_link_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( audience_error as gage_audience_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( audience_insights_error as gage_audience_insights_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( authentication_error as gage_authentication_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( authorization_error as gage_authorization_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( automatically_created_asset_removal_error as gage_automatically_created_asset_removal_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( batch_job_error as gage_batch_job_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( + benchmarks_error as gage_benchmarks_error, +) +from google.ads.googleads.v23.errors.types import ( bidding_error as gage_bidding_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( bidding_strategy_error as gage_bidding_strategy_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( billing_setup_error as gage_billing_setup_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( brand_guidelines_migration_error as gage_brand_guidelines_migration_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( campaign_budget_error as gage_campaign_budget_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( campaign_conversion_goal_error as gage_campaign_conversion_goal_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( campaign_criterion_error as gage_campaign_criterion_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( campaign_customizer_error as gage_campaign_customizer_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( campaign_draft_error as gage_campaign_draft_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( campaign_error as gage_campaign_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( campaign_experiment_error as gage_campaign_experiment_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( campaign_feed_error as gage_campaign_feed_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( + campaign_goal_config_error as gage_campaign_goal_config_error, +) +from google.ads.googleads.v23.errors.types import ( campaign_lifecycle_goal_error as gage_campaign_lifecycle_goal_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( campaign_shared_set_error as gage_campaign_shared_set_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( change_event_error as gage_change_event_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( change_status_error as gage_change_status_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( + click_view_error as gage_click_view_error, +) +from google.ads.googleads.v23.errors.types import ( collection_size_error as gage_collection_size_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( context_error as gage_context_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( conversion_action_error as gage_conversion_action_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( conversion_adjustment_upload_error as gage_conversion_adjustment_upload_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( conversion_custom_variable_error as gage_conversion_custom_variable_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( conversion_goal_campaign_config_error as gage_conversion_goal_campaign_config_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( conversion_upload_error as gage_conversion_upload_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( conversion_value_rule_error as gage_conversion_value_rule_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( conversion_value_rule_set_error as gage_conversion_value_rule_set_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( country_code_error as gage_country_code_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( criterion_error as gage_criterion_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( currency_code_error as gage_currency_code_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( currency_error as gage_currency_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( custom_audience_error as gage_custom_audience_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( custom_conversion_goal_error as gage_custom_conversion_goal_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( custom_interest_error as gage_custom_interest_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( customer_client_link_error as gage_customer_client_link_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( customer_customizer_error as gage_customer_customizer_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( customer_error as gage_customer_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( customer_feed_error as gage_customer_feed_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( customer_lifecycle_goal_error as gage_customer_lifecycle_goal_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( customer_manager_link_error as gage_customer_manager_link_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( customer_sk_ad_network_conversion_value_schema_error as gage_customer_sk_ad_network_conversion_value_schema_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( customer_user_access_error as gage_customer_user_access_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( customizer_attribute_error as gage_customizer_attribute_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( data_link_error as gage_data_link_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( database_error as gage_database_error, ) -from google.ads.googleads.v19.errors.types import date_error as gage_date_error -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import date_error as gage_date_error +from google.ads.googleads.v23.errors.types import ( date_range_error as gage_date_range_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( distinct_error as gage_distinct_error, ) -from google.ads.googleads.v19.errors.types import enum_error as gage_enum_error -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import enum_error as gage_enum_error +from google.ads.googleads.v23.errors.types import ( experiment_arm_error as gage_experiment_arm_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( experiment_error as gage_experiment_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( extension_feed_item_error as gage_extension_feed_item_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( extension_setting_error as gage_extension_setting_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( feed_attribute_reference_error as gage_feed_attribute_reference_error, ) -from google.ads.googleads.v19.errors.types import feed_error as gage_feed_error -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import feed_error as gage_feed_error +from google.ads.googleads.v23.errors.types import ( feed_item_error as gage_feed_item_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( feed_item_set_error as gage_feed_item_set_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( feed_item_set_link_error as gage_feed_item_set_link_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( feed_item_target_error as gage_feed_item_target_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( feed_item_validation_error as gage_feed_item_validation_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( feed_mapping_error as gage_feed_mapping_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( field_error as gage_field_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( field_mask_error as gage_field_mask_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( + final_url_expansion_asset_view_error as gage_final_url_expansion_asset_view_error, +) +from google.ads.googleads.v23.errors.types import ( function_error as gage_function_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( function_parsing_error as gage_function_parsing_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( geo_target_constant_suggestion_error as gage_geo_target_constant_suggestion_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import goal_error as gage_goal_error +from google.ads.googleads.v23.errors.types import ( header_error as gage_header_error, ) -from google.ads.googleads.v19.errors.types import id_error as gage_id_error -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import id_error as gage_id_error +from google.ads.googleads.v23.errors.types import ( identity_verification_error as gage_identity_verification_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( image_error as gage_image_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( + incentive_error as gage_incentive_error, +) +from google.ads.googleads.v23.errors.types import ( internal_error as gage_internal_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( invoice_error as gage_invoice_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( keyword_plan_ad_group_error as gage_keyword_plan_ad_group_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( keyword_plan_ad_group_keyword_error as gage_keyword_plan_ad_group_keyword_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( keyword_plan_campaign_error as gage_keyword_plan_campaign_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( keyword_plan_campaign_keyword_error as gage_keyword_plan_campaign_keyword_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( keyword_plan_error as gage_keyword_plan_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( keyword_plan_idea_error as gage_keyword_plan_idea_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( label_error as gage_label_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( language_code_error as gage_language_code_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( list_operation_error as gage_list_operation_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( manager_link_error as gage_manager_link_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( media_bundle_error as gage_media_bundle_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( media_file_error as gage_media_file_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( media_upload_error as gage_media_upload_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( merchant_center_error as gage_merchant_center_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( multiplier_error as gage_multiplier_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( mutate_error as gage_mutate_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( new_resource_creation_error as gage_new_resource_creation_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( not_allowlisted_error as gage_not_allowlisted_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( not_empty_error as gage_not_empty_error, ) -from google.ads.googleads.v19.errors.types import null_error as gage_null_error -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import null_error as gage_null_error +from google.ads.googleads.v23.errors.types import ( offline_user_data_job_error as gage_offline_user_data_job_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( operation_access_denied_error as gage_operation_access_denied_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( operator_error as gage_operator_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( partial_failure_error as gage_partial_failure_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( payments_account_error as gage_payments_account_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( policy_finding_error as gage_policy_finding_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( policy_validation_parameter_error as gage_policy_validation_parameter_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( policy_violation_error as gage_policy_violation_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( product_link_error as gage_product_link_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( product_link_invitation_error as gage_product_link_invitation_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( query_error as gage_query_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( quota_error as gage_quota_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( range_error as gage_range_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( reach_plan_error as gage_reach_plan_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( recommendation_error as gage_recommendation_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( recommendation_subscription_error as gage_recommendation_subscription_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( region_code_error as gage_region_code_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( request_error as gage_request_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( resource_access_denied_error as gage_resource_access_denied_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( resource_count_limit_exceeded_error as gage_resource_count_limit_exceeded_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( search_term_insight_error as gage_search_term_insight_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( setting_error as gage_setting_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( shareable_preview_error as gage_shareable_preview_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( shared_criterion_error as gage_shared_criterion_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( shared_set_error as gage_shared_set_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( shopping_product_error as gage_shopping_product_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( size_limit_error as gage_size_limit_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( smart_campaign_error as gage_smart_campaign_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( string_format_error as gage_string_format_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( string_length_error as gage_string_length_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( third_party_app_analytics_link_error as gage_third_party_app_analytics_link_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( time_zone_error as gage_time_zone_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( url_field_error as gage_url_field_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( user_data_error as gage_user_data_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( user_list_customer_type_error as gage_user_list_customer_type_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( user_list_error as gage_user_list_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( video_campaign_error as gage_video_campaign_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( youtube_video_registration_error as gage_youtube_video_registration_error, ) from google.protobuf import duration_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "GoogleAdsFailure", "GoogleAdsError", @@ -498,6 +517,7 @@ "PolicyFindingDetails", "QuotaErrorDetails", "ResourceCountDetails", + "BudgetPerDayMinimumErrorDetails", }, ) @@ -507,7 +527,7 @@ class GoogleAdsFailure(proto.Message): inside google.rpc.Status.details when a call fails. Attributes: - errors (MutableSequence[google.ads.googleads.v19.errors.types.GoogleAdsError]): + errors (MutableSequence[google.ads.googleads.v23.errors.types.GoogleAdsError]): The list of errors that occurred. request_id (str): The unique ID of the request that is used for @@ -529,17 +549,17 @@ class GoogleAdsError(proto.Message): r"""GoogleAds-specific error. Attributes: - error_code (google.ads.googleads.v19.errors.types.ErrorCode): + error_code (google.ads.googleads.v23.errors.types.ErrorCode): An enum value that indicates which error occurred. message (str): A human-readable description of the error. - trigger (google.ads.googleads.v19.common.types.Value): + trigger (google.ads.googleads.v23.common.types.Value): The value that triggered the error. - location (google.ads.googleads.v19.errors.types.ErrorLocation): + location (google.ads.googleads.v23.errors.types.ErrorLocation): Describes the part of the request proto that caused the error. - details (google.ads.googleads.v19.errors.types.ErrorDetails): + details (google.ads.googleads.v23.errors.types.ErrorDetails): Additional error details, which are returned by certain error codes. Most error codes do not include details. @@ -582,685 +602,716 @@ class ErrorCode(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - request_error (google.ads.googleads.v19.errors.types.RequestErrorEnum.RequestError): + request_error (google.ads.googleads.v23.errors.types.RequestErrorEnum.RequestError): An error caused by the request This field is a member of `oneof`_ ``error_code``. - bidding_strategy_error (google.ads.googleads.v19.errors.types.BiddingStrategyErrorEnum.BiddingStrategyError): + bidding_strategy_error (google.ads.googleads.v23.errors.types.BiddingStrategyErrorEnum.BiddingStrategyError): An error with a Bidding Strategy mutate. This field is a member of `oneof`_ ``error_code``. - url_field_error (google.ads.googleads.v19.errors.types.UrlFieldErrorEnum.UrlFieldError): + url_field_error (google.ads.googleads.v23.errors.types.UrlFieldErrorEnum.UrlFieldError): An error with a URL field mutate. This field is a member of `oneof`_ ``error_code``. - list_operation_error (google.ads.googleads.v19.errors.types.ListOperationErrorEnum.ListOperationError): + list_operation_error (google.ads.googleads.v23.errors.types.ListOperationErrorEnum.ListOperationError): An error with a list operation. This field is a member of `oneof`_ ``error_code``. - query_error (google.ads.googleads.v19.errors.types.QueryErrorEnum.QueryError): + query_error (google.ads.googleads.v23.errors.types.QueryErrorEnum.QueryError): An error with an AWQL query This field is a member of `oneof`_ ``error_code``. - mutate_error (google.ads.googleads.v19.errors.types.MutateErrorEnum.MutateError): + mutate_error (google.ads.googleads.v23.errors.types.MutateErrorEnum.MutateError): An error with a mutate This field is a member of `oneof`_ ``error_code``. - field_mask_error (google.ads.googleads.v19.errors.types.FieldMaskErrorEnum.FieldMaskError): + field_mask_error (google.ads.googleads.v23.errors.types.FieldMaskErrorEnum.FieldMaskError): An error with a field mask This field is a member of `oneof`_ ``error_code``. - authorization_error (google.ads.googleads.v19.errors.types.AuthorizationErrorEnum.AuthorizationError): + authorization_error (google.ads.googleads.v23.errors.types.AuthorizationErrorEnum.AuthorizationError): An error encountered when trying to authorize a user. This field is a member of `oneof`_ ``error_code``. - internal_error (google.ads.googleads.v19.errors.types.InternalErrorEnum.InternalError): + internal_error (google.ads.googleads.v23.errors.types.InternalErrorEnum.InternalError): An unexpected server-side error. This field is a member of `oneof`_ ``error_code``. - quota_error (google.ads.googleads.v19.errors.types.QuotaErrorEnum.QuotaError): + quota_error (google.ads.googleads.v23.errors.types.QuotaErrorEnum.QuotaError): An error with the amount of quota remaining. This field is a member of `oneof`_ ``error_code``. - ad_error (google.ads.googleads.v19.errors.types.AdErrorEnum.AdError): + ad_error (google.ads.googleads.v23.errors.types.AdErrorEnum.AdError): An error with an Ad Group Ad mutate. This field is a member of `oneof`_ ``error_code``. - ad_group_error (google.ads.googleads.v19.errors.types.AdGroupErrorEnum.AdGroupError): + ad_group_error (google.ads.googleads.v23.errors.types.AdGroupErrorEnum.AdGroupError): An error with an Ad Group mutate. This field is a member of `oneof`_ ``error_code``. - campaign_budget_error (google.ads.googleads.v19.errors.types.CampaignBudgetErrorEnum.CampaignBudgetError): + campaign_budget_error (google.ads.googleads.v23.errors.types.CampaignBudgetErrorEnum.CampaignBudgetError): An error with a Campaign Budget mutate. This field is a member of `oneof`_ ``error_code``. - campaign_error (google.ads.googleads.v19.errors.types.CampaignErrorEnum.CampaignError): + campaign_error (google.ads.googleads.v23.errors.types.CampaignErrorEnum.CampaignError): An error with a Campaign mutate. This field is a member of `oneof`_ ``error_code``. - video_campaign_error (google.ads.googleads.v19.errors.types.VideoCampaignErrorEnum.VideoCampaignError): + video_campaign_error (google.ads.googleads.v23.errors.types.VideoCampaignErrorEnum.VideoCampaignError): An error with a Video Campaign mutate. This field is a member of `oneof`_ ``error_code``. - authentication_error (google.ads.googleads.v19.errors.types.AuthenticationErrorEnum.AuthenticationError): + authentication_error (google.ads.googleads.v23.errors.types.AuthenticationErrorEnum.AuthenticationError): Indicates failure to properly authenticate user. This field is a member of `oneof`_ ``error_code``. - ad_group_criterion_customizer_error (google.ads.googleads.v19.errors.types.AdGroupCriterionCustomizerErrorEnum.AdGroupCriterionCustomizerError): + ad_group_criterion_customizer_error (google.ads.googleads.v23.errors.types.AdGroupCriterionCustomizerErrorEnum.AdGroupCriterionCustomizerError): The reasons for the ad group criterion customizer error. This field is a member of `oneof`_ ``error_code``. - ad_group_criterion_error (google.ads.googleads.v19.errors.types.AdGroupCriterionErrorEnum.AdGroupCriterionError): + ad_group_criterion_error (google.ads.googleads.v23.errors.types.AdGroupCriterionErrorEnum.AdGroupCriterionError): Indicates failure to properly authenticate user. This field is a member of `oneof`_ ``error_code``. - ad_group_customizer_error (google.ads.googleads.v19.errors.types.AdGroupCustomizerErrorEnum.AdGroupCustomizerError): + ad_group_customizer_error (google.ads.googleads.v23.errors.types.AdGroupCustomizerErrorEnum.AdGroupCustomizerError): The reasons for the ad group customizer error. This field is a member of `oneof`_ ``error_code``. - ad_customizer_error (google.ads.googleads.v19.errors.types.AdCustomizerErrorEnum.AdCustomizerError): + ad_customizer_error (google.ads.googleads.v23.errors.types.AdCustomizerErrorEnum.AdCustomizerError): The reasons for the ad customizer error This field is a member of `oneof`_ ``error_code``. - ad_group_ad_error (google.ads.googleads.v19.errors.types.AdGroupAdErrorEnum.AdGroupAdError): + ad_group_ad_error (google.ads.googleads.v23.errors.types.AdGroupAdErrorEnum.AdGroupAdError): The reasons for the ad group ad error This field is a member of `oneof`_ ``error_code``. - ad_sharing_error (google.ads.googleads.v19.errors.types.AdSharingErrorEnum.AdSharingError): + ad_sharing_error (google.ads.googleads.v23.errors.types.AdSharingErrorEnum.AdSharingError): The reasons for the ad sharing error This field is a member of `oneof`_ ``error_code``. - adx_error (google.ads.googleads.v19.errors.types.AdxErrorEnum.AdxError): + adx_error (google.ads.googleads.v23.errors.types.AdxErrorEnum.AdxError): The reasons for the adx error This field is a member of `oneof`_ ``error_code``. - asset_error (google.ads.googleads.v19.errors.types.AssetErrorEnum.AssetError): + asset_error (google.ads.googleads.v23.errors.types.AssetErrorEnum.AssetError): The reasons for the asset error This field is a member of `oneof`_ ``error_code``. - asset_group_asset_error (google.ads.googleads.v19.errors.types.AssetGroupAssetErrorEnum.AssetGroupAssetError): + asset_group_asset_error (google.ads.googleads.v23.errors.types.AssetGroupAssetErrorEnum.AssetGroupAssetError): The reasons for the asset group asset error This field is a member of `oneof`_ ``error_code``. - asset_group_listing_group_filter_error (google.ads.googleads.v19.errors.types.AssetGroupListingGroupFilterErrorEnum.AssetGroupListingGroupFilterError): + asset_group_listing_group_filter_error (google.ads.googleads.v23.errors.types.AssetGroupListingGroupFilterErrorEnum.AssetGroupListingGroupFilterError): The reasons for the asset group listing group filter error This field is a member of `oneof`_ ``error_code``. - asset_group_error (google.ads.googleads.v19.errors.types.AssetGroupErrorEnum.AssetGroupError): + asset_group_error (google.ads.googleads.v23.errors.types.AssetGroupErrorEnum.AssetGroupError): The reasons for the asset group error This field is a member of `oneof`_ ``error_code``. - asset_set_asset_error (google.ads.googleads.v19.errors.types.AssetSetAssetErrorEnum.AssetSetAssetError): + asset_set_asset_error (google.ads.googleads.v23.errors.types.AssetSetAssetErrorEnum.AssetSetAssetError): The reasons for the asset set asset error This field is a member of `oneof`_ ``error_code``. - asset_set_link_error (google.ads.googleads.v19.errors.types.AssetSetLinkErrorEnum.AssetSetLinkError): + asset_set_link_error (google.ads.googleads.v23.errors.types.AssetSetLinkErrorEnum.AssetSetLinkError): The reasons for the asset set link error This field is a member of `oneof`_ ``error_code``. - asset_set_error (google.ads.googleads.v19.errors.types.AssetSetErrorEnum.AssetSetError): + asset_set_error (google.ads.googleads.v23.errors.types.AssetSetErrorEnum.AssetSetError): The reasons for the asset set error This field is a member of `oneof`_ ``error_code``. - bidding_error (google.ads.googleads.v19.errors.types.BiddingErrorEnum.BiddingError): + bidding_error (google.ads.googleads.v23.errors.types.BiddingErrorEnum.BiddingError): The reasons for the bidding errors This field is a member of `oneof`_ ``error_code``. - campaign_criterion_error (google.ads.googleads.v19.errors.types.CampaignCriterionErrorEnum.CampaignCriterionError): + campaign_criterion_error (google.ads.googleads.v23.errors.types.CampaignCriterionErrorEnum.CampaignCriterionError): The reasons for the campaign criterion error This field is a member of `oneof`_ ``error_code``. - campaign_conversion_goal_error (google.ads.googleads.v19.errors.types.CampaignConversionGoalErrorEnum.CampaignConversionGoalError): + campaign_conversion_goal_error (google.ads.googleads.v23.errors.types.CampaignConversionGoalErrorEnum.CampaignConversionGoalError): The reasons for the campaign conversion goal error This field is a member of `oneof`_ ``error_code``. - campaign_customizer_error (google.ads.googleads.v19.errors.types.CampaignCustomizerErrorEnum.CampaignCustomizerError): + campaign_customizer_error (google.ads.googleads.v23.errors.types.CampaignCustomizerErrorEnum.CampaignCustomizerError): The reasons for the campaign customizer error. This field is a member of `oneof`_ ``error_code``. - collection_size_error (google.ads.googleads.v19.errors.types.CollectionSizeErrorEnum.CollectionSizeError): + collection_size_error (google.ads.googleads.v23.errors.types.CollectionSizeErrorEnum.CollectionSizeError): The reasons for the collection size error This field is a member of `oneof`_ ``error_code``. - conversion_goal_campaign_config_error (google.ads.googleads.v19.errors.types.ConversionGoalCampaignConfigErrorEnum.ConversionGoalCampaignConfigError): + conversion_goal_campaign_config_error (google.ads.googleads.v23.errors.types.ConversionGoalCampaignConfigErrorEnum.ConversionGoalCampaignConfigError): The reasons for the conversion goal campaign config error This field is a member of `oneof`_ ``error_code``. - country_code_error (google.ads.googleads.v19.errors.types.CountryCodeErrorEnum.CountryCodeError): + country_code_error (google.ads.googleads.v23.errors.types.CountryCodeErrorEnum.CountryCodeError): The reasons for the country code error This field is a member of `oneof`_ ``error_code``. - criterion_error (google.ads.googleads.v19.errors.types.CriterionErrorEnum.CriterionError): + criterion_error (google.ads.googleads.v23.errors.types.CriterionErrorEnum.CriterionError): The reasons for the criterion error This field is a member of `oneof`_ ``error_code``. - custom_conversion_goal_error (google.ads.googleads.v19.errors.types.CustomConversionGoalErrorEnum.CustomConversionGoalError): + custom_conversion_goal_error (google.ads.googleads.v23.errors.types.CustomConversionGoalErrorEnum.CustomConversionGoalError): The reasons for the custom conversion goal error This field is a member of `oneof`_ ``error_code``. - customer_customizer_error (google.ads.googleads.v19.errors.types.CustomerCustomizerErrorEnum.CustomerCustomizerError): + customer_customizer_error (google.ads.googleads.v23.errors.types.CustomerCustomizerErrorEnum.CustomerCustomizerError): The reasons for the customer customizer error. This field is a member of `oneof`_ ``error_code``. - customer_error (google.ads.googleads.v19.errors.types.CustomerErrorEnum.CustomerError): + customer_error (google.ads.googleads.v23.errors.types.CustomerErrorEnum.CustomerError): The reasons for the customer error This field is a member of `oneof`_ ``error_code``. - customizer_attribute_error (google.ads.googleads.v19.errors.types.CustomizerAttributeErrorEnum.CustomizerAttributeError): + customizer_attribute_error (google.ads.googleads.v23.errors.types.CustomizerAttributeErrorEnum.CustomizerAttributeError): The reasons for the customizer attribute error. This field is a member of `oneof`_ ``error_code``. - date_error (google.ads.googleads.v19.errors.types.DateErrorEnum.DateError): + date_error (google.ads.googleads.v23.errors.types.DateErrorEnum.DateError): The reasons for the date error This field is a member of `oneof`_ ``error_code``. - date_range_error (google.ads.googleads.v19.errors.types.DateRangeErrorEnum.DateRangeError): + date_range_error (google.ads.googleads.v23.errors.types.DateRangeErrorEnum.DateRangeError): The reasons for the date range error This field is a member of `oneof`_ ``error_code``. - distinct_error (google.ads.googleads.v19.errors.types.DistinctErrorEnum.DistinctError): + distinct_error (google.ads.googleads.v23.errors.types.DistinctErrorEnum.DistinctError): The reasons for the distinct error This field is a member of `oneof`_ ``error_code``. - feed_attribute_reference_error (google.ads.googleads.v19.errors.types.FeedAttributeReferenceErrorEnum.FeedAttributeReferenceError): + feed_attribute_reference_error (google.ads.googleads.v23.errors.types.FeedAttributeReferenceErrorEnum.FeedAttributeReferenceError): The reasons for the feed attribute reference error This field is a member of `oneof`_ ``error_code``. - function_error (google.ads.googleads.v19.errors.types.FunctionErrorEnum.FunctionError): + final_url_expansion_asset_view_error (google.ads.googleads.v23.errors.types.FinalUrlExpansionAssetViewErrorEnum.FinalUrlExpansionAssetViewError): + The reasons for the final url expansion asset + view error + + This field is a member of `oneof`_ ``error_code``. + function_error (google.ads.googleads.v23.errors.types.FunctionErrorEnum.FunctionError): The reasons for the function error This field is a member of `oneof`_ ``error_code``. - function_parsing_error (google.ads.googleads.v19.errors.types.FunctionParsingErrorEnum.FunctionParsingError): + function_parsing_error (google.ads.googleads.v23.errors.types.FunctionParsingErrorEnum.FunctionParsingError): The reasons for the function parsing error This field is a member of `oneof`_ ``error_code``. - id_error (google.ads.googleads.v19.errors.types.IdErrorEnum.IdError): + id_error (google.ads.googleads.v23.errors.types.IdErrorEnum.IdError): The reasons for the id error This field is a member of `oneof`_ ``error_code``. - image_error (google.ads.googleads.v19.errors.types.ImageErrorEnum.ImageError): + image_error (google.ads.googleads.v23.errors.types.ImageErrorEnum.ImageError): The reasons for the image error This field is a member of `oneof`_ ``error_code``. - language_code_error (google.ads.googleads.v19.errors.types.LanguageCodeErrorEnum.LanguageCodeError): + language_code_error (google.ads.googleads.v23.errors.types.LanguageCodeErrorEnum.LanguageCodeError): The reasons for the language code error This field is a member of `oneof`_ ``error_code``. - media_bundle_error (google.ads.googleads.v19.errors.types.MediaBundleErrorEnum.MediaBundleError): + media_bundle_error (google.ads.googleads.v23.errors.types.MediaBundleErrorEnum.MediaBundleError): The reasons for the media bundle error This field is a member of `oneof`_ ``error_code``. - media_upload_error (google.ads.googleads.v19.errors.types.MediaUploadErrorEnum.MediaUploadError): + media_upload_error (google.ads.googleads.v23.errors.types.MediaUploadErrorEnum.MediaUploadError): The reasons for media uploading errors. This field is a member of `oneof`_ ``error_code``. - media_file_error (google.ads.googleads.v19.errors.types.MediaFileErrorEnum.MediaFileError): + media_file_error (google.ads.googleads.v23.errors.types.MediaFileErrorEnum.MediaFileError): The reasons for the media file error This field is a member of `oneof`_ ``error_code``. - merchant_center_error (google.ads.googleads.v19.errors.types.MerchantCenterErrorEnum.MerchantCenterError): + merchant_center_error (google.ads.googleads.v23.errors.types.MerchantCenterErrorEnum.MerchantCenterError): Container for enum describing possible merchant center errors. This field is a member of `oneof`_ ``error_code``. - multiplier_error (google.ads.googleads.v19.errors.types.MultiplierErrorEnum.MultiplierError): + multiplier_error (google.ads.googleads.v23.errors.types.MultiplierErrorEnum.MultiplierError): The reasons for the multiplier error This field is a member of `oneof`_ ``error_code``. - new_resource_creation_error (google.ads.googleads.v19.errors.types.NewResourceCreationErrorEnum.NewResourceCreationError): + new_resource_creation_error (google.ads.googleads.v23.errors.types.NewResourceCreationErrorEnum.NewResourceCreationError): The reasons for the new resource creation error This field is a member of `oneof`_ ``error_code``. - not_empty_error (google.ads.googleads.v19.errors.types.NotEmptyErrorEnum.NotEmptyError): + not_empty_error (google.ads.googleads.v23.errors.types.NotEmptyErrorEnum.NotEmptyError): The reasons for the not empty error This field is a member of `oneof`_ ``error_code``. - null_error (google.ads.googleads.v19.errors.types.NullErrorEnum.NullError): + null_error (google.ads.googleads.v23.errors.types.NullErrorEnum.NullError): The reasons for the null error This field is a member of `oneof`_ ``error_code``. - operator_error (google.ads.googleads.v19.errors.types.OperatorErrorEnum.OperatorError): + operator_error (google.ads.googleads.v23.errors.types.OperatorErrorEnum.OperatorError): The reasons for the operator error This field is a member of `oneof`_ ``error_code``. - range_error (google.ads.googleads.v19.errors.types.RangeErrorEnum.RangeError): + range_error (google.ads.googleads.v23.errors.types.RangeErrorEnum.RangeError): The reasons for the range error This field is a member of `oneof`_ ``error_code``. - recommendation_error (google.ads.googleads.v19.errors.types.RecommendationErrorEnum.RecommendationError): + recommendation_error (google.ads.googleads.v23.errors.types.RecommendationErrorEnum.RecommendationError): The reasons for error in applying a recommendation This field is a member of `oneof`_ ``error_code``. - recommendation_subscription_error (google.ads.googleads.v19.errors.types.RecommendationSubscriptionErrorEnum.RecommendationSubscriptionError): + recommendation_subscription_error (google.ads.googleads.v23.errors.types.RecommendationSubscriptionErrorEnum.RecommendationSubscriptionError): The reasons for the recommendation subscription error. This field is a member of `oneof`_ ``error_code``. - region_code_error (google.ads.googleads.v19.errors.types.RegionCodeErrorEnum.RegionCodeError): + region_code_error (google.ads.googleads.v23.errors.types.RegionCodeErrorEnum.RegionCodeError): The reasons for the region code error This field is a member of `oneof`_ ``error_code``. - setting_error (google.ads.googleads.v19.errors.types.SettingErrorEnum.SettingError): + setting_error (google.ads.googleads.v23.errors.types.SettingErrorEnum.SettingError): The reasons for the setting error This field is a member of `oneof`_ ``error_code``. - string_format_error (google.ads.googleads.v19.errors.types.StringFormatErrorEnum.StringFormatError): + string_format_error (google.ads.googleads.v23.errors.types.StringFormatErrorEnum.StringFormatError): The reasons for the string format error This field is a member of `oneof`_ ``error_code``. - string_length_error (google.ads.googleads.v19.errors.types.StringLengthErrorEnum.StringLengthError): + string_length_error (google.ads.googleads.v23.errors.types.StringLengthErrorEnum.StringLengthError): The reasons for the string length error This field is a member of `oneof`_ ``error_code``. - operation_access_denied_error (google.ads.googleads.v19.errors.types.OperationAccessDeniedErrorEnum.OperationAccessDeniedError): + operation_access_denied_error (google.ads.googleads.v23.errors.types.OperationAccessDeniedErrorEnum.OperationAccessDeniedError): The reasons for the operation access denied error This field is a member of `oneof`_ ``error_code``. - resource_access_denied_error (google.ads.googleads.v19.errors.types.ResourceAccessDeniedErrorEnum.ResourceAccessDeniedError): + resource_access_denied_error (google.ads.googleads.v23.errors.types.ResourceAccessDeniedErrorEnum.ResourceAccessDeniedError): The reasons for the resource access denied error This field is a member of `oneof`_ ``error_code``. - resource_count_limit_exceeded_error (google.ads.googleads.v19.errors.types.ResourceCountLimitExceededErrorEnum.ResourceCountLimitExceededError): + resource_count_limit_exceeded_error (google.ads.googleads.v23.errors.types.ResourceCountLimitExceededErrorEnum.ResourceCountLimitExceededError): The reasons for the resource count limit exceeded error This field is a member of `oneof`_ ``error_code``. - youtube_video_registration_error (google.ads.googleads.v19.errors.types.YoutubeVideoRegistrationErrorEnum.YoutubeVideoRegistrationError): + youtube_video_registration_error (google.ads.googleads.v23.errors.types.YoutubeVideoRegistrationErrorEnum.YoutubeVideoRegistrationError): The reasons for YouTube video registration errors. This field is a member of `oneof`_ ``error_code``. - ad_group_bid_modifier_error (google.ads.googleads.v19.errors.types.AdGroupBidModifierErrorEnum.AdGroupBidModifierError): + ad_group_bid_modifier_error (google.ads.googleads.v23.errors.types.AdGroupBidModifierErrorEnum.AdGroupBidModifierError): The reasons for the ad group bid modifier error This field is a member of `oneof`_ ``error_code``. - context_error (google.ads.googleads.v19.errors.types.ContextErrorEnum.ContextError): + context_error (google.ads.googleads.v23.errors.types.ContextErrorEnum.ContextError): The reasons for the context error This field is a member of `oneof`_ ``error_code``. - field_error (google.ads.googleads.v19.errors.types.FieldErrorEnum.FieldError): + field_error (google.ads.googleads.v23.errors.types.FieldErrorEnum.FieldError): The reasons for the field error This field is a member of `oneof`_ ``error_code``. - shared_set_error (google.ads.googleads.v19.errors.types.SharedSetErrorEnum.SharedSetError): + shared_set_error (google.ads.googleads.v23.errors.types.SharedSetErrorEnum.SharedSetError): The reasons for the shared set error This field is a member of `oneof`_ ``error_code``. - shared_criterion_error (google.ads.googleads.v19.errors.types.SharedCriterionErrorEnum.SharedCriterionError): + shared_criterion_error (google.ads.googleads.v23.errors.types.SharedCriterionErrorEnum.SharedCriterionError): The reasons for the shared criterion error This field is a member of `oneof`_ ``error_code``. - campaign_shared_set_error (google.ads.googleads.v19.errors.types.CampaignSharedSetErrorEnum.CampaignSharedSetError): + campaign_shared_set_error (google.ads.googleads.v23.errors.types.CampaignSharedSetErrorEnum.CampaignSharedSetError): The reasons for the campaign shared set error This field is a member of `oneof`_ ``error_code``. - conversion_action_error (google.ads.googleads.v19.errors.types.ConversionActionErrorEnum.ConversionActionError): + conversion_action_error (google.ads.googleads.v23.errors.types.ConversionActionErrorEnum.ConversionActionError): The reasons for the conversion action error This field is a member of `oneof`_ ``error_code``. - conversion_adjustment_upload_error (google.ads.googleads.v19.errors.types.ConversionAdjustmentUploadErrorEnum.ConversionAdjustmentUploadError): + conversion_adjustment_upload_error (google.ads.googleads.v23.errors.types.ConversionAdjustmentUploadErrorEnum.ConversionAdjustmentUploadError): The reasons for the conversion adjustment upload error This field is a member of `oneof`_ ``error_code``. - conversion_custom_variable_error (google.ads.googleads.v19.errors.types.ConversionCustomVariableErrorEnum.ConversionCustomVariableError): + conversion_custom_variable_error (google.ads.googleads.v23.errors.types.ConversionCustomVariableErrorEnum.ConversionCustomVariableError): The reasons for the conversion custom variable error This field is a member of `oneof`_ ``error_code``. - conversion_upload_error (google.ads.googleads.v19.errors.types.ConversionUploadErrorEnum.ConversionUploadError): + conversion_upload_error (google.ads.googleads.v23.errors.types.ConversionUploadErrorEnum.ConversionUploadError): The reasons for the conversion upload error This field is a member of `oneof`_ ``error_code``. - conversion_value_rule_error (google.ads.googleads.v19.errors.types.ConversionValueRuleErrorEnum.ConversionValueRuleError): + conversion_value_rule_error (google.ads.googleads.v23.errors.types.ConversionValueRuleErrorEnum.ConversionValueRuleError): The reasons for the conversion value rule error This field is a member of `oneof`_ ``error_code``. - conversion_value_rule_set_error (google.ads.googleads.v19.errors.types.ConversionValueRuleSetErrorEnum.ConversionValueRuleSetError): + conversion_value_rule_set_error (google.ads.googleads.v23.errors.types.ConversionValueRuleSetErrorEnum.ConversionValueRuleSetError): The reasons for the conversion value rule set error This field is a member of `oneof`_ ``error_code``. - header_error (google.ads.googleads.v19.errors.types.HeaderErrorEnum.HeaderError): + header_error (google.ads.googleads.v23.errors.types.HeaderErrorEnum.HeaderError): The reasons for the header error. This field is a member of `oneof`_ ``error_code``. - database_error (google.ads.googleads.v19.errors.types.DatabaseErrorEnum.DatabaseError): + database_error (google.ads.googleads.v23.errors.types.DatabaseErrorEnum.DatabaseError): The reasons for the database error. This field is a member of `oneof`_ ``error_code``. - policy_finding_error (google.ads.googleads.v19.errors.types.PolicyFindingErrorEnum.PolicyFindingError): + policy_finding_error (google.ads.googleads.v23.errors.types.PolicyFindingErrorEnum.PolicyFindingError): The reasons for the policy finding error. This field is a member of `oneof`_ ``error_code``. - enum_error (google.ads.googleads.v19.errors.types.EnumErrorEnum.EnumError): + enum_error (google.ads.googleads.v23.errors.types.EnumErrorEnum.EnumError): The reason for enum error. This field is a member of `oneof`_ ``error_code``. - keyword_plan_error (google.ads.googleads.v19.errors.types.KeywordPlanErrorEnum.KeywordPlanError): + keyword_plan_error (google.ads.googleads.v23.errors.types.KeywordPlanErrorEnum.KeywordPlanError): The reason for keyword plan error. This field is a member of `oneof`_ ``error_code``. - keyword_plan_campaign_error (google.ads.googleads.v19.errors.types.KeywordPlanCampaignErrorEnum.KeywordPlanCampaignError): + keyword_plan_campaign_error (google.ads.googleads.v23.errors.types.KeywordPlanCampaignErrorEnum.KeywordPlanCampaignError): The reason for keyword plan campaign error. This field is a member of `oneof`_ ``error_code``. - keyword_plan_campaign_keyword_error (google.ads.googleads.v19.errors.types.KeywordPlanCampaignKeywordErrorEnum.KeywordPlanCampaignKeywordError): + keyword_plan_campaign_keyword_error (google.ads.googleads.v23.errors.types.KeywordPlanCampaignKeywordErrorEnum.KeywordPlanCampaignKeywordError): The reason for keyword plan campaign keyword error. This field is a member of `oneof`_ ``error_code``. - keyword_plan_ad_group_error (google.ads.googleads.v19.errors.types.KeywordPlanAdGroupErrorEnum.KeywordPlanAdGroupError): + keyword_plan_ad_group_error (google.ads.googleads.v23.errors.types.KeywordPlanAdGroupErrorEnum.KeywordPlanAdGroupError): The reason for keyword plan ad group error. This field is a member of `oneof`_ ``error_code``. - keyword_plan_ad_group_keyword_error (google.ads.googleads.v19.errors.types.KeywordPlanAdGroupKeywordErrorEnum.KeywordPlanAdGroupKeywordError): + keyword_plan_ad_group_keyword_error (google.ads.googleads.v23.errors.types.KeywordPlanAdGroupKeywordErrorEnum.KeywordPlanAdGroupKeywordError): The reason for keyword plan ad group keyword error. This field is a member of `oneof`_ ``error_code``. - keyword_plan_idea_error (google.ads.googleads.v19.errors.types.KeywordPlanIdeaErrorEnum.KeywordPlanIdeaError): + keyword_plan_idea_error (google.ads.googleads.v23.errors.types.KeywordPlanIdeaErrorEnum.KeywordPlanIdeaError): The reason for keyword idea error. This field is a member of `oneof`_ ``error_code``. - account_budget_proposal_error (google.ads.googleads.v19.errors.types.AccountBudgetProposalErrorEnum.AccountBudgetProposalError): + account_budget_proposal_error (google.ads.googleads.v23.errors.types.AccountBudgetProposalErrorEnum.AccountBudgetProposalError): The reasons for account budget proposal errors. This field is a member of `oneof`_ ``error_code``. - user_list_error (google.ads.googleads.v19.errors.types.UserListErrorEnum.UserListError): + user_list_error (google.ads.googleads.v23.errors.types.UserListErrorEnum.UserListError): The reasons for the user list error This field is a member of `oneof`_ ``error_code``. - change_event_error (google.ads.googleads.v19.errors.types.ChangeEventErrorEnum.ChangeEventError): + change_event_error (google.ads.googleads.v23.errors.types.ChangeEventErrorEnum.ChangeEventError): The reasons for the change event error This field is a member of `oneof`_ ``error_code``. - change_status_error (google.ads.googleads.v19.errors.types.ChangeStatusErrorEnum.ChangeStatusError): + change_status_error (google.ads.googleads.v23.errors.types.ChangeStatusErrorEnum.ChangeStatusError): The reasons for the change status error This field is a member of `oneof`_ ``error_code``. - feed_error (google.ads.googleads.v19.errors.types.FeedErrorEnum.FeedError): + feed_error (google.ads.googleads.v23.errors.types.FeedErrorEnum.FeedError): The reasons for the feed error This field is a member of `oneof`_ ``error_code``. - geo_target_constant_suggestion_error (google.ads.googleads.v19.errors.types.GeoTargetConstantSuggestionErrorEnum.GeoTargetConstantSuggestionError): + geo_target_constant_suggestion_error (google.ads.googleads.v23.errors.types.GeoTargetConstantSuggestionErrorEnum.GeoTargetConstantSuggestionError): The reasons for the geo target constant suggestion error. This field is a member of `oneof`_ ``error_code``. - campaign_draft_error (google.ads.googleads.v19.errors.types.CampaignDraftErrorEnum.CampaignDraftError): + campaign_draft_error (google.ads.googleads.v23.errors.types.CampaignDraftErrorEnum.CampaignDraftError): The reasons for the campaign draft error This field is a member of `oneof`_ ``error_code``. - feed_item_error (google.ads.googleads.v19.errors.types.FeedItemErrorEnum.FeedItemError): + feed_item_error (google.ads.googleads.v23.errors.types.FeedItemErrorEnum.FeedItemError): The reasons for the feed item error This field is a member of `oneof`_ ``error_code``. - label_error (google.ads.googleads.v19.errors.types.LabelErrorEnum.LabelError): + label_error (google.ads.googleads.v23.errors.types.LabelErrorEnum.LabelError): The reason for the label error. This field is a member of `oneof`_ ``error_code``. - billing_setup_error (google.ads.googleads.v19.errors.types.BillingSetupErrorEnum.BillingSetupError): + billing_setup_error (google.ads.googleads.v23.errors.types.BillingSetupErrorEnum.BillingSetupError): The reasons for the billing setup error This field is a member of `oneof`_ ``error_code``. - customer_client_link_error (google.ads.googleads.v19.errors.types.CustomerClientLinkErrorEnum.CustomerClientLinkError): + customer_client_link_error (google.ads.googleads.v23.errors.types.CustomerClientLinkErrorEnum.CustomerClientLinkError): The reasons for the customer client link error This field is a member of `oneof`_ ``error_code``. - customer_manager_link_error (google.ads.googleads.v19.errors.types.CustomerManagerLinkErrorEnum.CustomerManagerLinkError): + customer_manager_link_error (google.ads.googleads.v23.errors.types.CustomerManagerLinkErrorEnum.CustomerManagerLinkError): The reasons for the customer manager link error This field is a member of `oneof`_ ``error_code``. - feed_mapping_error (google.ads.googleads.v19.errors.types.FeedMappingErrorEnum.FeedMappingError): + feed_mapping_error (google.ads.googleads.v23.errors.types.FeedMappingErrorEnum.FeedMappingError): The reasons for the feed mapping error This field is a member of `oneof`_ ``error_code``. - customer_feed_error (google.ads.googleads.v19.errors.types.CustomerFeedErrorEnum.CustomerFeedError): + customer_feed_error (google.ads.googleads.v23.errors.types.CustomerFeedErrorEnum.CustomerFeedError): The reasons for the customer feed error This field is a member of `oneof`_ ``error_code``. - ad_group_feed_error (google.ads.googleads.v19.errors.types.AdGroupFeedErrorEnum.AdGroupFeedError): + ad_group_feed_error (google.ads.googleads.v23.errors.types.AdGroupFeedErrorEnum.AdGroupFeedError): The reasons for the ad group feed error This field is a member of `oneof`_ ``error_code``. - campaign_feed_error (google.ads.googleads.v19.errors.types.CampaignFeedErrorEnum.CampaignFeedError): + campaign_feed_error (google.ads.googleads.v23.errors.types.CampaignFeedErrorEnum.CampaignFeedError): The reasons for the campaign feed error This field is a member of `oneof`_ ``error_code``. - custom_interest_error (google.ads.googleads.v19.errors.types.CustomInterestErrorEnum.CustomInterestError): + custom_interest_error (google.ads.googleads.v23.errors.types.CustomInterestErrorEnum.CustomInterestError): The reasons for the custom interest error This field is a member of `oneof`_ ``error_code``. - campaign_experiment_error (google.ads.googleads.v19.errors.types.CampaignExperimentErrorEnum.CampaignExperimentError): + campaign_experiment_error (google.ads.googleads.v23.errors.types.CampaignExperimentErrorEnum.CampaignExperimentError): The reasons for the campaign experiment error This field is a member of `oneof`_ ``error_code``. - extension_feed_item_error (google.ads.googleads.v19.errors.types.ExtensionFeedItemErrorEnum.ExtensionFeedItemError): + extension_feed_item_error (google.ads.googleads.v23.errors.types.ExtensionFeedItemErrorEnum.ExtensionFeedItemError): The reasons for the extension feed item error This field is a member of `oneof`_ ``error_code``. - ad_parameter_error (google.ads.googleads.v19.errors.types.AdParameterErrorEnum.AdParameterError): + ad_parameter_error (google.ads.googleads.v23.errors.types.AdParameterErrorEnum.AdParameterError): The reasons for the ad parameter error This field is a member of `oneof`_ ``error_code``. - feed_item_validation_error (google.ads.googleads.v19.errors.types.FeedItemValidationErrorEnum.FeedItemValidationError): + feed_item_validation_error (google.ads.googleads.v23.errors.types.FeedItemValidationErrorEnum.FeedItemValidationError): The reasons for the feed item validation error This field is a member of `oneof`_ ``error_code``. - extension_setting_error (google.ads.googleads.v19.errors.types.ExtensionSettingErrorEnum.ExtensionSettingError): + extension_setting_error (google.ads.googleads.v23.errors.types.ExtensionSettingErrorEnum.ExtensionSettingError): The reasons for the extension setting error This field is a member of `oneof`_ ``error_code``. - feed_item_set_error (google.ads.googleads.v19.errors.types.FeedItemSetErrorEnum.FeedItemSetError): + feed_item_set_error (google.ads.googleads.v23.errors.types.FeedItemSetErrorEnum.FeedItemSetError): The reasons for the feed item set error This field is a member of `oneof`_ ``error_code``. - feed_item_set_link_error (google.ads.googleads.v19.errors.types.FeedItemSetLinkErrorEnum.FeedItemSetLinkError): + feed_item_set_link_error (google.ads.googleads.v23.errors.types.FeedItemSetLinkErrorEnum.FeedItemSetLinkError): The reasons for the feed item set link error This field is a member of `oneof`_ ``error_code``. - feed_item_target_error (google.ads.googleads.v19.errors.types.FeedItemTargetErrorEnum.FeedItemTargetError): + feed_item_target_error (google.ads.googleads.v23.errors.types.FeedItemTargetErrorEnum.FeedItemTargetError): The reasons for the feed item target error This field is a member of `oneof`_ ``error_code``. - policy_violation_error (google.ads.googleads.v19.errors.types.PolicyViolationErrorEnum.PolicyViolationError): + policy_violation_error (google.ads.googleads.v23.errors.types.PolicyViolationErrorEnum.PolicyViolationError): The reasons for the policy violation error This field is a member of `oneof`_ ``error_code``. - partial_failure_error (google.ads.googleads.v19.errors.types.PartialFailureErrorEnum.PartialFailureError): + partial_failure_error (google.ads.googleads.v23.errors.types.PartialFailureErrorEnum.PartialFailureError): The reasons for the mutate job error This field is a member of `oneof`_ ``error_code``. - policy_validation_parameter_error (google.ads.googleads.v19.errors.types.PolicyValidationParameterErrorEnum.PolicyValidationParameterError): + click_view_error (google.ads.googleads.v23.errors.types.ClickViewErrorEnum.ClickViewError): + The reasons for the click view error + + This field is a member of `oneof`_ ``error_code``. + policy_validation_parameter_error (google.ads.googleads.v23.errors.types.PolicyValidationParameterErrorEnum.PolicyValidationParameterError): The reasons for the policy validation parameter error This field is a member of `oneof`_ ``error_code``. - size_limit_error (google.ads.googleads.v19.errors.types.SizeLimitErrorEnum.SizeLimitError): + size_limit_error (google.ads.googleads.v23.errors.types.SizeLimitErrorEnum.SizeLimitError): The reasons for the size limit error This field is a member of `oneof`_ ``error_code``. - offline_user_data_job_error (google.ads.googleads.v19.errors.types.OfflineUserDataJobErrorEnum.OfflineUserDataJobError): + offline_user_data_job_error (google.ads.googleads.v23.errors.types.OfflineUserDataJobErrorEnum.OfflineUserDataJobError): The reasons for the offline user data job error. This field is a member of `oneof`_ ``error_code``. - not_allowlisted_error (google.ads.googleads.v19.errors.types.NotAllowlistedErrorEnum.NotAllowlistedError): + not_allowlisted_error (google.ads.googleads.v23.errors.types.NotAllowlistedErrorEnum.NotAllowlistedError): The reasons for the not allowlisted error This field is a member of `oneof`_ ``error_code``. - manager_link_error (google.ads.googleads.v19.errors.types.ManagerLinkErrorEnum.ManagerLinkError): + manager_link_error (google.ads.googleads.v23.errors.types.ManagerLinkErrorEnum.ManagerLinkError): The reasons for the manager link error This field is a member of `oneof`_ ``error_code``. - currency_code_error (google.ads.googleads.v19.errors.types.CurrencyCodeErrorEnum.CurrencyCodeError): + currency_code_error (google.ads.googleads.v23.errors.types.CurrencyCodeErrorEnum.CurrencyCodeError): The reasons for the currency code error This field is a member of `oneof`_ ``error_code``. - experiment_error (google.ads.googleads.v19.errors.types.ExperimentErrorEnum.ExperimentError): + experiment_error (google.ads.googleads.v23.errors.types.ExperimentErrorEnum.ExperimentError): The reasons for the experiment error This field is a member of `oneof`_ ``error_code``. - access_invitation_error (google.ads.googleads.v19.errors.types.AccessInvitationErrorEnum.AccessInvitationError): + access_invitation_error (google.ads.googleads.v23.errors.types.AccessInvitationErrorEnum.AccessInvitationError): The reasons for the access invitation error This field is a member of `oneof`_ ``error_code``. - reach_plan_error (google.ads.googleads.v19.errors.types.ReachPlanErrorEnum.ReachPlanError): + reach_plan_error (google.ads.googleads.v23.errors.types.ReachPlanErrorEnum.ReachPlanError): The reasons for the reach plan error This field is a member of `oneof`_ ``error_code``. - invoice_error (google.ads.googleads.v19.errors.types.InvoiceErrorEnum.InvoiceError): + invoice_error (google.ads.googleads.v23.errors.types.InvoiceErrorEnum.InvoiceError): The reasons for the invoice error This field is a member of `oneof`_ ``error_code``. - payments_account_error (google.ads.googleads.v19.errors.types.PaymentsAccountErrorEnum.PaymentsAccountError): + payments_account_error (google.ads.googleads.v23.errors.types.PaymentsAccountErrorEnum.PaymentsAccountError): The reasons for errors in payments accounts service This field is a member of `oneof`_ ``error_code``. - time_zone_error (google.ads.googleads.v19.errors.types.TimeZoneErrorEnum.TimeZoneError): + time_zone_error (google.ads.googleads.v23.errors.types.TimeZoneErrorEnum.TimeZoneError): The reasons for the time zone error This field is a member of `oneof`_ ``error_code``. - asset_link_error (google.ads.googleads.v19.errors.types.AssetLinkErrorEnum.AssetLinkError): + asset_link_error (google.ads.googleads.v23.errors.types.AssetLinkErrorEnum.AssetLinkError): The reasons for the asset link error This field is a member of `oneof`_ ``error_code``. - user_data_error (google.ads.googleads.v19.errors.types.UserDataErrorEnum.UserDataError): + user_data_error (google.ads.googleads.v23.errors.types.UserDataErrorEnum.UserDataError): The reasons for the user data error. This field is a member of `oneof`_ ``error_code``. - batch_job_error (google.ads.googleads.v19.errors.types.BatchJobErrorEnum.BatchJobError): + batch_job_error (google.ads.googleads.v23.errors.types.BatchJobErrorEnum.BatchJobError): The reasons for the batch job error This field is a member of `oneof`_ ``error_code``. - account_link_error (google.ads.googleads.v19.errors.types.AccountLinkErrorEnum.AccountLinkError): + account_link_error (google.ads.googleads.v23.errors.types.AccountLinkErrorEnum.AccountLinkError): The reasons for the account link status change error This field is a member of `oneof`_ ``error_code``. - third_party_app_analytics_link_error (google.ads.googleads.v19.errors.types.ThirdPartyAppAnalyticsLinkErrorEnum.ThirdPartyAppAnalyticsLinkError): + third_party_app_analytics_link_error (google.ads.googleads.v23.errors.types.ThirdPartyAppAnalyticsLinkErrorEnum.ThirdPartyAppAnalyticsLinkError): The reasons for the third party app analytics link mutate error This field is a member of `oneof`_ ``error_code``. - customer_user_access_error (google.ads.googleads.v19.errors.types.CustomerUserAccessErrorEnum.CustomerUserAccessError): + customer_user_access_error (google.ads.googleads.v23.errors.types.CustomerUserAccessErrorEnum.CustomerUserAccessError): The reasons for the customer user access mutate error This field is a member of `oneof`_ ``error_code``. - custom_audience_error (google.ads.googleads.v19.errors.types.CustomAudienceErrorEnum.CustomAudienceError): + custom_audience_error (google.ads.googleads.v23.errors.types.CustomAudienceErrorEnum.CustomAudienceError): The reasons for the custom audience error This field is a member of `oneof`_ ``error_code``. - audience_error (google.ads.googleads.v19.errors.types.AudienceErrorEnum.AudienceError): + audience_error (google.ads.googleads.v23.errors.types.AudienceErrorEnum.AudienceError): The reasons for the audience error This field is a member of `oneof`_ ``error_code``. - search_term_insight_error (google.ads.googleads.v19.errors.types.SearchTermInsightErrorEnum.SearchTermInsightError): + search_term_insight_error (google.ads.googleads.v23.errors.types.SearchTermInsightErrorEnum.SearchTermInsightError): The reasons for the Search term insight error This field is a member of `oneof`_ ``error_code``. - smart_campaign_error (google.ads.googleads.v19.errors.types.SmartCampaignErrorEnum.SmartCampaignError): + smart_campaign_error (google.ads.googleads.v23.errors.types.SmartCampaignErrorEnum.SmartCampaignError): The reasons for the Smart campaign error This field is a member of `oneof`_ ``error_code``. - experiment_arm_error (google.ads.googleads.v19.errors.types.ExperimentArmErrorEnum.ExperimentArmError): + experiment_arm_error (google.ads.googleads.v23.errors.types.ExperimentArmErrorEnum.ExperimentArmError): The reasons for the experiment arm error This field is a member of `oneof`_ ``error_code``. - audience_insights_error (google.ads.googleads.v19.errors.types.AudienceInsightsErrorEnum.AudienceInsightsError): + audience_insights_error (google.ads.googleads.v23.errors.types.AudienceInsightsErrorEnum.AudienceInsightsError): The reasons for the Audience Insights error This field is a member of `oneof`_ ``error_code``. - product_link_error (google.ads.googleads.v19.errors.types.ProductLinkErrorEnum.ProductLinkError): + product_link_error (google.ads.googleads.v23.errors.types.ProductLinkErrorEnum.ProductLinkError): The reasons for the product link error This field is a member of `oneof`_ ``error_code``. - data_link_error (google.ads.googleads.v19.errors.types.DataLinkErrorEnum.DataLinkError): + data_link_error (google.ads.googleads.v23.errors.types.DataLinkErrorEnum.DataLinkError): The reasons for the data link error This field is a member of `oneof`_ ``error_code``. - customer_sk_ad_network_conversion_value_schema_error (google.ads.googleads.v19.errors.types.CustomerSkAdNetworkConversionValueSchemaErrorEnum.CustomerSkAdNetworkConversionValueSchemaError): + customer_sk_ad_network_conversion_value_schema_error (google.ads.googleads.v23.errors.types.CustomerSkAdNetworkConversionValueSchemaErrorEnum.CustomerSkAdNetworkConversionValueSchemaError): The reasons for the customer SK Ad network conversion value schema error This field is a member of `oneof`_ ``error_code``. - currency_error (google.ads.googleads.v19.errors.types.CurrencyErrorEnum.CurrencyError): + currency_error (google.ads.googleads.v23.errors.types.CurrencyErrorEnum.CurrencyError): The reasons for the currency errors. This field is a member of `oneof`_ ``error_code``. - asset_group_signal_error (google.ads.googleads.v19.errors.types.AssetGroupSignalErrorEnum.AssetGroupSignalError): + asset_group_signal_error (google.ads.googleads.v23.errors.types.AssetGroupSignalErrorEnum.AssetGroupSignalError): The reasons for the asset group hint error This field is a member of `oneof`_ ``error_code``. - product_link_invitation_error (google.ads.googleads.v19.errors.types.ProductLinkInvitationErrorEnum.ProductLinkInvitationError): + product_link_invitation_error (google.ads.googleads.v23.errors.types.ProductLinkInvitationErrorEnum.ProductLinkInvitationError): The reasons for the product link invitation error This field is a member of `oneof`_ ``error_code``. - customer_lifecycle_goal_error (google.ads.googleads.v19.errors.types.CustomerLifecycleGoalErrorEnum.CustomerLifecycleGoalError): + customer_lifecycle_goal_error (google.ads.googleads.v23.errors.types.CustomerLifecycleGoalErrorEnum.CustomerLifecycleGoalError): The reasons for the customer lifecycle goal error This field is a member of `oneof`_ ``error_code``. - campaign_lifecycle_goal_error (google.ads.googleads.v19.errors.types.CampaignLifecycleGoalErrorEnum.CampaignLifecycleGoalError): + campaign_lifecycle_goal_error (google.ads.googleads.v23.errors.types.CampaignLifecycleGoalErrorEnum.CampaignLifecycleGoalError): The reasons for the campaign lifecycle goal error This field is a member of `oneof`_ ``error_code``. - identity_verification_error (google.ads.googleads.v19.errors.types.IdentityVerificationErrorEnum.IdentityVerificationError): + identity_verification_error (google.ads.googleads.v23.errors.types.IdentityVerificationErrorEnum.IdentityVerificationError): The reasons for an identity verification error. This field is a member of `oneof`_ ``error_code``. - user_list_customer_type_error (google.ads.googleads.v19.errors.types.UserListCustomerTypeErrorEnum.UserListCustomerTypeError): + user_list_customer_type_error (google.ads.googleads.v23.errors.types.UserListCustomerTypeErrorEnum.UserListCustomerTypeError): The reasons for a user list customer type error. This field is a member of `oneof`_ ``error_code``. - shopping_product_error (google.ads.googleads.v19.errors.types.ShoppingProductErrorEnum.ShoppingProductError): + shopping_product_error (google.ads.googleads.v23.errors.types.ShoppingProductErrorEnum.ShoppingProductError): The reasons for error in querying shopping product. This field is a member of `oneof`_ ``error_code``. - automatically_created_asset_removal_error (google.ads.googleads.v19.errors.types.AutomaticallyCreatedAssetRemovalErrorEnum.AutomaticallyCreatedAssetRemovalError): + automatically_created_asset_removal_error (google.ads.googleads.v23.errors.types.AutomaticallyCreatedAssetRemovalErrorEnum.AutomaticallyCreatedAssetRemovalError): The reasons for error in automatically created asset removal action. This field is a member of `oneof`_ ``error_code``. - shareable_preview_error (google.ads.googleads.v19.errors.types.ShareablePreviewErrorEnum.ShareablePreviewError): + shareable_preview_error (google.ads.googleads.v23.errors.types.ShareablePreviewErrorEnum.ShareablePreviewError): The reasons for the shareable preview error. This field is a member of `oneof`_ ``error_code``. - brand_guidelines_migration_error (google.ads.googleads.v19.errors.types.BrandGuidelinesMigrationErrorEnum.BrandGuidelinesMigrationError): + campaign_goal_config_error (google.ads.googleads.v23.errors.types.CampaignGoalConfigErrorEnum.CampaignGoalConfigError): + The reasons for the campaign goal config + error. + + This field is a member of `oneof`_ ``error_code``. + goal_error (google.ads.googleads.v23.errors.types.GoalErrorEnum.GoalError): + The reasons for the goal error. + + This field is a member of `oneof`_ ``error_code``. + brand_guidelines_migration_error (google.ads.googleads.v23.errors.types.BrandGuidelinesMigrationErrorEnum.BrandGuidelinesMigrationError): The reasons for the brand guidelines migration error. + This field is a member of `oneof`_ ``error_code``. + asset_generation_error (google.ads.googleads.v23.errors.types.AssetGenerationErrorEnum.AssetGenerationError): + The reasons for the GenAI asset generation + error. + + This field is a member of `oneof`_ ``error_code``. + benchmarks_error (google.ads.googleads.v23.errors.types.BenchmarksErrorEnum.BenchmarksError): + The reasons for the Benchmarks error. + + This field is a member of `oneof`_ ``error_code``. + incentive_error (google.ads.googleads.v23.errors.types.IncentiveErrorEnum.IncentiveError): + The reasons for the incentive error + This field is a member of `oneof`_ ``error_code``. """ @@ -1618,6 +1669,14 @@ class ErrorCode(proto.Message): oneof="error_code", enum=gage_feed_attribute_reference_error.FeedAttributeReferenceErrorEnum.FeedAttributeReferenceError, ) + final_url_expansion_asset_view_error: ( + gage_final_url_expansion_asset_view_error.FinalUrlExpansionAssetViewErrorEnum.FinalUrlExpansionAssetViewError + ) = proto.Field( + proto.ENUM, + number=193, + oneof="error_code", + enum=gage_final_url_expansion_asset_view_error.FinalUrlExpansionAssetViewErrorEnum.FinalUrlExpansionAssetViewError, + ) function_error: gage_function_error.FunctionErrorEnum.FunctionError = ( proto.Field( proto.ENUM, @@ -2192,6 +2251,14 @@ class ErrorCode(proto.Message): oneof="error_code", enum=gage_partial_failure_error.PartialFailureErrorEnum.PartialFailureError, ) + click_view_error: ( + gage_click_view_error.ClickViewErrorEnum.ClickViewError + ) = proto.Field( + proto.ENUM, + number=113, + oneof="error_code", + enum=gage_click_view_error.ClickViewErrorEnum.ClickViewError, + ) policy_validation_parameter_error: ( gage_policy_validation_parameter_error.PolicyValidationParameterErrorEnum.PolicyValidationParameterError ) = proto.Field( @@ -2488,6 +2555,20 @@ class ErrorCode(proto.Message): oneof="error_code", enum=gage_shareable_preview_error.ShareablePreviewErrorEnum.ShareablePreviewError, ) + campaign_goal_config_error: ( + gage_campaign_goal_config_error.CampaignGoalConfigErrorEnum.CampaignGoalConfigError + ) = proto.Field( + proto.ENUM, + number=188, + oneof="error_code", + enum=gage_campaign_goal_config_error.CampaignGoalConfigErrorEnum.CampaignGoalConfigError, + ) + goal_error: gage_goal_error.GoalErrorEnum.GoalError = proto.Field( + proto.ENUM, + number=189, + oneof="error_code", + enum=gage_goal_error.GoalErrorEnum.GoalError, + ) brand_guidelines_migration_error: ( gage_brand_guidelines_migration_error.BrandGuidelinesMigrationErrorEnum.BrandGuidelinesMigrationError ) = proto.Field( @@ -2496,6 +2577,30 @@ class ErrorCode(proto.Message): oneof="error_code", enum=gage_brand_guidelines_migration_error.BrandGuidelinesMigrationErrorEnum.BrandGuidelinesMigrationError, ) + asset_generation_error: ( + gage_asset_generation_error.AssetGenerationErrorEnum.AssetGenerationError + ) = proto.Field( + proto.ENUM, + number=194, + oneof="error_code", + enum=gage_asset_generation_error.AssetGenerationErrorEnum.AssetGenerationError, + ) + benchmarks_error: ( + gage_benchmarks_error.BenchmarksErrorEnum.BenchmarksError + ) = proto.Field( + proto.ENUM, + number=195, + oneof="error_code", + enum=gage_benchmarks_error.BenchmarksErrorEnum.BenchmarksError, + ) + incentive_error: gage_incentive_error.IncentiveErrorEnum.IncentiveError = ( + proto.Field( + proto.ENUM, + number=197, + oneof="error_code", + enum=gage_incentive_error.IncentiveErrorEnum.IncentiveError, + ) + ) class ErrorLocation(proto.Message): @@ -2503,7 +2608,7 @@ class ErrorLocation(proto.Message): error. Attributes: - field_path_elements (MutableSequence[google.ads.googleads.v19.errors.types.ErrorLocation.FieldPathElement]): + field_path_elements (MutableSequence[google.ads.googleads.v23.errors.types.ErrorLocation.FieldPathElement]): A field path that indicates which field was invalid in the request. """ @@ -2551,17 +2656,20 @@ class ErrorDetails(proto.Message): returned, but wasn't. This is used when the error code is not published in the client specified version. - policy_violation_details (google.ads.googleads.v19.errors.types.PolicyViolationDetails): + policy_violation_details (google.ads.googleads.v23.errors.types.PolicyViolationDetails): Describes an ad policy violation. - policy_finding_details (google.ads.googleads.v19.errors.types.PolicyFindingDetails): + policy_finding_details (google.ads.googleads.v23.errors.types.PolicyFindingDetails): Describes policy violation findings. - quota_error_details (google.ads.googleads.v19.errors.types.QuotaErrorDetails): + quota_error_details (google.ads.googleads.v23.errors.types.QuotaErrorDetails): Details on the quota error, including the scope (account or developer), the rate bucket name and the retry delay. - resource_count_details (google.ads.googleads.v19.errors.types.ResourceCountDetails): + resource_count_details (google.ads.googleads.v23.errors.types.ResourceCountDetails): Details for a resource count limit exceeded error. + budget_per_day_minimum_error_details (google.ads.googleads.v23.errors.types.BudgetPerDayMinimumErrorDetails): + Details for a budget below per-day minimum + error. """ unpublished_error_code: str = proto.Field( @@ -2588,6 +2696,13 @@ class ErrorDetails(proto.Message): number=5, message="ResourceCountDetails", ) + budget_per_day_minimum_error_details: "BudgetPerDayMinimumErrorDetails" = ( + proto.Field( + proto.MESSAGE, + number=6, + message="BudgetPerDayMinimumErrorDetails", + ) + ) class PolicyViolationDetails(proto.Message): @@ -2599,7 +2714,7 @@ class PolicyViolationDetails(proto.Message): external_policy_description (str): Human readable description of policy violation. - key (google.ads.googleads.v19.common.types.PolicyViolationKey): + key (google.ads.googleads.v23.common.types.PolicyViolationKey): Unique identifier for this violation. If policy is exemptible, this key may be used to request exemption. @@ -2635,7 +2750,7 @@ class PolicyFindingDetails(proto.Message): of a resource. Attributes: - policy_topic_entries (MutableSequence[google.ads.googleads.v19.common.types.PolicyTopicEntry]): + policy_topic_entries (MutableSequence[google.ads.googleads.v23.common.types.PolicyTopicEntry]): The list of policy topics for the resource. Contains the PROHIBITED or FULLY_LIMITED policy topic entries that prevented the resource from being saved (among any other @@ -2655,7 +2770,7 @@ class QuotaErrorDetails(proto.Message): r"""Additional quota error details when there is QuotaError. Attributes: - rate_scope (google.ads.googleads.v19.errors.types.QuotaErrorDetails.QuotaRateScope): + rate_scope (google.ads.googleads.v23.errors.types.QuotaErrorDetails.QuotaRateScope): The rate scope of the quota limit. rate_name (str): The high level description of the quota @@ -2716,7 +2831,7 @@ class ResourceCountDetails(proto.Message): etc.) whose limit was exceeded. limit (int): The limit which was exceeded. - limit_type (google.ads.googleads.v19.enums.types.ResourceLimitTypeEnum.ResourceLimitType): + limit_type (google.ads.googleads.v23.enums.types.ResourceLimitTypeEnum.ResourceLimitType): The resource limit type which was exceeded. existing_count (int): The count of existing entities. @@ -2747,4 +2862,63 @@ class ResourceCountDetails(proto.Message): ) +class BudgetPerDayMinimumErrorDetails(proto.Message): + r"""Error details for a budget below per-day minimum error. + + Attributes: + currency_code (str): + The advertiser's currency, represented as a + three-letter ISO 4217 currency code (such as + "USD"). + budget_per_day_minimum_micros (int): + The minimum budget required by the campaign + per day, in micros of the advertiser currency. + Applies to both daily and custom budgets. + minimum_budget_amount_micros (int): + The minimum value for the budget's amount + field required by the campaign, in micros of the + advertiser currency. Only set if this error is + caused by the amount field value. + minimum_budget_total_amount_micros (int): + The minimum value for the budget's total_amount field + required by the campaign given its configured start and end + time, in micros of the advertiser currency. Only set if this + error is caused by the total_amount field value. + failed_budget_amount_micros (int): + The budget amount value that was rejected as + too low, in micros of the advertiser currency. + Only set if this error is caused by the amount + field value. + failed_budget_total_amount_micros (int): + The budget total_amount value that was rejected as too low, + in micros of the advertiser currency. Only set if this error + is caused by the total_amount field value. + """ + + currency_code: str = proto.Field( + proto.STRING, + number=1, + ) + budget_per_day_minimum_micros: int = proto.Field( + proto.INT64, + number=2, + ) + minimum_budget_amount_micros: int = proto.Field( + proto.INT64, + number=3, + ) + minimum_budget_total_amount_micros: int = proto.Field( + proto.INT64, + number=4, + ) + failed_budget_amount_micros: int = proto.Field( + proto.INT64, + number=5, + ) + failed_budget_total_amount_micros: int = proto.Field( + proto.INT64, + number=6, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/experiment_arm_error.py b/google/ads/googleads/v23/errors/types/experiment_arm_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/experiment_arm_error.py rename to google/ads/googleads/v23/errors/types/experiment_arm_error.py index 7a9d901e9..b5cbf4e22 100644 --- a/google/ads/googleads/v19/errors/types/experiment_arm_error.py +++ b/google/ads/googleads/v23/errors/types/experiment_arm_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ExperimentArmErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/experiment_error.py b/google/ads/googleads/v23/errors/types/experiment_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/experiment_error.py rename to google/ads/googleads/v23/errors/types/experiment_error.py index ea4b6c35f..5d4c0bf48 100644 --- a/google/ads/googleads/v19/errors/types/experiment_error.py +++ b/google/ads/googleads/v23/errors/types/experiment_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ExperimentErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/extension_feed_item_error.py b/google/ads/googleads/v23/errors/types/extension_feed_item_error.py similarity index 99% rename from google/ads/googleads/v19/errors/types/extension_feed_item_error.py rename to google/ads/googleads/v23/errors/types/extension_feed_item_error.py index 5b1629267..553460509 100644 --- a/google/ads/googleads/v19/errors/types/extension_feed_item_error.py +++ b/google/ads/googleads/v23/errors/types/extension_feed_item_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ExtensionFeedItemErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/extension_setting_error.py b/google/ads/googleads/v23/errors/types/extension_setting_error.py similarity index 99% rename from google/ads/googleads/v19/errors/types/extension_setting_error.py rename to google/ads/googleads/v23/errors/types/extension_setting_error.py index 43fbe8934..f52890178 100644 --- a/google/ads/googleads/v19/errors/types/extension_setting_error.py +++ b/google/ads/googleads/v23/errors/types/extension_setting_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ExtensionSettingErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/feed_attribute_reference_error.py b/google/ads/googleads/v23/errors/types/feed_attribute_reference_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/feed_attribute_reference_error.py rename to google/ads/googleads/v23/errors/types/feed_attribute_reference_error.py index 78fa9487b..0741e5dec 100644 --- a/google/ads/googleads/v19/errors/types/feed_attribute_reference_error.py +++ b/google/ads/googleads/v23/errors/types/feed_attribute_reference_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FeedAttributeReferenceErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/feed_error.py b/google/ads/googleads/v23/errors/types/feed_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/feed_error.py rename to google/ads/googleads/v23/errors/types/feed_error.py index 4f56ab6dd..bfe61e1e9 100644 --- a/google/ads/googleads/v19/errors/types/feed_error.py +++ b/google/ads/googleads/v23/errors/types/feed_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FeedErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/feed_item_error.py b/google/ads/googleads/v23/errors/types/feed_item_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/feed_item_error.py rename to google/ads/googleads/v23/errors/types/feed_item_error.py index ec200b015..ab319f8cf 100644 --- a/google/ads/googleads/v19/errors/types/feed_item_error.py +++ b/google/ads/googleads/v23/errors/types/feed_item_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FeedItemErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/feed_item_set_error.py b/google/ads/googleads/v23/errors/types/feed_item_set_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/feed_item_set_error.py rename to google/ads/googleads/v23/errors/types/feed_item_set_error.py index 68b8fd3a5..72f4871b7 100644 --- a/google/ads/googleads/v19/errors/types/feed_item_set_error.py +++ b/google/ads/googleads/v23/errors/types/feed_item_set_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FeedItemSetErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/feed_item_set_link_error.py b/google/ads/googleads/v23/errors/types/feed_item_set_link_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/feed_item_set_link_error.py rename to google/ads/googleads/v23/errors/types/feed_item_set_link_error.py index bceeb8966..a608ce044 100644 --- a/google/ads/googleads/v19/errors/types/feed_item_set_link_error.py +++ b/google/ads/googleads/v23/errors/types/feed_item_set_link_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FeedItemSetLinkErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/feed_item_target_error.py b/google/ads/googleads/v23/errors/types/feed_item_target_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/feed_item_target_error.py rename to google/ads/googleads/v23/errors/types/feed_item_target_error.py index bfc51051d..faa121f0d 100644 --- a/google/ads/googleads/v19/errors/types/feed_item_target_error.py +++ b/google/ads/googleads/v23/errors/types/feed_item_target_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FeedItemTargetErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/feed_item_validation_error.py b/google/ads/googleads/v23/errors/types/feed_item_validation_error.py similarity index 99% rename from google/ads/googleads/v19/errors/types/feed_item_validation_error.py rename to google/ads/googleads/v23/errors/types/feed_item_validation_error.py index af2b0e8ed..315e63635 100644 --- a/google/ads/googleads/v19/errors/types/feed_item_validation_error.py +++ b/google/ads/googleads/v23/errors/types/feed_item_validation_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FeedItemValidationErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/feed_mapping_error.py b/google/ads/googleads/v23/errors/types/feed_mapping_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/feed_mapping_error.py rename to google/ads/googleads/v23/errors/types/feed_mapping_error.py index e030ff0dd..9359f25db 100644 --- a/google/ads/googleads/v19/errors/types/feed_mapping_error.py +++ b/google/ads/googleads/v23/errors/types/feed_mapping_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FeedMappingErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/field_error.py b/google/ads/googleads/v23/errors/types/field_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/field_error.py rename to google/ads/googleads/v23/errors/types/field_error.py index e99ed7f9d..dca288d67 100644 --- a/google/ads/googleads/v19/errors/types/field_error.py +++ b/google/ads/googleads/v23/errors/types/field_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FieldErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/field_mask_error.py b/google/ads/googleads/v23/errors/types/field_mask_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/field_mask_error.py rename to google/ads/googleads/v23/errors/types/field_mask_error.py index 99523b4e2..665f5426b 100644 --- a/google/ads/googleads/v19/errors/types/field_mask_error.py +++ b/google/ads/googleads/v23/errors/types/field_mask_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FieldMaskErrorEnum", }, diff --git a/google/ads/googleads/v23/errors/types/final_url_expansion_asset_view_error.py b/google/ads/googleads/v23/errors/types/final_url_expansion_asset_view_error.py new file mode 100644 index 000000000..a537a4e61 --- /dev/null +++ b/google/ads/googleads/v23/errors/types/final_url_expansion_asset_view_error.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", + manifest={ + "FinalUrlExpansionAssetViewErrorEnum", + }, +) + + +class FinalUrlExpansionAssetViewErrorEnum(proto.Message): + r"""Container for enum describing possible final url expansion + asset view errors. + + """ + + class FinalUrlExpansionAssetViewError(proto.Enum): + r"""Enum describing possible final url expansion asset view + errors. + + Values: + UNSPECIFIED (0): + Name unspecified. + UNKNOWN (1): + The received error code is not known in this + version. + MISSING_REQUIRED_FILTER (2): + At least one required filter has to be + applied in the query. + REQUIRES_ADVERTISING_CHANNEL_TYPE_FILTER (3): + Advertising channel type filter is required. + INVALID_ADVERTISING_CHANNEL_TYPE_IN_FILTER (4): + Advertising channel type filter has an + invalid value. + CANNOT_SELECT_ASSET_GROUP (5): + Asset group cannot be selected in the query. + CANNOT_SELECT_AD_GROUP (6): + Ad group cannot be selected in the query. + REQUIRES_FILTER_BY_SINGLE_RESOURCE (7): + A selected field/resource requires filtering + by a single resource. + CANNOT_SELECT_BOTH_AD_GROUP_AND_ASSET_GROUP (8): + Both ad group and asset group cannot be + selected in the query. + CANNOT_FILTER_BY_BOTH_AD_GROUP_AND_ASSET_GROUP (9): + Both ad group and asset group cannot be + filtered in the query. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + MISSING_REQUIRED_FILTER = 2 + REQUIRES_ADVERTISING_CHANNEL_TYPE_FILTER = 3 + INVALID_ADVERTISING_CHANNEL_TYPE_IN_FILTER = 4 + CANNOT_SELECT_ASSET_GROUP = 5 + CANNOT_SELECT_AD_GROUP = 6 + REQUIRES_FILTER_BY_SINGLE_RESOURCE = 7 + CANNOT_SELECT_BOTH_AD_GROUP_AND_ASSET_GROUP = 8 + CANNOT_FILTER_BY_BOTH_AD_GROUP_AND_ASSET_GROUP = 9 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/function_error.py b/google/ads/googleads/v23/errors/types/function_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/function_error.py rename to google/ads/googleads/v23/errors/types/function_error.py index 4c1989062..2872dca9c 100644 --- a/google/ads/googleads/v19/errors/types/function_error.py +++ b/google/ads/googleads/v23/errors/types/function_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FunctionErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/function_parsing_error.py b/google/ads/googleads/v23/errors/types/function_parsing_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/function_parsing_error.py rename to google/ads/googleads/v23/errors/types/function_parsing_error.py index c8c37be96..5573ecccc 100644 --- a/google/ads/googleads/v19/errors/types/function_parsing_error.py +++ b/google/ads/googleads/v23/errors/types/function_parsing_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "FunctionParsingErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/geo_target_constant_suggestion_error.py b/google/ads/googleads/v23/errors/types/geo_target_constant_suggestion_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/geo_target_constant_suggestion_error.py rename to google/ads/googleads/v23/errors/types/geo_target_constant_suggestion_error.py index 38a85c768..ee0ca26c1 100644 --- a/google/ads/googleads/v19/errors/types/geo_target_constant_suggestion_error.py +++ b/google/ads/googleads/v23/errors/types/geo_target_constant_suggestion_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "GeoTargetConstantSuggestionErrorEnum", }, diff --git a/google/ads/googleads/v23/errors/types/goal_error.py b/google/ads/googleads/v23/errors/types/goal_error.py new file mode 100644 index 000000000..e68caa88e --- /dev/null +++ b/google/ads/googleads/v23/errors/types/goal_error.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", + manifest={ + "GoalErrorEnum", + }, +) + + +class GoalErrorEnum(proto.Message): + r"""Container for enum describing possible goal errors.""" + + class GoalError(proto.Enum): + r"""Enum describing possible goal errors. + + Values: + UNSPECIFIED (0): + Enum unspecified. + UNKNOWN (1): + The received error code is not known in this + version. + RETENTION_GOAL_ALREADY_EXISTS (4): + Retention goal already exists. + HIGH_LIFETIME_VALUE_PRESENT_BUT_VALUE_ABSENT (5): + When using customer lifecycle optimization + goal, if high lifetime value is present then + value should be present. + HIGH_LIFETIME_VALUE_LESS_THAN_OR_EQUAL_TO_VALUE (6): + When using customer lifecycle optimization + goal, high lifetime value should be greater than + value. + CUSTOMER_LIFECYCLE_OPTIMIZATION_ACCOUNT_TYPE_NOT_ALLOWED (7): + Only Google Ads account can have customer + lifecycle optimization goal. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + RETENTION_GOAL_ALREADY_EXISTS = 4 + HIGH_LIFETIME_VALUE_PRESENT_BUT_VALUE_ABSENT = 5 + HIGH_LIFETIME_VALUE_LESS_THAN_OR_EQUAL_TO_VALUE = 6 + CUSTOMER_LIFECYCLE_OPTIMIZATION_ACCOUNT_TYPE_NOT_ALLOWED = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/header_error.py b/google/ads/googleads/v23/errors/types/header_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/header_error.py rename to google/ads/googleads/v23/errors/types/header_error.py index efc4de8cd..8ae585594 100644 --- a/google/ads/googleads/v19/errors/types/header_error.py +++ b/google/ads/googleads/v23/errors/types/header_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "HeaderErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/id_error.py b/google/ads/googleads/v23/errors/types/id_error.py similarity index 93% rename from google/ads/googleads/v19/errors/types/id_error.py rename to google/ads/googleads/v23/errors/types/id_error.py index 694f07085..36036b82d 100644 --- a/google/ads/googleads/v19/errors/types/id_error.py +++ b/google/ads/googleads/v23/errors/types/id_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "IdErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/identity_verification_error.py b/google/ads/googleads/v23/errors/types/identity_verification_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/identity_verification_error.py rename to google/ads/googleads/v23/errors/types/identity_verification_error.py index 9f3e06a7a..6ce469c7c 100644 --- a/google/ads/googleads/v19/errors/types/identity_verification_error.py +++ b/google/ads/googleads/v23/errors/types/identity_verification_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "IdentityVerificationErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/image_error.py b/google/ads/googleads/v23/errors/types/image_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/image_error.py rename to google/ads/googleads/v23/errors/types/image_error.py index 8a16e0b0f..df06172f4 100644 --- a/google/ads/googleads/v19/errors/types/image_error.py +++ b/google/ads/googleads/v23/errors/types/image_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ImageErrorEnum", }, @@ -86,9 +86,9 @@ class ImageError(proto.Enum): FLASH_HAS_RANDOM_NUM (23): Flash cannot have a random number. FLASH_SELF_TARGETS (24): - Ad click target cannot be '_self'. + Ad click target cannot be '\_self'. FLASH_BAD_GETURL_TARGET (25): - GetUrl method should only use '_blank'. + GetUrl method should only use '\_blank'. FLASH_VERSION_NOT_SUPPORTED (26): Flash version is not supported. FLASH_WITHOUT_HARD_CODED_CLICK_URL (27): diff --git a/google/ads/googleads/v23/errors/types/incentive_error.py b/google/ads/googleads/v23/errors/types/incentive_error.py new file mode 100644 index 000000000..0a1b103ac --- /dev/null +++ b/google/ads/googleads/v23/errors/types/incentive_error.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", + manifest={ + "IncentiveErrorEnum", + }, +) + + +class IncentiveErrorEnum(proto.Message): + r"""Container for enum describing possible incentive errors.""" + + class IncentiveError(proto.Enum): + r"""Enum describing possible incentive errors. + + Values: + UNSPECIFIED (0): + Enum unspecified. + UNKNOWN (1): + The received error code is not known in this + version. + INVALID_INCENTIVE_ID (2): + The incentive ID is either invalid or not + supported for the given country. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + INVALID_INCENTIVE_ID = 2 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/internal_error.py b/google/ads/googleads/v23/errors/types/internal_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/internal_error.py rename to google/ads/googleads/v23/errors/types/internal_error.py index a5eb7b0c7..0e9fd2755 100644 --- a/google/ads/googleads/v19/errors/types/internal_error.py +++ b/google/ads/googleads/v23/errors/types/internal_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "InternalErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/invoice_error.py b/google/ads/googleads/v23/errors/types/invoice_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/invoice_error.py rename to google/ads/googleads/v23/errors/types/invoice_error.py index 7f827a324..6563d77ad 100644 --- a/google/ads/googleads/v19/errors/types/invoice_error.py +++ b/google/ads/googleads/v23/errors/types/invoice_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "InvoiceErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/keyword_plan_ad_group_error.py b/google/ads/googleads/v23/errors/types/keyword_plan_ad_group_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/keyword_plan_ad_group_error.py rename to google/ads/googleads/v23/errors/types/keyword_plan_ad_group_error.py index 6d4f42085..8b4d5f22f 100644 --- a/google/ads/googleads/v19/errors/types/keyword_plan_ad_group_error.py +++ b/google/ads/googleads/v23/errors/types/keyword_plan_ad_group_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanAdGroupErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/keyword_plan_ad_group_keyword_error.py b/google/ads/googleads/v23/errors/types/keyword_plan_ad_group_keyword_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/keyword_plan_ad_group_keyword_error.py rename to google/ads/googleads/v23/errors/types/keyword_plan_ad_group_keyword_error.py index 1b8cde3ce..0d1e1d958 100644 --- a/google/ads/googleads/v19/errors/types/keyword_plan_ad_group_keyword_error.py +++ b/google/ads/googleads/v23/errors/types/keyword_plan_ad_group_keyword_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanAdGroupKeywordErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/keyword_plan_campaign_error.py b/google/ads/googleads/v23/errors/types/keyword_plan_campaign_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/keyword_plan_campaign_error.py rename to google/ads/googleads/v23/errors/types/keyword_plan_campaign_error.py index 1fbf97672..d34863a95 100644 --- a/google/ads/googleads/v19/errors/types/keyword_plan_campaign_error.py +++ b/google/ads/googleads/v23/errors/types/keyword_plan_campaign_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanCampaignErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/keyword_plan_campaign_keyword_error.py b/google/ads/googleads/v23/errors/types/keyword_plan_campaign_keyword_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/keyword_plan_campaign_keyword_error.py rename to google/ads/googleads/v23/errors/types/keyword_plan_campaign_keyword_error.py index 69b70301c..102e6b2d8 100644 --- a/google/ads/googleads/v19/errors/types/keyword_plan_campaign_keyword_error.py +++ b/google/ads/googleads/v23/errors/types/keyword_plan_campaign_keyword_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanCampaignKeywordErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/keyword_plan_error.py b/google/ads/googleads/v23/errors/types/keyword_plan_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/keyword_plan_error.py rename to google/ads/googleads/v23/errors/types/keyword_plan_error.py index 3206d14d0..6aece392e 100644 --- a/google/ads/googleads/v19/errors/types/keyword_plan_error.py +++ b/google/ads/googleads/v23/errors/types/keyword_plan_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/keyword_plan_idea_error.py b/google/ads/googleads/v23/errors/types/keyword_plan_idea_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/keyword_plan_idea_error.py rename to google/ads/googleads/v23/errors/types/keyword_plan_idea_error.py index 1eccdac49..497323778 100644 --- a/google/ads/googleads/v19/errors/types/keyword_plan_idea_error.py +++ b/google/ads/googleads/v23/errors/types/keyword_plan_idea_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanIdeaErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/label_error.py b/google/ads/googleads/v23/errors/types/label_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/label_error.py rename to google/ads/googleads/v23/errors/types/label_error.py index 06bd9a661..51a8e2b55 100644 --- a/google/ads/googleads/v19/errors/types/label_error.py +++ b/google/ads/googleads/v23/errors/types/label_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "LabelErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/language_code_error.py b/google/ads/googleads/v23/errors/types/language_code_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/language_code_error.py rename to google/ads/googleads/v23/errors/types/language_code_error.py index ddce751ad..ed448e854 100644 --- a/google/ads/googleads/v19/errors/types/language_code_error.py +++ b/google/ads/googleads/v23/errors/types/language_code_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "LanguageCodeErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/list_operation_error.py b/google/ads/googleads/v23/errors/types/list_operation_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/list_operation_error.py rename to google/ads/googleads/v23/errors/types/list_operation_error.py index e1326835c..c2c538e73 100644 --- a/google/ads/googleads/v19/errors/types/list_operation_error.py +++ b/google/ads/googleads/v23/errors/types/list_operation_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ListOperationErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/manager_link_error.py b/google/ads/googleads/v23/errors/types/manager_link_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/manager_link_error.py rename to google/ads/googleads/v23/errors/types/manager_link_error.py index aa9646451..4b0a74b27 100644 --- a/google/ads/googleads/v19/errors/types/manager_link_error.py +++ b/google/ads/googleads/v23/errors/types/manager_link_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ManagerLinkErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/media_bundle_error.py b/google/ads/googleads/v23/errors/types/media_bundle_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/media_bundle_error.py rename to google/ads/googleads/v23/errors/types/media_bundle_error.py index b4db0439a..f46004226 100644 --- a/google/ads/googleads/v19/errors/types/media_bundle_error.py +++ b/google/ads/googleads/v23/errors/types/media_bundle_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "MediaBundleErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/media_file_error.py b/google/ads/googleads/v23/errors/types/media_file_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/media_file_error.py rename to google/ads/googleads/v23/errors/types/media_file_error.py index 54ef22e2a..8b6582883 100644 --- a/google/ads/googleads/v19/errors/types/media_file_error.py +++ b/google/ads/googleads/v23/errors/types/media_file_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "MediaFileErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/media_upload_error.py b/google/ads/googleads/v23/errors/types/media_upload_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/media_upload_error.py rename to google/ads/googleads/v23/errors/types/media_upload_error.py index 8fe357007..7131c628f 100644 --- a/google/ads/googleads/v19/errors/types/media_upload_error.py +++ b/google/ads/googleads/v23/errors/types/media_upload_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "MediaUploadErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/merchant_center_error.py b/google/ads/googleads/v23/errors/types/merchant_center_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/merchant_center_error.py rename to google/ads/googleads/v23/errors/types/merchant_center_error.py index 28e9bf03c..3c4bf498f 100644 --- a/google/ads/googleads/v19/errors/types/merchant_center_error.py +++ b/google/ads/googleads/v23/errors/types/merchant_center_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "MerchantCenterErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/multiplier_error.py b/google/ads/googleads/v23/errors/types/multiplier_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/multiplier_error.py rename to google/ads/googleads/v23/errors/types/multiplier_error.py index 62d119c36..07f560b44 100644 --- a/google/ads/googleads/v19/errors/types/multiplier_error.py +++ b/google/ads/googleads/v23/errors/types/multiplier_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "MultiplierErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/mutate_error.py b/google/ads/googleads/v23/errors/types/mutate_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/mutate_error.py rename to google/ads/googleads/v23/errors/types/mutate_error.py index ecaec28e3..f6e856730 100644 --- a/google/ads/googleads/v19/errors/types/mutate_error.py +++ b/google/ads/googleads/v23/errors/types/mutate_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "MutateErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/new_resource_creation_error.py b/google/ads/googleads/v23/errors/types/new_resource_creation_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/new_resource_creation_error.py rename to google/ads/googleads/v23/errors/types/new_resource_creation_error.py index fb88456de..5ccfc3368 100644 --- a/google/ads/googleads/v19/errors/types/new_resource_creation_error.py +++ b/google/ads/googleads/v23/errors/types/new_resource_creation_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "NewResourceCreationErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/not_allowlisted_error.py b/google/ads/googleads/v23/errors/types/not_allowlisted_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/not_allowlisted_error.py rename to google/ads/googleads/v23/errors/types/not_allowlisted_error.py index 841af8974..14f500e05 100644 --- a/google/ads/googleads/v19/errors/types/not_allowlisted_error.py +++ b/google/ads/googleads/v23/errors/types/not_allowlisted_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "NotAllowlistedErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/not_empty_error.py b/google/ads/googleads/v23/errors/types/not_empty_error.py similarity index 93% rename from google/ads/googleads/v19/errors/types/not_empty_error.py rename to google/ads/googleads/v23/errors/types/not_empty_error.py index 03434f1ba..520382409 100644 --- a/google/ads/googleads/v19/errors/types/not_empty_error.py +++ b/google/ads/googleads/v23/errors/types/not_empty_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "NotEmptyErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/null_error.py b/google/ads/googleads/v23/errors/types/null_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/null_error.py rename to google/ads/googleads/v23/errors/types/null_error.py index 8e764d231..e500cec6b 100644 --- a/google/ads/googleads/v19/errors/types/null_error.py +++ b/google/ads/googleads/v23/errors/types/null_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "NullErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/offline_user_data_job_error.py b/google/ads/googleads/v23/errors/types/offline_user_data_job_error.py similarity index 99% rename from google/ads/googleads/v19/errors/types/offline_user_data_job_error.py rename to google/ads/googleads/v23/errors/types/offline_user_data_job_error.py index d054376b1..92b91a060 100644 --- a/google/ads/googleads/v19/errors/types/offline_user_data_job_error.py +++ b/google/ads/googleads/v23/errors/types/offline_user_data_job_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "OfflineUserDataJobErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/operation_access_denied_error.py b/google/ads/googleads/v23/errors/types/operation_access_denied_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/operation_access_denied_error.py rename to google/ads/googleads/v23/errors/types/operation_access_denied_error.py index da866eed4..8a687f5dc 100644 --- a/google/ads/googleads/v19/errors/types/operation_access_denied_error.py +++ b/google/ads/googleads/v23/errors/types/operation_access_denied_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "OperationAccessDeniedErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/operator_error.py b/google/ads/googleads/v23/errors/types/operator_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/operator_error.py rename to google/ads/googleads/v23/errors/types/operator_error.py index 846af1c94..0628ff2cc 100644 --- a/google/ads/googleads/v19/errors/types/operator_error.py +++ b/google/ads/googleads/v23/errors/types/operator_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "OperatorErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/partial_failure_error.py b/google/ads/googleads/v23/errors/types/partial_failure_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/partial_failure_error.py rename to google/ads/googleads/v23/errors/types/partial_failure_error.py index c0b7f8472..6bc78dcdb 100644 --- a/google/ads/googleads/v19/errors/types/partial_failure_error.py +++ b/google/ads/googleads/v23/errors/types/partial_failure_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "PartialFailureErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/payments_account_error.py b/google/ads/googleads/v23/errors/types/payments_account_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/payments_account_error.py rename to google/ads/googleads/v23/errors/types/payments_account_error.py index 04f622dc4..db671874e 100644 --- a/google/ads/googleads/v19/errors/types/payments_account_error.py +++ b/google/ads/googleads/v23/errors/types/payments_account_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "PaymentsAccountErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/policy_finding_error.py b/google/ads/googleads/v23/errors/types/policy_finding_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/policy_finding_error.py rename to google/ads/googleads/v23/errors/types/policy_finding_error.py index 67e787559..e1cfd4891 100644 --- a/google/ads/googleads/v19/errors/types/policy_finding_error.py +++ b/google/ads/googleads/v23/errors/types/policy_finding_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "PolicyFindingErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/policy_validation_parameter_error.py b/google/ads/googleads/v23/errors/types/policy_validation_parameter_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/policy_validation_parameter_error.py rename to google/ads/googleads/v23/errors/types/policy_validation_parameter_error.py index 9b7d7d490..2214ba536 100644 --- a/google/ads/googleads/v19/errors/types/policy_validation_parameter_error.py +++ b/google/ads/googleads/v23/errors/types/policy_validation_parameter_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "PolicyValidationParameterErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/policy_violation_error.py b/google/ads/googleads/v23/errors/types/policy_violation_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/policy_violation_error.py rename to google/ads/googleads/v23/errors/types/policy_violation_error.py index 45a05230a..414349cc8 100644 --- a/google/ads/googleads/v19/errors/types/policy_violation_error.py +++ b/google/ads/googleads/v23/errors/types/policy_violation_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "PolicyViolationErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/product_link_error.py b/google/ads/googleads/v23/errors/types/product_link_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/product_link_error.py rename to google/ads/googleads/v23/errors/types/product_link_error.py index 713cf72d8..b742c8382 100644 --- a/google/ads/googleads/v19/errors/types/product_link_error.py +++ b/google/ads/googleads/v23/errors/types/product_link_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ProductLinkErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/product_link_invitation_error.py b/google/ads/googleads/v23/errors/types/product_link_invitation_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/product_link_invitation_error.py rename to google/ads/googleads/v23/errors/types/product_link_invitation_error.py index dcf2581ba..e2630fe21 100644 --- a/google/ads/googleads/v19/errors/types/product_link_invitation_error.py +++ b/google/ads/googleads/v23/errors/types/product_link_invitation_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ProductLinkInvitationErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/query_error.py b/google/ads/googleads/v23/errors/types/query_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/query_error.py rename to google/ads/googleads/v23/errors/types/query_error.py index eed232369..5cd8b24f7 100644 --- a/google/ads/googleads/v19/errors/types/query_error.py +++ b/google/ads/googleads/v23/errors/types/query_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "QueryErrorEnum", }, @@ -162,6 +162,10 @@ class QueryError(proto.Enum): A segment in the SELECT clause is incompatible with a metric in the SELECT or WHERE clause. + PROHIBITED_FIELD_OR_SEGMENT_WITH_METRIC (65): + A metric may not be selected with one of the + selected resource fields, or segmented by one of + the selected segment fields. LIMIT_VALUE_TOO_LOW (25): The value passed to the limit clause is too low. @@ -196,6 +200,8 @@ class QueryError(proto.Enum): FILTER_HAS_TOO_MANY_VALUES (63): The number of values (right-hand-side operands) in a filter exceeds the limit. + REQUIRED_SEGMENT_FIELD_MISSING (66): + Required segment field is missing. """ UNSPECIFIED = 0 @@ -243,6 +249,7 @@ class QueryError(proto.Enum): PROHIBITED_METRIC_IN_SELECT_OR_WHERE_CLAUSE = 49 PROHIBITED_SEGMENT_IN_SELECT_OR_WHERE_CLAUSE = 51 PROHIBITED_SEGMENT_WITH_METRIC_IN_SELECT_OR_WHERE_CLAUSE = 53 + PROHIBITED_FIELD_OR_SEGMENT_WITH_METRIC = 65 LIMIT_VALUE_TOO_LOW = 25 PROHIBITED_NEWLINE_IN_STRING = 8 PROHIBITED_VALUE_COMBINATION_IN_LIST = 10 @@ -255,6 +262,7 @@ class QueryError(proto.Enum): UNEXPECTED_INPUT = 11 REQUESTED_METRICS_FOR_MANAGER = 59 FILTER_HAS_TOO_MANY_VALUES = 63 + REQUIRED_SEGMENT_FIELD_MISSING = 66 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/errors/types/quota_error.py b/google/ads/googleads/v23/errors/types/quota_error.py new file mode 100644 index 000000000..1b0b5da55 --- /dev/null +++ b/google/ads/googleads/v23/errors/types/quota_error.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", + manifest={ + "QuotaErrorEnum", + }, +) + + +class QuotaErrorEnum(proto.Message): + r"""Container for enum describing possible quota errors.""" + + class QuotaError(proto.Enum): + r"""Enum describing possible quota errors. + + Values: + UNSPECIFIED (0): + Enum unspecified. + UNKNOWN (1): + The received error code is not known in this + version. + RESOURCE_EXHAUSTED (2): + Too many requests. + ACCESS_PROHIBITED (3): + Access is prohibited. + RESOURCE_TEMPORARILY_EXHAUSTED (4): + Too many requests in a short amount of time. + EXCESSIVE_SHORT_TERM_QUERY_RESOURCE_CONSUMPTION (5): + Too many expensive requests from query + pattern over a short amount of time. + EXCESSIVE_LONG_TERM_QUERY_RESOURCE_CONSUMPTION (6): + Too many expensive requests from query + pattern over an extended duration of time. + PAYMENTS_PROFILE_ACTIVATION_RATE_LIMIT_EXCEEDED (7): + To activate ad serving in a customer account, + it has to be linked with a payment profile (also + known as a Billing Customer Number, or BCN), + which is then billed for the costs incurred by + that customer account. This error will be thrown + if too many customer accounts are activated in a + short period of time for the same payment + profile. Once this rate limit is exceeded, the + customer should wait for a week before trying + again, or contact Google Ads customer support to + reset the rate limits. See + https://support.google.com/google-ads/answer/6372658 + to learn more about this limit. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + RESOURCE_EXHAUSTED = 2 + ACCESS_PROHIBITED = 3 + RESOURCE_TEMPORARILY_EXHAUSTED = 4 + EXCESSIVE_SHORT_TERM_QUERY_RESOURCE_CONSUMPTION = 5 + EXCESSIVE_LONG_TERM_QUERY_RESOURCE_CONSUMPTION = 6 + PAYMENTS_PROFILE_ACTIVATION_RATE_LIMIT_EXCEEDED = 7 + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/range_error.py b/google/ads/googleads/v23/errors/types/range_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/range_error.py rename to google/ads/googleads/v23/errors/types/range_error.py index f5f0d4ec4..e875d8199 100644 --- a/google/ads/googleads/v19/errors/types/range_error.py +++ b/google/ads/googleads/v23/errors/types/range_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "RangeErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/reach_plan_error.py b/google/ads/googleads/v23/errors/types/reach_plan_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/reach_plan_error.py rename to google/ads/googleads/v23/errors/types/reach_plan_error.py index db1a19405..4477c86f6 100644 --- a/google/ads/googleads/v19/errors/types/reach_plan_error.py +++ b/google/ads/googleads/v23/errors/types/reach_plan_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ReachPlanErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/recommendation_error.py b/google/ads/googleads/v23/errors/types/recommendation_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/recommendation_error.py rename to google/ads/googleads/v23/errors/types/recommendation_error.py index eef9683e5..8eda127ed 100644 --- a/google/ads/googleads/v19/errors/types/recommendation_error.py +++ b/google/ads/googleads/v23/errors/types/recommendation_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "RecommendationErrorEnum", }, @@ -145,6 +145,9 @@ class RecommendationError(proto.Enum): Target impression share info is required for the CAMPAIGN_BUDGET recommendation type for bidding strategy type TARGET_IMPRESSION_SHARE. + MERCHANT_CENTER_ACCOUNT_ID_NOT_SUPPORTED_ADVERTISING_CHANNEL_TYPE (36): + Merchant Center Account ID is only supported for + advertising_channel_type PERFORMANCE_MAX. """ UNSPECIFIED = 0 @@ -204,6 +207,7 @@ class RecommendationError(proto.Enum): CAMPAIGN_BUDGET_RECOMMENDATION_TYPE_WITH_CHANNEL_TYPE_SEARCH_AND_BIDDING_STRATEGY_TYPE_TARGET_IMPRESSION_SHARE_REQUIRES_TARGET_IMPRESSION_SHARE_INFO = ( 35 ) + MERCHANT_CENTER_ACCOUNT_ID_NOT_SUPPORTED_ADVERTISING_CHANNEL_TYPE = 36 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/recommendation_subscription_error.py b/google/ads/googleads/v23/errors/types/recommendation_subscription_error.py similarity index 93% rename from google/ads/googleads/v19/errors/types/recommendation_subscription_error.py rename to google/ads/googleads/v23/errors/types/recommendation_subscription_error.py index 05a3b43b5..9f0dc98fc 100644 --- a/google/ads/googleads/v19/errors/types/recommendation_subscription_error.py +++ b/google/ads/googleads/v23/errors/types/recommendation_subscription_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "RecommendationSubscriptionErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/region_code_error.py b/google/ads/googleads/v23/errors/types/region_code_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/region_code_error.py rename to google/ads/googleads/v23/errors/types/region_code_error.py index 0f9f0352f..e8aafee33 100644 --- a/google/ads/googleads/v19/errors/types/region_code_error.py +++ b/google/ads/googleads/v23/errors/types/region_code_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "RegionCodeErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/request_error.py b/google/ads/googleads/v23/errors/types/request_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/request_error.py rename to google/ads/googleads/v23/errors/types/request_error.py index 4f9dbfc11..628895c3b 100644 --- a/google/ads/googleads/v19/errors/types/request_error.py +++ b/google/ads/googleads/v23/errors/types/request_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "RequestErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/resource_access_denied_error.py b/google/ads/googleads/v23/errors/types/resource_access_denied_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/resource_access_denied_error.py rename to google/ads/googleads/v23/errors/types/resource_access_denied_error.py index 5e1691723..334f2308d 100644 --- a/google/ads/googleads/v19/errors/types/resource_access_denied_error.py +++ b/google/ads/googleads/v23/errors/types/resource_access_denied_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ResourceAccessDeniedErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/resource_count_limit_exceeded_error.py b/google/ads/googleads/v23/errors/types/resource_count_limit_exceeded_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/resource_count_limit_exceeded_error.py rename to google/ads/googleads/v23/errors/types/resource_count_limit_exceeded_error.py index 71c2c047a..708b0cf65 100644 --- a/google/ads/googleads/v19/errors/types/resource_count_limit_exceeded_error.py +++ b/google/ads/googleads/v23/errors/types/resource_count_limit_exceeded_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ResourceCountLimitExceededErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/search_term_insight_error.py b/google/ads/googleads/v23/errors/types/search_term_insight_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/search_term_insight_error.py rename to google/ads/googleads/v23/errors/types/search_term_insight_error.py index b8fead2df..1f5c466f4 100644 --- a/google/ads/googleads/v19/errors/types/search_term_insight_error.py +++ b/google/ads/googleads/v23/errors/types/search_term_insight_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "SearchTermInsightErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/setting_error.py b/google/ads/googleads/v23/errors/types/setting_error.py similarity index 98% rename from google/ads/googleads/v19/errors/types/setting_error.py rename to google/ads/googleads/v23/errors/types/setting_error.py index 66e00d262..e72451244 100644 --- a/google/ads/googleads/v19/errors/types/setting_error.py +++ b/google/ads/googleads/v23/errors/types/setting_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "SettingErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/shareable_preview_error.py b/google/ads/googleads/v23/errors/types/shareable_preview_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/shareable_preview_error.py rename to google/ads/googleads/v23/errors/types/shareable_preview_error.py index 8018ae7ff..4825e6b62 100644 --- a/google/ads/googleads/v19/errors/types/shareable_preview_error.py +++ b/google/ads/googleads/v23/errors/types/shareable_preview_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ShareablePreviewErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/shared_criterion_error.py b/google/ads/googleads/v23/errors/types/shared_criterion_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/shared_criterion_error.py rename to google/ads/googleads/v23/errors/types/shared_criterion_error.py index e4de627dd..d08abc704 100644 --- a/google/ads/googleads/v19/errors/types/shared_criterion_error.py +++ b/google/ads/googleads/v23/errors/types/shared_criterion_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "SharedCriterionErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/shared_set_error.py b/google/ads/googleads/v23/errors/types/shared_set_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/shared_set_error.py rename to google/ads/googleads/v23/errors/types/shared_set_error.py index 54ce573c1..09d9722d8 100644 --- a/google/ads/googleads/v19/errors/types/shared_set_error.py +++ b/google/ads/googleads/v23/errors/types/shared_set_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "SharedSetErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/shopping_product_error.py b/google/ads/googleads/v23/errors/types/shopping_product_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/shopping_product_error.py rename to google/ads/googleads/v23/errors/types/shopping_product_error.py index b6427f493..73d519993 100644 --- a/google/ads/googleads/v19/errors/types/shopping_product_error.py +++ b/google/ads/googleads/v23/errors/types/shopping_product_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ShoppingProductErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/size_limit_error.py b/google/ads/googleads/v23/errors/types/size_limit_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/size_limit_error.py rename to google/ads/googleads/v23/errors/types/size_limit_error.py index c521a90c2..890cc3002 100644 --- a/google/ads/googleads/v19/errors/types/size_limit_error.py +++ b/google/ads/googleads/v23/errors/types/size_limit_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "SizeLimitErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/smart_campaign_error.py b/google/ads/googleads/v23/errors/types/smart_campaign_error.py similarity index 96% rename from google/ads/googleads/v19/errors/types/smart_campaign_error.py rename to google/ads/googleads/v23/errors/types/smart_campaign_error.py index 0de55ba31..37608df1f 100644 --- a/google/ads/googleads/v19/errors/types/smart_campaign_error.py +++ b/google/ads/googleads/v23/errors/types/smart_campaign_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "SmartCampaignErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/string_format_error.py b/google/ads/googleads/v23/errors/types/string_format_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/string_format_error.py rename to google/ads/googleads/v23/errors/types/string_format_error.py index 355236558..fb889f6f6 100644 --- a/google/ads/googleads/v19/errors/types/string_format_error.py +++ b/google/ads/googleads/v23/errors/types/string_format_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "StringFormatErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/string_length_error.py b/google/ads/googleads/v23/errors/types/string_length_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/string_length_error.py rename to google/ads/googleads/v23/errors/types/string_length_error.py index 7776ed4ac..3eb4cc53f 100644 --- a/google/ads/googleads/v19/errors/types/string_length_error.py +++ b/google/ads/googleads/v23/errors/types/string_length_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "StringLengthErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/third_party_app_analytics_link_error.py b/google/ads/googleads/v23/errors/types/third_party_app_analytics_link_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/third_party_app_analytics_link_error.py rename to google/ads/googleads/v23/errors/types/third_party_app_analytics_link_error.py index fe8e13571..8f1d37d24 100644 --- a/google/ads/googleads/v19/errors/types/third_party_app_analytics_link_error.py +++ b/google/ads/googleads/v23/errors/types/third_party_app_analytics_link_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "ThirdPartyAppAnalyticsLinkErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/time_zone_error.py b/google/ads/googleads/v23/errors/types/time_zone_error.py similarity index 93% rename from google/ads/googleads/v19/errors/types/time_zone_error.py rename to google/ads/googleads/v23/errors/types/time_zone_error.py index b491e220d..b780f4cea 100644 --- a/google/ads/googleads/v19/errors/types/time_zone_error.py +++ b/google/ads/googleads/v23/errors/types/time_zone_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "TimeZoneErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/url_field_error.py b/google/ads/googleads/v23/errors/types/url_field_error.py similarity index 99% rename from google/ads/googleads/v19/errors/types/url_field_error.py rename to google/ads/googleads/v23/errors/types/url_field_error.py index 074e5d764..6bf2394da 100644 --- a/google/ads/googleads/v19/errors/types/url_field_error.py +++ b/google/ads/googleads/v23/errors/types/url_field_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "UrlFieldErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/user_data_error.py b/google/ads/googleads/v23/errors/types/user_data_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/user_data_error.py rename to google/ads/googleads/v23/errors/types/user_data_error.py index 1fa8a7b56..862bfba9a 100644 --- a/google/ads/googleads/v19/errors/types/user_data_error.py +++ b/google/ads/googleads/v23/errors/types/user_data_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "UserDataErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/user_list_customer_type_error.py b/google/ads/googleads/v23/errors/types/user_list_customer_type_error.py similarity index 97% rename from google/ads/googleads/v19/errors/types/user_list_customer_type_error.py rename to google/ads/googleads/v23/errors/types/user_list_customer_type_error.py index 3d3d24c12..9057149cb 100644 --- a/google/ads/googleads/v19/errors/types/user_list_customer_type_error.py +++ b/google/ads/googleads/v23/errors/types/user_list_customer_type_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "UserListCustomerTypeErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/user_list_error.py b/google/ads/googleads/v23/errors/types/user_list_error.py similarity index 78% rename from google/ads/googleads/v19/errors/types/user_list_error.py rename to google/ads/googleads/v23/errors/types/user_list_error.py index e408bb782..7c343b19c 100644 --- a/google/ads/googleads/v19/errors/types/user_list_error.py +++ b/google/ads/googleads/v23/errors/types/user_list_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "UserListErrorEnum", }, @@ -131,6 +131,33 @@ class UserListError(proto.Enum): INVALID_COUNTRY_CODES (45): One or more invalid country codes are added to Lookalike UserList. + PARTNER_AUDIENCE_SOURCE_NOT_SUPPORTED_FOR_USER_LIST_TYPE (47): + The partner audience source is not supported + for the user list type. + COMMERCE_PARTNER_NOT_ALLOWED (48): + The commerce partner is only supported for + COMMERCE_AUDIENCE. + PARTNER_AUDIENCE_INFO_NOT_SUPPORTED_FOR_USER_LIST_TYPE (49): + The partner audience info is not supported + for the user list type. + PARTNER_MANAGER_ACCOUNT_DISALLOWED (50): + Manager account is not allowed to create this + UserList. + PARTNER_NOT_ALLOWLISTED_FOR_THIRD_PARTY_PARTNER_DATA (51): + This UserList can only be created by + allowlisted partners. + ADVERTISER_TOS_NOT_ACCEPTED (52): + The advertiser must accept the Terms of + Service to create this UserList. + ADVERTISER_PARTNER_LINK_MISSING (53): + The advertiser must have an active link to + the partner to create this UserList. + ADVERTISER_NOT_ALLOWLISTED_FOR_THIRD_PARTY_PARTNER_DATA (54): + This UserList can only be created for + allowlisted advertisers. + ACCOUNT_SETTING_TYPE_NOT_ALLOWED (55): + This UserList is not allowed for this account + type. """ UNSPECIFIED = 0 @@ -168,6 +195,15 @@ class UserListError(proto.Enum): INVALID_SEED_LIST_ACCESS_REASON = 43 INVALID_SEED_LIST_TYPE = 44 INVALID_COUNTRY_CODES = 45 + PARTNER_AUDIENCE_SOURCE_NOT_SUPPORTED_FOR_USER_LIST_TYPE = 47 + COMMERCE_PARTNER_NOT_ALLOWED = 48 + PARTNER_AUDIENCE_INFO_NOT_SUPPORTED_FOR_USER_LIST_TYPE = 49 + PARTNER_MANAGER_ACCOUNT_DISALLOWED = 50 + PARTNER_NOT_ALLOWLISTED_FOR_THIRD_PARTY_PARTNER_DATA = 51 + ADVERTISER_TOS_NOT_ACCEPTED = 52 + ADVERTISER_PARTNER_LINK_MISSING = 53 + ADVERTISER_NOT_ALLOWLISTED_FOR_THIRD_PARTY_PARTNER_DATA = 54 + ACCOUNT_SETTING_TYPE_NOT_ALLOWED = 55 __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/errors/types/video_campaign_error.py b/google/ads/googleads/v23/errors/types/video_campaign_error.py similarity index 94% rename from google/ads/googleads/v19/errors/types/video_campaign_error.py rename to google/ads/googleads/v23/errors/types/video_campaign_error.py index 5f057f333..933035fff 100644 --- a/google/ads/googleads/v19/errors/types/video_campaign_error.py +++ b/google/ads/googleads/v23/errors/types/video_campaign_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "VideoCampaignErrorEnum", }, diff --git a/google/ads/googleads/v19/errors/types/youtube_video_registration_error.py b/google/ads/googleads/v23/errors/types/youtube_video_registration_error.py similarity index 95% rename from google/ads/googleads/v19/errors/types/youtube_video_registration_error.py rename to google/ads/googleads/v23/errors/types/youtube_video_registration_error.py index 8b5e461b6..09e999e9f 100644 --- a/google/ads/googleads/v19/errors/types/youtube_video_registration_error.py +++ b/google/ads/googleads/v23/errors/types/youtube_video_registration_error.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.errors", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.errors", + marshal="google.ads.googleads.v23", manifest={ "YoutubeVideoRegistrationErrorEnum", }, diff --git a/google/ads/googleads/v19/gapic_metadata.json b/google/ads/googleads/v23/gapic_metadata.json similarity index 92% rename from google/ads/googleads/v19/gapic_metadata.json rename to google/ads/googleads/v23/gapic_metadata.json index 0d1850fb0..1bc46a006 100644 --- a/google/ads/googleads/v19/gapic_metadata.json +++ b/google/ads/googleads/v23/gapic_metadata.json @@ -1,8 +1,8 @@ { "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", "language": "python", - "libraryPackage": "google.ads.googleads.v19", - "protoPackage": "google.ads.googleads.v19", + "libraryPackage": "google.ads.googleads.v23", + "protoPackage": "google.ads.googleads.v23", "schema": "1.0", "services": { "AccountBudgetProposalService": { @@ -385,6 +385,40 @@ } } }, + "AssetGenerationService": { + "clients": { + "grpc": { + "libraryClient": "AssetGenerationServiceClient", + "rpcs": { + "GenerateImages": { + "methods": [ + "generate_images" + ] + }, + "GenerateText": { + "methods": [ + "generate_text" + ] + } + } + }, + "grpc-async": { + "libraryClient": "AssetGenerationServiceAsyncClient", + "rpcs": { + "GenerateImages": { + "methods": [ + "generate_images" + ] + }, + "GenerateText": { + "methods": [ + "generate_text" + ] + } + } + } + } + }, "AssetGroupAssetService": { "clients": { "grpc": { @@ -563,6 +597,11 @@ "generate_audience_composition_insights" ] }, + "GenerateAudienceDefinition": { + "methods": [ + "generate_audience_definition" + ] + }, "GenerateAudienceOverlapInsights": { "methods": [ "generate_audience_overlap_insights" @@ -603,6 +642,11 @@ "generate_audience_composition_insights" ] }, + "GenerateAudienceDefinition": { + "methods": [ + "generate_audience_definition" + ] + }, "GenerateAudienceOverlapInsights": { "methods": [ "generate_audience_overlap_insights" @@ -661,6 +705,30 @@ } } }, + "AutomaticallyCreatedAssetRemovalService": { + "clients": { + "grpc": { + "libraryClient": "AutomaticallyCreatedAssetRemovalServiceClient", + "rpcs": { + "RemoveCampaignAutomaticallyCreatedAsset": { + "methods": [ + "remove_campaign_automatically_created_asset" + ] + } + } + }, + "grpc-async": { + "libraryClient": "AutomaticallyCreatedAssetRemovalServiceAsyncClient", + "rpcs": { + "RemoveCampaignAutomaticallyCreatedAsset": { + "methods": [ + "remove_campaign_automatically_created_asset" + ] + } + } + } + } + }, "BatchJobService": { "clients": { "grpc": { @@ -715,6 +783,70 @@ } } }, + "BenchmarksService": { + "clients": { + "grpc": { + "libraryClient": "BenchmarksServiceClient", + "rpcs": { + "GenerateBenchmarksMetrics": { + "methods": [ + "generate_benchmarks_metrics" + ] + }, + "ListBenchmarksAvailableDates": { + "methods": [ + "list_benchmarks_available_dates" + ] + }, + "ListBenchmarksLocations": { + "methods": [ + "list_benchmarks_locations" + ] + }, + "ListBenchmarksProducts": { + "methods": [ + "list_benchmarks_products" + ] + }, + "ListBenchmarksSources": { + "methods": [ + "list_benchmarks_sources" + ] + } + } + }, + "grpc-async": { + "libraryClient": "BenchmarksServiceAsyncClient", + "rpcs": { + "GenerateBenchmarksMetrics": { + "methods": [ + "generate_benchmarks_metrics" + ] + }, + "ListBenchmarksAvailableDates": { + "methods": [ + "list_benchmarks_available_dates" + ] + }, + "ListBenchmarksLocations": { + "methods": [ + "list_benchmarks_locations" + ] + }, + "ListBenchmarksProducts": { + "methods": [ + "list_benchmarks_products" + ] + }, + "ListBenchmarksSources": { + "methods": [ + "list_benchmarks_sources" + ] + } + } + } + } + }, "BiddingDataExclusionService": { "clients": { "grpc": { @@ -1047,6 +1179,30 @@ } } }, + "CampaignGoalConfigService": { + "clients": { + "grpc": { + "libraryClient": "CampaignGoalConfigServiceClient", + "rpcs": { + "MutateCampaignGoalConfigs": { + "methods": [ + "mutate_campaign_goal_configs" + ] + } + } + }, + "grpc-async": { + "libraryClient": "CampaignGoalConfigServiceAsyncClient", + "rpcs": { + "MutateCampaignGoalConfigs": { + "methods": [ + "mutate_campaign_goal_configs" + ] + } + } + } + } + }, "CampaignGroupService": { "clients": { "grpc": { @@ -1993,6 +2149,30 @@ } } }, + "GoalService": { + "clients": { + "grpc": { + "libraryClient": "GoalServiceClient", + "rpcs": { + "MutateGoals": { + "methods": [ + "mutate_goals" + ] + } + } + }, + "grpc-async": { + "libraryClient": "GoalServiceAsyncClient", + "rpcs": { + "MutateGoals": { + "methods": [ + "mutate_goals" + ] + } + } + } + } + }, "GoogleAdsFieldService": { "clients": { "grpc": { @@ -2105,6 +2285,40 @@ } } }, + "IncentiveService": { + "clients": { + "grpc": { + "libraryClient": "IncentiveServiceClient", + "rpcs": { + "ApplyIncentive": { + "methods": [ + "apply_incentive" + ] + }, + "FetchIncentive": { + "methods": [ + "fetch_incentive" + ] + } + } + }, + "grpc-async": { + "libraryClient": "IncentiveServiceAsyncClient", + "rpcs": { + "ApplyIncentive": { + "methods": [ + "apply_incentive" + ] + }, + "FetchIncentive": { + "methods": [ + "fetch_incentive" + ] + } + } + } + } + }, "InvoiceService": { "clients": { "grpc": { @@ -2555,6 +2769,16 @@ "methods": [ "list_plannable_products" ] + }, + "ListPlannableUserInterests": { + "methods": [ + "list_plannable_user_interests" + ] + }, + "ListPlannableUserLists": { + "methods": [ + "list_plannable_user_lists" + ] } } }, @@ -2580,6 +2804,16 @@ "methods": [ "list_plannable_products" ] + }, + "ListPlannableUserInterests": { + "methods": [ + "list_plannable_user_interests" + ] + }, + "ListPlannableUserLists": { + "methods": [ + "list_plannable_user_lists" + ] } } } diff --git a/google/ads/googleads/v19/gapic_version.py b/google/ads/googleads/v23/gapic_version.py similarity index 100% rename from google/ads/googleads/v19/gapic_version.py rename to google/ads/googleads/v23/gapic_version.py diff --git a/google/ads/googleads/v19/py.typed b/google/ads/googleads/v23/py.typed similarity index 100% rename from google/ads/googleads/v19/py.typed rename to google/ads/googleads/v23/py.typed diff --git a/google/ads/googleads/v23/resources/__init__.py b/google/ads/googleads/v23/resources/__init__.py new file mode 100644 index 000000000..f69610731 --- /dev/null +++ b/google/ads/googleads/v23/resources/__init__.py @@ -0,0 +1,661 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from google.ads.googleads.v23 import gapic_version as package_version + +import google.api_core as api_core +import sys + +__version__ = package_version.__version__ + +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata + + +from .types.accessible_bidding_strategy import AccessibleBiddingStrategy +from .types.account_budget import AccountBudget +from .types.account_budget_proposal import AccountBudgetProposal +from .types.account_link import AccountLink +from .types.account_link import ThirdPartyAppAnalyticsLinkIdentifier +from .types.ad import Ad +from .types.ad_group import AdGroup +from .types.ad_group_ad import AdGroupAd +from .types.ad_group_ad import AdGroupAdAssetAutomationSetting +from .types.ad_group_ad import AdGroupAdPolicySummary +from .types.ad_group_ad_asset_combination_view import ( + AdGroupAdAssetCombinationView, +) +from .types.ad_group_ad_asset_view import AdGroupAdAssetPolicySummary +from .types.ad_group_ad_asset_view import AdGroupAdAssetView +from .types.ad_group_ad_label import AdGroupAdLabel +from .types.ad_group_asset import AdGroupAsset +from .types.ad_group_asset_set import AdGroupAssetSet +from .types.ad_group_audience_view import AdGroupAudienceView +from .types.ad_group_bid_modifier import AdGroupBidModifier +from .types.ad_group_criterion import AdGroupCriterion +from .types.ad_group_criterion_customizer import AdGroupCriterionCustomizer +from .types.ad_group_criterion_label import AdGroupCriterionLabel +from .types.ad_group_criterion_simulation import AdGroupCriterionSimulation +from .types.ad_group_customizer import AdGroupCustomizer +from .types.ad_group_label import AdGroupLabel +from .types.ad_group_simulation import AdGroupSimulation +from .types.ad_parameter import AdParameter +from .types.ad_schedule_view import AdScheduleView +from .types.age_range_view import AgeRangeView +from .types.ai_max_search_term_ad_combination_view import ( + AiMaxSearchTermAdCombinationView, +) +from .types.android_privacy_shared_key_google_ad_group import ( + AndroidPrivacySharedKeyGoogleAdGroup, +) +from .types.android_privacy_shared_key_google_campaign import ( + AndroidPrivacySharedKeyGoogleCampaign, +) +from .types.android_privacy_shared_key_google_network_type import ( + AndroidPrivacySharedKeyGoogleNetworkType, +) +from .types.applied_incentive import AppliedIncentive +from .types.asset import Asset +from .types.asset import AssetFieldTypePolicySummary +from .types.asset import AssetPolicySummary +from .types.asset_field_type_view import AssetFieldTypeView +from .types.asset_group import AdStrengthActionItem +from .types.asset_group import AssetCoverage +from .types.asset_group import AssetGroup +from .types.asset_group_asset import AssetGroupAsset +from .types.asset_group_listing_group_filter import AssetGroupListingGroupFilter +from .types.asset_group_listing_group_filter import ListingGroupFilterDimension +from .types.asset_group_listing_group_filter import ( + ListingGroupFilterDimensionPath, +) +from .types.asset_group_product_group_view import AssetGroupProductGroupView +from .types.asset_group_signal import AssetGroupSignal +from .types.asset_group_top_combination_view import ( + AssetGroupAssetCombinationData, +) +from .types.asset_group_top_combination_view import AssetGroupTopCombinationView +from .types.asset_set import AssetSet +from .types.asset_set_asset import AssetSetAsset +from .types.asset_set_type_view import AssetSetTypeView +from .types.audience import Audience +from .types.batch_job import BatchJob +from .types.bidding_data_exclusion import BiddingDataExclusion +from .types.bidding_seasonality_adjustment import BiddingSeasonalityAdjustment +from .types.bidding_strategy import BiddingStrategy +from .types.bidding_strategy_simulation import BiddingStrategySimulation +from .types.billing_setup import BillingSetup +from .types.call_view import CallView +from .types.campaign import Campaign +from .types.campaign_aggregate_asset_view import CampaignAggregateAssetView +from .types.campaign_asset import CampaignAsset +from .types.campaign_asset_set import CampaignAssetSet +from .types.campaign_audience_view import CampaignAudienceView +from .types.campaign_bid_modifier import CampaignBidModifier +from .types.campaign_budget import CampaignBudget +from .types.campaign_conversion_goal import CampaignConversionGoal +from .types.campaign_criterion import CampaignCriterion +from .types.campaign_customizer import CampaignCustomizer +from .types.campaign_draft import CampaignDraft +from .types.campaign_goal_config import CampaignGoalConfig +from .types.campaign_group import CampaignGroup +from .types.campaign_label import CampaignLabel +from .types.campaign_lifecycle_goal import CampaignLifecycleGoal +from .types.campaign_lifecycle_goal import CustomerAcquisitionGoalSettings +from .types.campaign_search_term_insight import CampaignSearchTermInsight +from .types.campaign_search_term_view import CampaignSearchTermView +from .types.campaign_shared_set import CampaignSharedSet +from .types.campaign_simulation import CampaignSimulation +from .types.carrier_constant import CarrierConstant +from .types.change_event import ChangeEvent +from .types.change_status import ChangeStatus +from .types.channel_aggregate_asset_view import ChannelAggregateAssetView +from .types.click_view import ClickView +from .types.combined_audience import CombinedAudience +from .types.content_criterion_view import ContentCriterionView +from .types.conversion_action import ConversionAction +from .types.conversion_custom_variable import ConversionCustomVariable +from .types.conversion_goal_campaign_config import ConversionGoalCampaignConfig +from .types.conversion_value_rule import ConversionValueRule +from .types.conversion_value_rule_set import ConversionValueRuleSet +from .types.currency_constant import CurrencyConstant +from .types.custom_audience import CustomAudience +from .types.custom_audience import CustomAudienceMember +from .types.custom_conversion_goal import CustomConversionGoal +from .types.custom_interest import CustomInterest +from .types.custom_interest import CustomInterestMember +from .types.customer import CallReportingSetting +from .types.customer import ConversionTrackingSetting +from .types.customer import Customer +from .types.customer import CustomerAgreementSetting +from .types.customer import GranularInsuranceStatus +from .types.customer import GranularLicenseStatus +from .types.customer import LocalServicesSettings +from .types.customer import RemarketingSetting +from .types.customer import VideoCustomer +from .types.customer_asset import CustomerAsset +from .types.customer_asset_set import CustomerAssetSet +from .types.customer_client import CustomerClient +from .types.customer_client_link import CustomerClientLink +from .types.customer_conversion_goal import CustomerConversionGoal +from .types.customer_customizer import CustomerCustomizer +from .types.customer_label import CustomerLabel +from .types.customer_lifecycle_goal import CustomerLifecycleGoal +from .types.customer_manager_link import CustomerManagerLink +from .types.customer_negative_criterion import CustomerNegativeCriterion +from .types.customer_search_term_insight import CustomerSearchTermInsight +from .types.customer_sk_ad_network_conversion_value_schema import ( + CustomerSkAdNetworkConversionValueSchema, +) +from .types.customer_user_access import CustomerUserAccess +from .types.customer_user_access_invitation import CustomerUserAccessInvitation +from .types.customizer_attribute import CustomizerAttribute +from .types.data_link import DataLink +from .types.data_link import YoutubeVideoIdentifier +from .types.detail_content_suitability_placement_view import ( + DetailContentSuitabilityPlacementView, +) +from .types.detail_placement_view import DetailPlacementView +from .types.detailed_demographic import DetailedDemographic +from .types.display_keyword_view import DisplayKeywordView +from .types.distance_view import DistanceView +from .types.domain_category import DomainCategory +from .types.dynamic_search_ads_search_term_view import ( + DynamicSearchAdsSearchTermView, +) +from .types.expanded_landing_page_view import ExpandedLandingPageView +from .types.experiment import Experiment +from .types.experiment_arm import ExperimentArm +from .types.final_url_expansion_asset_view import FinalUrlExpansionAssetView +from .types.gender_view import GenderView +from .types.geo_target_constant import GeoTargetConstant +from .types.geographic_view import GeographicView +from .types.goal import Goal +from .types.google_ads_field import GoogleAdsField +from .types.group_content_suitability_placement_view import ( + GroupContentSuitabilityPlacementView, +) +from .types.group_placement_view import GroupPlacementView +from .types.hotel_group_view import HotelGroupView +from .types.hotel_performance_view import HotelPerformanceView +from .types.hotel_reconciliation import HotelReconciliation +from .types.income_range_view import IncomeRangeView +from .types.invoice import Invoice +from .types.keyword_plan import KeywordPlan +from .types.keyword_plan import KeywordPlanForecastPeriod +from .types.keyword_plan_ad_group import KeywordPlanAdGroup +from .types.keyword_plan_ad_group_keyword import KeywordPlanAdGroupKeyword +from .types.keyword_plan_campaign import KeywordPlanCampaign +from .types.keyword_plan_campaign import KeywordPlanGeoTarget +from .types.keyword_plan_campaign_keyword import KeywordPlanCampaignKeyword +from .types.keyword_theme_constant import KeywordThemeConstant +from .types.keyword_view import KeywordView +from .types.label import Label +from .types.landing_page_view import LandingPageView +from .types.language_constant import LanguageConstant +from .types.lead_form_submission_data import CustomLeadFormSubmissionField +from .types.lead_form_submission_data import LeadFormSubmissionData +from .types.lead_form_submission_data import LeadFormSubmissionField +from .types.life_event import LifeEvent +from .types.local_services_employee import Fellowship +from .types.local_services_employee import LocalServicesEmployee +from .types.local_services_employee import Residency +from .types.local_services_employee import UniversityDegree +from .types.local_services_lead import ContactDetails +from .types.local_services_lead import CreditDetails +from .types.local_services_lead import LocalServicesLead +from .types.local_services_lead import Note +from .types.local_services_lead_conversation import ( + LocalServicesLeadConversation, +) +from .types.local_services_lead_conversation import MessageDetails +from .types.local_services_lead_conversation import PhoneCallDetails +from .types.local_services_verification_artifact import ( + BackgroundCheckVerificationArtifact, +) +from .types.local_services_verification_artifact import ( + BusinessRegistrationCheckVerificationArtifact, +) +from .types.local_services_verification_artifact import ( + BusinessRegistrationDocument, +) +from .types.local_services_verification_artifact import ( + BusinessRegistrationNumber, +) +from .types.local_services_verification_artifact import ( + InsuranceVerificationArtifact, +) +from .types.local_services_verification_artifact import ( + LicenseVerificationArtifact, +) +from .types.local_services_verification_artifact import ( + LocalServicesVerificationArtifact, +) +from .types.location_interest_view import LocationInterestView +from .types.location_view import LocationView +from .types.managed_placement_view import ManagedPlacementView +from .types.matched_location_interest_view import MatchedLocationInterestView +from .types.media_file import MediaAudio +from .types.media_file import MediaBundle +from .types.media_file import MediaFile +from .types.media_file import MediaImage +from .types.media_file import MediaVideo +from .types.mobile_app_category_constant import MobileAppCategoryConstant +from .types.mobile_device_constant import MobileDeviceConstant +from .types.offline_conversion_upload_client_summary import ( + OfflineConversionAlert, +) +from .types.offline_conversion_upload_client_summary import ( + OfflineConversionError, +) +from .types.offline_conversion_upload_client_summary import ( + OfflineConversionSummary, +) +from .types.offline_conversion_upload_client_summary import ( + OfflineConversionUploadClientSummary, +) +from .types.offline_conversion_upload_conversion_action_summary import ( + OfflineConversionUploadConversionActionSummary, +) +from .types.offline_user_data_job import OfflineUserDataJob +from .types.offline_user_data_job import OfflineUserDataJobMetadata +from .types.operating_system_version_constant import ( + OperatingSystemVersionConstant, +) +from .types.paid_organic_search_term_view import PaidOrganicSearchTermView +from .types.parental_status_view import ParentalStatusView +from .types.payments_account import PaymentsAccount +from .types.per_store_view import PerStoreView +from .types.performance_max_placement_view import PerformanceMaxPlacementView +from .types.product_category_constant import ProductCategoryConstant +from .types.product_group_view import ProductGroupView +from .types.product_link import AdvertisingPartnerIdentifier +from .types.product_link import DataPartnerIdentifier +from .types.product_link import GoogleAdsIdentifier +from .types.product_link import MerchantCenterIdentifier +from .types.product_link import ProductLink +from .types.product_link_invitation import ( + AdvertisingPartnerLinkInvitationIdentifier, +) +from .types.product_link_invitation import HotelCenterLinkInvitationIdentifier +from .types.product_link_invitation import ( + MerchantCenterLinkInvitationIdentifier, +) +from .types.product_link_invitation import ProductLinkInvitation +from .types.qualifying_question import QualifyingQuestion +from .types.recommendation import Recommendation +from .types.recommendation_subscription import RecommendationSubscription +from .types.remarketing_action import RemarketingAction +from .types.search_term_view import SearchTermView +from .types.shared_criterion import SharedCriterion +from .types.shared_set import SharedSet +from .types.shopping_performance_view import ShoppingPerformanceView +from .types.shopping_product import ShoppingProduct +from .types.smart_campaign_search_term_view import SmartCampaignSearchTermView +from .types.smart_campaign_setting import SmartCampaignSetting +from .types.targeting_expansion_view import TargetingExpansionView +from .types.third_party_app_analytics_link import ThirdPartyAppAnalyticsLink +from .types.topic_constant import TopicConstant +from .types.topic_view import TopicView +from .types.travel_activity_group_view import TravelActivityGroupView +from .types.travel_activity_performance_view import ( + TravelActivityPerformanceView, +) +from .types.user_interest import UserInterest +from .types.user_list import UserList +from .types.user_list_customer_type import UserListCustomerType +from .types.user_location_view import UserLocationView +from .types.video import Video +from .types.webpage_view import WebpageView + +if hasattr(api_core, "check_python_version") and hasattr( + api_core, "check_dependency_versions" +): # pragma: NO COVER + api_core.check_python_version("google.ads.googleads.v23") # type: ignore + api_core.check_dependency_versions("google.ads.googleads.v23") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.ads.googleads.v23" + if sys.version_info < (3, 9): + warnings.warn( + "You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning, + ) + if sys.version_info[:2] == (3, 9): + warnings.warn( + f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning, + ) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version( + _dependency_package + ) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn( + f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning, + ) + except Exception: + warnings.warn( + "Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/" + ) + +__all__ = ( + "AccessibleBiddingStrategy", + "AccountBudget", + "AccountBudgetProposal", + "AccountLink", + "Ad", + "AdGroup", + "AdGroupAd", + "AdGroupAdAssetAutomationSetting", + "AdGroupAdAssetCombinationView", + "AdGroupAdAssetPolicySummary", + "AdGroupAdAssetView", + "AdGroupAdLabel", + "AdGroupAdPolicySummary", + "AdGroupAsset", + "AdGroupAssetSet", + "AdGroupAudienceView", + "AdGroupBidModifier", + "AdGroupCriterion", + "AdGroupCriterionCustomizer", + "AdGroupCriterionLabel", + "AdGroupCriterionSimulation", + "AdGroupCustomizer", + "AdGroupLabel", + "AdGroupSimulation", + "AdParameter", + "AdScheduleView", + "AdStrengthActionItem", + "AdvertisingPartnerIdentifier", + "AdvertisingPartnerLinkInvitationIdentifier", + "AgeRangeView", + "AiMaxSearchTermAdCombinationView", + "AndroidPrivacySharedKeyGoogleAdGroup", + "AndroidPrivacySharedKeyGoogleCampaign", + "AndroidPrivacySharedKeyGoogleNetworkType", + "AppliedIncentive", + "Asset", + "AssetCoverage", + "AssetFieldTypePolicySummary", + "AssetFieldTypeView", + "AssetGroup", + "AssetGroupAsset", + "AssetGroupAssetCombinationData", + "AssetGroupListingGroupFilter", + "AssetGroupProductGroupView", + "AssetGroupSignal", + "AssetGroupTopCombinationView", + "AssetPolicySummary", + "AssetSet", + "AssetSetAsset", + "AssetSetTypeView", + "Audience", + "BackgroundCheckVerificationArtifact", + "BatchJob", + "BiddingDataExclusion", + "BiddingSeasonalityAdjustment", + "BiddingStrategy", + "BiddingStrategySimulation", + "BillingSetup", + "BusinessRegistrationCheckVerificationArtifact", + "BusinessRegistrationDocument", + "BusinessRegistrationNumber", + "CallReportingSetting", + "CallView", + "Campaign", + "CampaignAggregateAssetView", + "CampaignAsset", + "CampaignAssetSet", + "CampaignAudienceView", + "CampaignBidModifier", + "CampaignBudget", + "CampaignConversionGoal", + "CampaignCriterion", + "CampaignCustomizer", + "CampaignDraft", + "CampaignGoalConfig", + "CampaignGroup", + "CampaignLabel", + "CampaignLifecycleGoal", + "CampaignSearchTermInsight", + "CampaignSearchTermView", + "CampaignSharedSet", + "CampaignSimulation", + "CarrierConstant", + "ChangeEvent", + "ChangeStatus", + "ChannelAggregateAssetView", + "ClickView", + "CombinedAudience", + "ContactDetails", + "ContentCriterionView", + "ConversionAction", + "ConversionCustomVariable", + "ConversionGoalCampaignConfig", + "ConversionTrackingSetting", + "ConversionValueRule", + "ConversionValueRuleSet", + "CreditDetails", + "CurrencyConstant", + "CustomAudience", + "CustomAudienceMember", + "CustomConversionGoal", + "CustomInterest", + "CustomInterestMember", + "CustomLeadFormSubmissionField", + "Customer", + "CustomerAcquisitionGoalSettings", + "CustomerAgreementSetting", + "CustomerAsset", + "CustomerAssetSet", + "CustomerClient", + "CustomerClientLink", + "CustomerConversionGoal", + "CustomerCustomizer", + "CustomerLabel", + "CustomerLifecycleGoal", + "CustomerManagerLink", + "CustomerNegativeCriterion", + "CustomerSearchTermInsight", + "CustomerSkAdNetworkConversionValueSchema", + "CustomerUserAccess", + "CustomerUserAccessInvitation", + "CustomizerAttribute", + "DataLink", + "DataPartnerIdentifier", + "DetailContentSuitabilityPlacementView", + "DetailPlacementView", + "DetailedDemographic", + "DisplayKeywordView", + "DistanceView", + "DomainCategory", + "DynamicSearchAdsSearchTermView", + "ExpandedLandingPageView", + "Experiment", + "ExperimentArm", + "Fellowship", + "FinalUrlExpansionAssetView", + "GenderView", + "GeoTargetConstant", + "GeographicView", + "Goal", + "GoogleAdsField", + "GoogleAdsIdentifier", + "GranularInsuranceStatus", + "GranularLicenseStatus", + "GroupContentSuitabilityPlacementView", + "GroupPlacementView", + "HotelCenterLinkInvitationIdentifier", + "HotelGroupView", + "HotelPerformanceView", + "HotelReconciliation", + "IncomeRangeView", + "InsuranceVerificationArtifact", + "Invoice", + "KeywordPlan", + "KeywordPlanAdGroup", + "KeywordPlanAdGroupKeyword", + "KeywordPlanCampaign", + "KeywordPlanCampaignKeyword", + "KeywordPlanForecastPeriod", + "KeywordPlanGeoTarget", + "KeywordThemeConstant", + "KeywordView", + "Label", + "LandingPageView", + "LanguageConstant", + "LeadFormSubmissionData", + "LeadFormSubmissionField", + "LicenseVerificationArtifact", + "LifeEvent", + "ListingGroupFilterDimension", + "ListingGroupFilterDimensionPath", + "LocalServicesEmployee", + "LocalServicesLead", + "LocalServicesLeadConversation", + "LocalServicesSettings", + "LocalServicesVerificationArtifact", + "LocationInterestView", + "LocationView", + "ManagedPlacementView", + "MatchedLocationInterestView", + "MediaAudio", + "MediaBundle", + "MediaFile", + "MediaImage", + "MediaVideo", + "MerchantCenterIdentifier", + "MerchantCenterLinkInvitationIdentifier", + "MessageDetails", + "MobileAppCategoryConstant", + "MobileDeviceConstant", + "Note", + "OfflineConversionAlert", + "OfflineConversionError", + "OfflineConversionSummary", + "OfflineConversionUploadClientSummary", + "OfflineConversionUploadConversionActionSummary", + "OfflineUserDataJob", + "OfflineUserDataJobMetadata", + "OperatingSystemVersionConstant", + "PaidOrganicSearchTermView", + "ParentalStatusView", + "PaymentsAccount", + "PerStoreView", + "PerformanceMaxPlacementView", + "PhoneCallDetails", + "ProductCategoryConstant", + "ProductGroupView", + "ProductLink", + "ProductLinkInvitation", + "QualifyingQuestion", + "Recommendation", + "RecommendationSubscription", + "RemarketingAction", + "RemarketingSetting", + "Residency", + "SearchTermView", + "SharedCriterion", + "SharedSet", + "ShoppingPerformanceView", + "ShoppingProduct", + "SmartCampaignSearchTermView", + "SmartCampaignSetting", + "TargetingExpansionView", + "ThirdPartyAppAnalyticsLink", + "ThirdPartyAppAnalyticsLinkIdentifier", + "TopicConstant", + "TopicView", + "TravelActivityGroupView", + "TravelActivityPerformanceView", + "UniversityDegree", + "UserInterest", + "UserList", + "UserListCustomerType", + "UserLocationView", + "Video", + "VideoCustomer", + "WebpageView", + "YoutubeVideoIdentifier", +) diff --git a/google/ads/googleads/v19/resources/services/__init__.py b/google/ads/googleads/v23/resources/services/__init__.py similarity index 100% rename from google/ads/googleads/v19/resources/services/__init__.py rename to google/ads/googleads/v23/resources/services/__init__.py diff --git a/google/ads/googleads/v23/resources/types/__init__.py b/google/ads/googleads/v23/resources/types/__init__.py new file mode 100644 index 000000000..3cc9fc737 --- /dev/null +++ b/google/ads/googleads/v23/resources/types/__init__.py @@ -0,0 +1,858 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .accessible_bidding_strategy import ( + AccessibleBiddingStrategy, +) +from .account_budget import ( + AccountBudget, +) +from .account_budget_proposal import ( + AccountBudgetProposal, +) +from .account_link import ( + AccountLink, + ThirdPartyAppAnalyticsLinkIdentifier, +) +from .ad import ( + Ad, +) +from .ad_group import ( + AdGroup, +) +from .ad_group_ad import ( + AdGroupAd, + AdGroupAdAssetAutomationSetting, + AdGroupAdPolicySummary, +) +from .ad_group_ad_asset_combination_view import ( + AdGroupAdAssetCombinationView, +) +from .ad_group_ad_asset_view import ( + AdGroupAdAssetPolicySummary, + AdGroupAdAssetView, +) +from .ad_group_ad_label import ( + AdGroupAdLabel, +) +from .ad_group_asset import ( + AdGroupAsset, +) +from .ad_group_asset_set import ( + AdGroupAssetSet, +) +from .ad_group_audience_view import ( + AdGroupAudienceView, +) +from .ad_group_bid_modifier import ( + AdGroupBidModifier, +) +from .ad_group_criterion import ( + AdGroupCriterion, +) +from .ad_group_criterion_customizer import ( + AdGroupCriterionCustomizer, +) +from .ad_group_criterion_label import ( + AdGroupCriterionLabel, +) +from .ad_group_criterion_simulation import ( + AdGroupCriterionSimulation, +) +from .ad_group_customizer import ( + AdGroupCustomizer, +) +from .ad_group_label import ( + AdGroupLabel, +) +from .ad_group_simulation import ( + AdGroupSimulation, +) +from .ad_parameter import ( + AdParameter, +) +from .ad_schedule_view import ( + AdScheduleView, +) +from .age_range_view import ( + AgeRangeView, +) +from .ai_max_search_term_ad_combination_view import ( + AiMaxSearchTermAdCombinationView, +) +from .android_privacy_shared_key_google_ad_group import ( + AndroidPrivacySharedKeyGoogleAdGroup, +) +from .android_privacy_shared_key_google_campaign import ( + AndroidPrivacySharedKeyGoogleCampaign, +) +from .android_privacy_shared_key_google_network_type import ( + AndroidPrivacySharedKeyGoogleNetworkType, +) +from .applied_incentive import ( + AppliedIncentive, +) +from .asset import ( + Asset, + AssetFieldTypePolicySummary, + AssetPolicySummary, +) +from .asset_field_type_view import ( + AssetFieldTypeView, +) +from .asset_group import ( + AdStrengthActionItem, + AssetCoverage, + AssetGroup, +) +from .asset_group_asset import ( + AssetGroupAsset, +) +from .asset_group_listing_group_filter import ( + AssetGroupListingGroupFilter, + ListingGroupFilterDimension, + ListingGroupFilterDimensionPath, +) +from .asset_group_product_group_view import ( + AssetGroupProductGroupView, +) +from .asset_group_signal import ( + AssetGroupSignal, +) +from .asset_group_top_combination_view import ( + AssetGroupAssetCombinationData, + AssetGroupTopCombinationView, +) +from .asset_set import ( + AssetSet, +) +from .asset_set_asset import ( + AssetSetAsset, +) +from .asset_set_type_view import ( + AssetSetTypeView, +) +from .audience import ( + Audience, +) +from .batch_job import ( + BatchJob, +) +from .bidding_data_exclusion import ( + BiddingDataExclusion, +) +from .bidding_seasonality_adjustment import ( + BiddingSeasonalityAdjustment, +) +from .bidding_strategy import ( + BiddingStrategy, +) +from .bidding_strategy_simulation import ( + BiddingStrategySimulation, +) +from .billing_setup import ( + BillingSetup, +) +from .call_view import ( + CallView, +) +from .campaign import ( + Campaign, +) +from .campaign_aggregate_asset_view import ( + CampaignAggregateAssetView, +) +from .campaign_asset import ( + CampaignAsset, +) +from .campaign_asset_set import ( + CampaignAssetSet, +) +from .campaign_audience_view import ( + CampaignAudienceView, +) +from .campaign_bid_modifier import ( + CampaignBidModifier, +) +from .campaign_budget import ( + CampaignBudget, +) +from .campaign_conversion_goal import ( + CampaignConversionGoal, +) +from .campaign_criterion import ( + CampaignCriterion, +) +from .campaign_customizer import ( + CampaignCustomizer, +) +from .campaign_draft import ( + CampaignDraft, +) +from .campaign_goal_config import ( + CampaignGoalConfig, +) +from .campaign_group import ( + CampaignGroup, +) +from .campaign_label import ( + CampaignLabel, +) +from .campaign_lifecycle_goal import ( + CampaignLifecycleGoal, + CustomerAcquisitionGoalSettings, +) +from .campaign_search_term_insight import ( + CampaignSearchTermInsight, +) +from .campaign_search_term_view import ( + CampaignSearchTermView, +) +from .campaign_shared_set import ( + CampaignSharedSet, +) +from .campaign_simulation import ( + CampaignSimulation, +) +from .carrier_constant import ( + CarrierConstant, +) +from .change_event import ( + ChangeEvent, +) +from .change_status import ( + ChangeStatus, +) +from .channel_aggregate_asset_view import ( + ChannelAggregateAssetView, +) +from .click_view import ( + ClickView, +) +from .combined_audience import ( + CombinedAudience, +) +from .content_criterion_view import ( + ContentCriterionView, +) +from .conversion_action import ( + ConversionAction, +) +from .conversion_custom_variable import ( + ConversionCustomVariable, +) +from .conversion_goal_campaign_config import ( + ConversionGoalCampaignConfig, +) +from .conversion_value_rule import ( + ConversionValueRule, +) +from .conversion_value_rule_set import ( + ConversionValueRuleSet, +) +from .currency_constant import ( + CurrencyConstant, +) +from .custom_audience import ( + CustomAudience, + CustomAudienceMember, +) +from .custom_conversion_goal import ( + CustomConversionGoal, +) +from .custom_interest import ( + CustomInterest, + CustomInterestMember, +) +from .customer import ( + CallReportingSetting, + ConversionTrackingSetting, + Customer, + CustomerAgreementSetting, + GranularInsuranceStatus, + GranularLicenseStatus, + LocalServicesSettings, + RemarketingSetting, + VideoCustomer, +) +from .customer_asset import ( + CustomerAsset, +) +from .customer_asset_set import ( + CustomerAssetSet, +) +from .customer_client import ( + CustomerClient, +) +from .customer_client_link import ( + CustomerClientLink, +) +from .customer_conversion_goal import ( + CustomerConversionGoal, +) +from .customer_customizer import ( + CustomerCustomizer, +) +from .customer_label import ( + CustomerLabel, +) +from .customer_lifecycle_goal import ( + CustomerLifecycleGoal, +) +from .customer_manager_link import ( + CustomerManagerLink, +) +from .customer_negative_criterion import ( + CustomerNegativeCriterion, +) +from .customer_search_term_insight import ( + CustomerSearchTermInsight, +) +from .customer_sk_ad_network_conversion_value_schema import ( + CustomerSkAdNetworkConversionValueSchema, +) +from .customer_user_access import ( + CustomerUserAccess, +) +from .customer_user_access_invitation import ( + CustomerUserAccessInvitation, +) +from .customizer_attribute import ( + CustomizerAttribute, +) +from .data_link import ( + DataLink, + YoutubeVideoIdentifier, +) +from .detail_content_suitability_placement_view import ( + DetailContentSuitabilityPlacementView, +) +from .detail_placement_view import ( + DetailPlacementView, +) +from .detailed_demographic import ( + DetailedDemographic, +) +from .display_keyword_view import ( + DisplayKeywordView, +) +from .distance_view import ( + DistanceView, +) +from .domain_category import ( + DomainCategory, +) +from .dynamic_search_ads_search_term_view import ( + DynamicSearchAdsSearchTermView, +) +from .expanded_landing_page_view import ( + ExpandedLandingPageView, +) +from .experiment import ( + Experiment, +) +from .experiment_arm import ( + ExperimentArm, +) +from .final_url_expansion_asset_view import ( + FinalUrlExpansionAssetView, +) +from .gender_view import ( + GenderView, +) +from .geo_target_constant import ( + GeoTargetConstant, +) +from .geographic_view import ( + GeographicView, +) +from .goal import ( + Goal, +) +from .google_ads_field import ( + GoogleAdsField, +) +from .group_content_suitability_placement_view import ( + GroupContentSuitabilityPlacementView, +) +from .group_placement_view import ( + GroupPlacementView, +) +from .hotel_group_view import ( + HotelGroupView, +) +from .hotel_performance_view import ( + HotelPerformanceView, +) +from .hotel_reconciliation import ( + HotelReconciliation, +) +from .income_range_view import ( + IncomeRangeView, +) +from .invoice import ( + Invoice, +) +from .keyword_plan import ( + KeywordPlan, + KeywordPlanForecastPeriod, +) +from .keyword_plan_ad_group import ( + KeywordPlanAdGroup, +) +from .keyword_plan_ad_group_keyword import ( + KeywordPlanAdGroupKeyword, +) +from .keyword_plan_campaign import ( + KeywordPlanCampaign, + KeywordPlanGeoTarget, +) +from .keyword_plan_campaign_keyword import ( + KeywordPlanCampaignKeyword, +) +from .keyword_theme_constant import ( + KeywordThemeConstant, +) +from .keyword_view import ( + KeywordView, +) +from .label import ( + Label, +) +from .landing_page_view import ( + LandingPageView, +) +from .language_constant import ( + LanguageConstant, +) +from .lead_form_submission_data import ( + CustomLeadFormSubmissionField, + LeadFormSubmissionData, + LeadFormSubmissionField, +) +from .life_event import ( + LifeEvent, +) +from .local_services_employee import ( + Fellowship, + LocalServicesEmployee, + Residency, + UniversityDegree, +) +from .local_services_lead import ( + ContactDetails, + CreditDetails, + LocalServicesLead, + Note, +) +from .local_services_lead_conversation import ( + LocalServicesLeadConversation, + MessageDetails, + PhoneCallDetails, +) +from .local_services_verification_artifact import ( + BackgroundCheckVerificationArtifact, + BusinessRegistrationCheckVerificationArtifact, + BusinessRegistrationDocument, + BusinessRegistrationNumber, + InsuranceVerificationArtifact, + LicenseVerificationArtifact, + LocalServicesVerificationArtifact, +) +from .location_interest_view import ( + LocationInterestView, +) +from .location_view import ( + LocationView, +) +from .managed_placement_view import ( + ManagedPlacementView, +) +from .matched_location_interest_view import ( + MatchedLocationInterestView, +) +from .media_file import ( + MediaAudio, + MediaBundle, + MediaFile, + MediaImage, + MediaVideo, +) +from .mobile_app_category_constant import ( + MobileAppCategoryConstant, +) +from .mobile_device_constant import ( + MobileDeviceConstant, +) +from .offline_conversion_upload_client_summary import ( + OfflineConversionAlert, + OfflineConversionError, + OfflineConversionSummary, + OfflineConversionUploadClientSummary, +) +from .offline_conversion_upload_conversion_action_summary import ( + OfflineConversionUploadConversionActionSummary, +) +from .offline_user_data_job import ( + OfflineUserDataJob, + OfflineUserDataJobMetadata, +) +from .operating_system_version_constant import ( + OperatingSystemVersionConstant, +) +from .paid_organic_search_term_view import ( + PaidOrganicSearchTermView, +) +from .parental_status_view import ( + ParentalStatusView, +) +from .payments_account import ( + PaymentsAccount, +) +from .per_store_view import ( + PerStoreView, +) +from .performance_max_placement_view import ( + PerformanceMaxPlacementView, +) +from .product_category_constant import ( + ProductCategoryConstant, +) +from .product_group_view import ( + ProductGroupView, +) +from .product_link import ( + AdvertisingPartnerIdentifier, + DataPartnerIdentifier, + GoogleAdsIdentifier, + MerchantCenterIdentifier, + ProductLink, +) +from .product_link_invitation import ( + AdvertisingPartnerLinkInvitationIdentifier, + HotelCenterLinkInvitationIdentifier, + MerchantCenterLinkInvitationIdentifier, + ProductLinkInvitation, +) +from .qualifying_question import ( + QualifyingQuestion, +) +from .recommendation import ( + Recommendation, +) +from .recommendation_subscription import ( + RecommendationSubscription, +) +from .remarketing_action import ( + RemarketingAction, +) +from .search_term_view import ( + SearchTermView, +) +from .shared_criterion import ( + SharedCriterion, +) +from .shared_set import ( + SharedSet, +) +from .shopping_performance_view import ( + ShoppingPerformanceView, +) +from .shopping_product import ( + ShoppingProduct, +) +from .smart_campaign_search_term_view import ( + SmartCampaignSearchTermView, +) +from .smart_campaign_setting import ( + SmartCampaignSetting, +) +from .targeting_expansion_view import ( + TargetingExpansionView, +) +from .third_party_app_analytics_link import ( + ThirdPartyAppAnalyticsLink, +) +from .topic_constant import ( + TopicConstant, +) +from .topic_view import ( + TopicView, +) +from .travel_activity_group_view import ( + TravelActivityGroupView, +) +from .travel_activity_performance_view import ( + TravelActivityPerformanceView, +) +from .user_interest import ( + UserInterest, +) +from .user_list import ( + UserList, +) +from .user_list_customer_type import ( + UserListCustomerType, +) +from .user_location_view import ( + UserLocationView, +) +from .video import ( + Video, +) +from .webpage_view import ( + WebpageView, +) + +__all__ = ( + "AccessibleBiddingStrategy", + "AccountBudget", + "AccountBudgetProposal", + "AccountLink", + "ThirdPartyAppAnalyticsLinkIdentifier", + "Ad", + "AdGroup", + "AdGroupAd", + "AdGroupAdAssetAutomationSetting", + "AdGroupAdPolicySummary", + "AdGroupAdAssetCombinationView", + "AdGroupAdAssetPolicySummary", + "AdGroupAdAssetView", + "AdGroupAdLabel", + "AdGroupAsset", + "AdGroupAssetSet", + "AdGroupAudienceView", + "AdGroupBidModifier", + "AdGroupCriterion", + "AdGroupCriterionCustomizer", + "AdGroupCriterionLabel", + "AdGroupCriterionSimulation", + "AdGroupCustomizer", + "AdGroupLabel", + "AdGroupSimulation", + "AdParameter", + "AdScheduleView", + "AgeRangeView", + "AiMaxSearchTermAdCombinationView", + "AndroidPrivacySharedKeyGoogleAdGroup", + "AndroidPrivacySharedKeyGoogleCampaign", + "AndroidPrivacySharedKeyGoogleNetworkType", + "AppliedIncentive", + "Asset", + "AssetFieldTypePolicySummary", + "AssetPolicySummary", + "AssetFieldTypeView", + "AdStrengthActionItem", + "AssetCoverage", + "AssetGroup", + "AssetGroupAsset", + "AssetGroupListingGroupFilter", + "ListingGroupFilterDimension", + "ListingGroupFilterDimensionPath", + "AssetGroupProductGroupView", + "AssetGroupSignal", + "AssetGroupAssetCombinationData", + "AssetGroupTopCombinationView", + "AssetSet", + "AssetSetAsset", + "AssetSetTypeView", + "Audience", + "BatchJob", + "BiddingDataExclusion", + "BiddingSeasonalityAdjustment", + "BiddingStrategy", + "BiddingStrategySimulation", + "BillingSetup", + "CallView", + "Campaign", + "CampaignAggregateAssetView", + "CampaignAsset", + "CampaignAssetSet", + "CampaignAudienceView", + "CampaignBidModifier", + "CampaignBudget", + "CampaignConversionGoal", + "CampaignCriterion", + "CampaignCustomizer", + "CampaignDraft", + "CampaignGoalConfig", + "CampaignGroup", + "CampaignLabel", + "CampaignLifecycleGoal", + "CustomerAcquisitionGoalSettings", + "CampaignSearchTermInsight", + "CampaignSearchTermView", + "CampaignSharedSet", + "CampaignSimulation", + "CarrierConstant", + "ChangeEvent", + "ChangeStatus", + "ChannelAggregateAssetView", + "ClickView", + "CombinedAudience", + "ContentCriterionView", + "ConversionAction", + "ConversionCustomVariable", + "ConversionGoalCampaignConfig", + "ConversionValueRule", + "ConversionValueRuleSet", + "CurrencyConstant", + "CustomAudience", + "CustomAudienceMember", + "CustomConversionGoal", + "CustomInterest", + "CustomInterestMember", + "CallReportingSetting", + "ConversionTrackingSetting", + "Customer", + "CustomerAgreementSetting", + "GranularInsuranceStatus", + "GranularLicenseStatus", + "LocalServicesSettings", + "RemarketingSetting", + "VideoCustomer", + "CustomerAsset", + "CustomerAssetSet", + "CustomerClient", + "CustomerClientLink", + "CustomerConversionGoal", + "CustomerCustomizer", + "CustomerLabel", + "CustomerLifecycleGoal", + "CustomerManagerLink", + "CustomerNegativeCriterion", + "CustomerSearchTermInsight", + "CustomerSkAdNetworkConversionValueSchema", + "CustomerUserAccess", + "CustomerUserAccessInvitation", + "CustomizerAttribute", + "DataLink", + "YoutubeVideoIdentifier", + "DetailContentSuitabilityPlacementView", + "DetailPlacementView", + "DetailedDemographic", + "DisplayKeywordView", + "DistanceView", + "DomainCategory", + "DynamicSearchAdsSearchTermView", + "ExpandedLandingPageView", + "Experiment", + "ExperimentArm", + "FinalUrlExpansionAssetView", + "GenderView", + "GeoTargetConstant", + "GeographicView", + "Goal", + "GoogleAdsField", + "GroupContentSuitabilityPlacementView", + "GroupPlacementView", + "HotelGroupView", + "HotelPerformanceView", + "HotelReconciliation", + "IncomeRangeView", + "Invoice", + "KeywordPlan", + "KeywordPlanForecastPeriod", + "KeywordPlanAdGroup", + "KeywordPlanAdGroupKeyword", + "KeywordPlanCampaign", + "KeywordPlanGeoTarget", + "KeywordPlanCampaignKeyword", + "KeywordThemeConstant", + "KeywordView", + "Label", + "LandingPageView", + "LanguageConstant", + "CustomLeadFormSubmissionField", + "LeadFormSubmissionData", + "LeadFormSubmissionField", + "LifeEvent", + "Fellowship", + "LocalServicesEmployee", + "Residency", + "UniversityDegree", + "ContactDetails", + "CreditDetails", + "LocalServicesLead", + "Note", + "LocalServicesLeadConversation", + "MessageDetails", + "PhoneCallDetails", + "BackgroundCheckVerificationArtifact", + "BusinessRegistrationCheckVerificationArtifact", + "BusinessRegistrationDocument", + "BusinessRegistrationNumber", + "InsuranceVerificationArtifact", + "LicenseVerificationArtifact", + "LocalServicesVerificationArtifact", + "LocationInterestView", + "LocationView", + "ManagedPlacementView", + "MatchedLocationInterestView", + "MediaAudio", + "MediaBundle", + "MediaFile", + "MediaImage", + "MediaVideo", + "MobileAppCategoryConstant", + "MobileDeviceConstant", + "OfflineConversionAlert", + "OfflineConversionError", + "OfflineConversionSummary", + "OfflineConversionUploadClientSummary", + "OfflineConversionUploadConversionActionSummary", + "OfflineUserDataJob", + "OfflineUserDataJobMetadata", + "OperatingSystemVersionConstant", + "PaidOrganicSearchTermView", + "ParentalStatusView", + "PaymentsAccount", + "PerStoreView", + "PerformanceMaxPlacementView", + "ProductCategoryConstant", + "ProductGroupView", + "AdvertisingPartnerIdentifier", + "DataPartnerIdentifier", + "GoogleAdsIdentifier", + "MerchantCenterIdentifier", + "ProductLink", + "AdvertisingPartnerLinkInvitationIdentifier", + "HotelCenterLinkInvitationIdentifier", + "MerchantCenterLinkInvitationIdentifier", + "ProductLinkInvitation", + "QualifyingQuestion", + "Recommendation", + "RecommendationSubscription", + "RemarketingAction", + "SearchTermView", + "SharedCriterion", + "SharedSet", + "ShoppingPerformanceView", + "ShoppingProduct", + "SmartCampaignSearchTermView", + "SmartCampaignSetting", + "TargetingExpansionView", + "ThirdPartyAppAnalyticsLink", + "TopicConstant", + "TopicView", + "TravelActivityGroupView", + "TravelActivityPerformanceView", + "UserInterest", + "UserList", + "UserListCustomerType", + "UserLocationView", + "Video", + "WebpageView", +) diff --git a/google/ads/googleads/v19/resources/types/accessible_bidding_strategy.py b/google/ads/googleads/v23/resources/types/accessible_bidding_strategy.py similarity index 94% rename from google/ads/googleads/v19/resources/types/accessible_bidding_strategy.py rename to google/ads/googleads/v23/resources/types/accessible_bidding_strategy.py index 48a285889..dcd0cb83f 100644 --- a/google/ads/googleads/v19/resources/types/accessible_bidding_strategy.py +++ b/google/ads/googleads/v23/resources/types/accessible_bidding_strategy.py @@ -18,15 +18,15 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import bidding_strategy_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import bidding_strategy_type +from google.ads.googleads.v23.enums.types import ( target_impression_share_location, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AccessibleBiddingStrategy", }, @@ -61,7 +61,7 @@ class AccessibleBiddingStrategy(proto.Message): name (str): Output only. The name of the bidding strategy. - type_ (google.ads.googleads.v19.enums.types.BiddingStrategyTypeEnum.BiddingStrategyType): + type_ (google.ads.googleads.v23.enums.types.BiddingStrategyTypeEnum.BiddingStrategyType): Output only. The type of the bidding strategy. owner_customer_id (int): @@ -70,38 +70,38 @@ class AccessibleBiddingStrategy(proto.Message): owner_descriptive_name (str): Output only. descriptive_name of the Customer which owns the bidding strategy. - maximize_conversion_value (google.ads.googleads.v19.resources.types.AccessibleBiddingStrategy.MaximizeConversionValue): + maximize_conversion_value (google.ads.googleads.v23.resources.types.AccessibleBiddingStrategy.MaximizeConversionValue): Output only. An automated bidding strategy to help get the most conversion value for your campaigns while spending your budget. This field is a member of `oneof`_ ``scheme``. - maximize_conversions (google.ads.googleads.v19.resources.types.AccessibleBiddingStrategy.MaximizeConversions): + maximize_conversions (google.ads.googleads.v23.resources.types.AccessibleBiddingStrategy.MaximizeConversions): Output only. An automated bidding strategy to help get the most conversions for your campaigns while spending your budget. This field is a member of `oneof`_ ``scheme``. - target_cpa (google.ads.googleads.v19.resources.types.AccessibleBiddingStrategy.TargetCpa): + target_cpa (google.ads.googleads.v23.resources.types.AccessibleBiddingStrategy.TargetCpa): Output only. A bidding strategy that sets bids to help get as many conversions as possible at the target cost-per-acquisition (CPA) you set. This field is a member of `oneof`_ ``scheme``. - target_impression_share (google.ads.googleads.v19.resources.types.AccessibleBiddingStrategy.TargetImpressionShare): + target_impression_share (google.ads.googleads.v23.resources.types.AccessibleBiddingStrategy.TargetImpressionShare): Output only. A bidding strategy that automatically optimizes towards a chosen percentage of impressions. This field is a member of `oneof`_ ``scheme``. - target_roas (google.ads.googleads.v19.resources.types.AccessibleBiddingStrategy.TargetRoas): + target_roas (google.ads.googleads.v23.resources.types.AccessibleBiddingStrategy.TargetRoas): Output only. A bidding strategy that helps you maximize revenue while averaging a specific target Return On Ad Spend (ROAS). This field is a member of `oneof`_ ``scheme``. - target_spend (google.ads.googleads.v19.resources.types.AccessibleBiddingStrategy.TargetSpend): + target_spend (google.ads.googleads.v23.resources.types.AccessibleBiddingStrategy.TargetSpend): Output only. A bid strategy that sets your bids to help get as many clicks as possible within your budget. @@ -179,7 +179,7 @@ class TargetImpressionShare(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - location (google.ads.googleads.v19.enums.types.TargetImpressionShareLocationEnum.TargetImpressionShareLocation): + location (google.ads.googleads.v23.enums.types.TargetImpressionShareLocationEnum.TargetImpressionShareLocation): Output only. The targeted location on the search results page. location_fraction_micros (int): diff --git a/google/ads/googleads/v19/resources/types/account_budget.py b/google/ads/googleads/v23/resources/types/account_budget.py similarity index 93% rename from google/ads/googleads/v19/resources/types/account_budget.py rename to google/ads/googleads/v23/resources/types/account_budget.py index 8894e61c9..d82ea2ce4 100644 --- a/google/ads/googleads/v19/resources/types/account_budget.py +++ b/google/ads/googleads/v23/resources/types/account_budget.py @@ -18,17 +18,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import account_budget_proposal_type -from google.ads.googleads.v19.enums.types import account_budget_status -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import account_budget_proposal_type +from google.ads.googleads.v23.enums.types import account_budget_status +from google.ads.googleads.v23.enums.types import ( spending_limit_type as gage_spending_limit_type, ) -from google.ads.googleads.v19.enums.types import time_type +from google.ads.googleads.v23.enums.types import time_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AccountBudget", }, @@ -41,11 +41,11 @@ class AccountBudget(proto.Message): and proposed changes that are pending approval. The proposed changes that are pending approval, if any, are found in 'pending_proposal'. Effective details about the budget are found in fields prefixed - 'approved_', 'adjusted_' and those without a prefix. Since some + 'approved\_', 'adjusted\_' and those without a prefix. Since some effective details may differ from what the user had originally requested (for example, spending limit), these differences are - juxtaposed through 'proposed_', 'approved_', and possibly - 'adjusted_' fields. + juxtaposed through 'proposed\_', 'approved\_', and possibly + 'adjusted\_' fields. This resource is mutated using AccountBudgetProposal and cannot be mutated directly. A budget may have at most one pending proposal at @@ -82,7 +82,7 @@ class AccountBudget(proto.Message): ``customers/{customer_id}/billingSetups/{billing_setup_id}`` This field is a member of `oneof`_ ``_billing_setup``. - status (google.ads.googleads.v19.enums.types.AccountBudgetStatusEnum.AccountBudgetStatus): + status (google.ads.googleads.v23.enums.types.AccountBudgetStatusEnum.AccountBudgetStatus): Output only. The status of this account-level budget. name (str): @@ -129,7 +129,7 @@ class AccountBudget(proto.Message): budget. This field is a member of `oneof`_ ``_notes``. - pending_proposal (google.ads.googleads.v19.resources.types.AccountBudget.PendingAccountBudgetProposal): + pending_proposal (google.ads.googleads.v23.resources.types.AccountBudget.PendingAccountBudgetProposal): Output only. The pending proposal to modify this budget, if applicable. proposed_end_date_time (str): @@ -137,7 +137,7 @@ class AccountBudget(proto.Message): yyyy-MM-dd HH:mm:ss format. This field is a member of `oneof`_ ``proposed_end_time``. - proposed_end_time_type (google.ads.googleads.v19.enums.types.TimeTypeEnum.TimeType): + proposed_end_time_type (google.ads.googleads.v23.enums.types.TimeTypeEnum.TimeType): Output only. The proposed end time as a well-defined type, for example, FOREVER. @@ -147,7 +147,7 @@ class AccountBudget(proto.Message): yyyy-MM-dd HH:mm:ss format. This field is a member of `oneof`_ ``approved_end_time``. - approved_end_time_type (google.ads.googleads.v19.enums.types.TimeTypeEnum.TimeType): + approved_end_time_type (google.ads.googleads.v23.enums.types.TimeTypeEnum.TimeType): Output only. The approved end time as a well-defined type, for example, FOREVER. @@ -157,7 +157,7 @@ class AccountBudget(proto.Message): micros. One million is equivalent to one unit. This field is a member of `oneof`_ ``proposed_spending_limit``. - proposed_spending_limit_type (google.ads.googleads.v19.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + proposed_spending_limit_type (google.ads.googleads.v23.enums.types.SpendingLimitTypeEnum.SpendingLimitType): Output only. The proposed spending limit as a well-defined type, for example, INFINITE. @@ -171,7 +171,7 @@ class AccountBudget(proto.Message): limit. This field is a member of `oneof`_ ``approved_spending_limit``. - approved_spending_limit_type (google.ads.googleads.v19.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + approved_spending_limit_type (google.ads.googleads.v23.enums.types.SpendingLimitTypeEnum.SpendingLimitType): Output only. The approved spending limit as a well-defined type, for example, INFINITE. This will only be populated if the approved spending @@ -196,7 +196,7 @@ class AccountBudget(proto.Message): the account is allowed to spend. This field is a member of `oneof`_ ``adjusted_spending_limit``. - adjusted_spending_limit_type (google.ads.googleads.v19.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + adjusted_spending_limit_type (google.ads.googleads.v23.enums.types.SpendingLimitTypeEnum.SpendingLimitType): Output only. The adjusted spending limit as a well-defined type, for example, INFINITE. This will only be populated if the adjusted spending @@ -225,7 +225,7 @@ class PendingAccountBudgetProposal(proto.Message): ``customers/{customer_id}/accountBudgetProposals/{account_budget_proposal_id}`` This field is a member of `oneof`_ ``_account_budget_proposal``. - proposal_type (google.ads.googleads.v19.enums.types.AccountBudgetProposalTypeEnum.AccountBudgetProposalType): + proposal_type (google.ads.googleads.v23.enums.types.AccountBudgetProposalTypeEnum.AccountBudgetProposalType): Output only. The type of this proposal, for example, END to end the budget associated with this proposal. @@ -261,7 +261,7 @@ class PendingAccountBudgetProposal(proto.Message): HH:mm:ss format. This field is a member of `oneof`_ ``end_time``. - end_time_type (google.ads.googleads.v19.enums.types.TimeTypeEnum.TimeType): + end_time_type (google.ads.googleads.v23.enums.types.TimeTypeEnum.TimeType): Output only. The end time as a well-defined type, for example, FOREVER. @@ -271,7 +271,7 @@ class PendingAccountBudgetProposal(proto.Message): One million is equivalent to one unit. This field is a member of `oneof`_ ``spending_limit``. - spending_limit_type (google.ads.googleads.v19.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + spending_limit_type (google.ads.googleads.v23.enums.types.SpendingLimitTypeEnum.SpendingLimitType): Output only. The spending limit as a well-defined type, for example, INFINITE. diff --git a/google/ads/googleads/v19/resources/types/account_budget_proposal.py b/google/ads/googleads/v23/resources/types/account_budget_proposal.py similarity index 92% rename from google/ads/googleads/v19/resources/types/account_budget_proposal.py rename to google/ads/googleads/v23/resources/types/account_budget_proposal.py index 7a95f57d1..608bb88f1 100644 --- a/google/ads/googleads/v19/resources/types/account_budget_proposal.py +++ b/google/ads/googleads/v23/resources/types/account_budget_proposal.py @@ -18,15 +18,15 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import account_budget_proposal_status -from google.ads.googleads.v19.enums.types import account_budget_proposal_type -from google.ads.googleads.v19.enums.types import spending_limit_type -from google.ads.googleads.v19.enums.types import time_type +from google.ads.googleads.v23.enums.types import account_budget_proposal_status +from google.ads.googleads.v23.enums.types import account_budget_proposal_type +from google.ads.googleads.v23.enums.types import spending_limit_type +from google.ads.googleads.v23.enums.types import time_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AccountBudgetProposal", }, @@ -72,11 +72,11 @@ class AccountBudgetProposal(proto.Message): proposal. This field is a member of `oneof`_ ``_account_budget``. - proposal_type (google.ads.googleads.v19.enums.types.AccountBudgetProposalTypeEnum.AccountBudgetProposalType): + proposal_type (google.ads.googleads.v23.enums.types.AccountBudgetProposalTypeEnum.AccountBudgetProposalType): Immutable. The type of this proposal, for example, END to end the budget associated with this proposal. - status (google.ads.googleads.v19.enums.types.AccountBudgetProposalStatusEnum.AccountBudgetProposalStatus): + status (google.ads.googleads.v23.enums.types.AccountBudgetProposalStatusEnum.AccountBudgetProposalStatus): Output only. The status of this proposal. When a new proposal is created, the status defaults to PENDING. @@ -118,7 +118,7 @@ class AccountBudgetProposal(proto.Message): yyyy-mm-dd hh:mm:ss format. This field is a member of `oneof`_ ``proposed_start_time``. - proposed_start_time_type (google.ads.googleads.v19.enums.types.TimeTypeEnum.TimeType): + proposed_start_time_type (google.ads.googleads.v23.enums.types.TimeTypeEnum.TimeType): Immutable. The proposed start date time as a well-defined type, for example, NOW. @@ -128,7 +128,7 @@ class AccountBudgetProposal(proto.Message): yyyy-mm-dd hh:mm:ss format. This field is a member of `oneof`_ ``proposed_end_time``. - proposed_end_time_type (google.ads.googleads.v19.enums.types.TimeTypeEnum.TimeType): + proposed_end_time_type (google.ads.googleads.v23.enums.types.TimeTypeEnum.TimeType): Immutable. The proposed end date time as a well-defined type, for example, FOREVER. @@ -138,7 +138,7 @@ class AccountBudgetProposal(proto.Message): yyyy-mm-dd hh:mm:ss format. This field is a member of `oneof`_ ``approved_end_time``. - approved_end_time_type (google.ads.googleads.v19.enums.types.TimeTypeEnum.TimeType): + approved_end_time_type (google.ads.googleads.v23.enums.types.TimeTypeEnum.TimeType): Output only. The approved end date time as a well-defined type, for example, FOREVER. @@ -148,7 +148,7 @@ class AccountBudgetProposal(proto.Message): micros. One million is equivalent to one unit. This field is a member of `oneof`_ ``proposed_spending_limit``. - proposed_spending_limit_type (google.ads.googleads.v19.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + proposed_spending_limit_type (google.ads.googleads.v23.enums.types.SpendingLimitTypeEnum.SpendingLimitType): Immutable. The proposed spending limit as a well-defined type, for example, INFINITE. @@ -158,7 +158,7 @@ class AccountBudgetProposal(proto.Message): micros. One million is equivalent to one unit. This field is a member of `oneof`_ ``approved_spending_limit``. - approved_spending_limit_type (google.ads.googleads.v19.enums.types.SpendingLimitTypeEnum.SpendingLimitType): + approved_spending_limit_type (google.ads.googleads.v23.enums.types.SpendingLimitTypeEnum.SpendingLimitType): Output only. The approved spending limit as a well-defined type, for example, INFINITE. diff --git a/google/ads/googleads/v19/resources/types/account_link.py b/google/ads/googleads/v23/resources/types/account_link.py similarity index 90% rename from google/ads/googleads/v19/resources/types/account_link.py rename to google/ads/googleads/v23/resources/types/account_link.py index ec05d14a4..7d6daf008 100644 --- a/google/ads/googleads/v19/resources/types/account_link.py +++ b/google/ads/googleads/v23/resources/types/account_link.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import account_link_status -from google.ads.googleads.v19.enums.types import linked_account_type -from google.ads.googleads.v19.enums.types import mobile_app_vendor +from google.ads.googleads.v23.enums.types import account_link_status +from google.ads.googleads.v23.enums.types import linked_account_type +from google.ads.googleads.v23.enums.types import mobile_app_vendor __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AccountLink", "ThirdPartyAppAnalyticsLinkIdentifier", @@ -50,11 +50,11 @@ class AccountLink(proto.Message): This field is read only. This field is a member of `oneof`_ ``_account_link_id``. - status (google.ads.googleads.v19.enums.types.AccountLinkStatusEnum.AccountLinkStatus): + status (google.ads.googleads.v23.enums.types.AccountLinkStatusEnum.AccountLinkStatus): The status of the link. - type_ (google.ads.googleads.v19.enums.types.LinkedAccountTypeEnum.LinkedAccountType): + type_ (google.ads.googleads.v23.enums.types.LinkedAccountTypeEnum.LinkedAccountType): Output only. The type of the linked account. - third_party_app_analytics (google.ads.googleads.v19.resources.types.ThirdPartyAppAnalyticsLinkIdentifier): + third_party_app_analytics (google.ads.googleads.v23.resources.types.ThirdPartyAppAnalyticsLinkIdentifier): Immutable. A third party app analytics link. This field is a member of `oneof`_ ``linked_account``. @@ -125,7 +125,7 @@ class ThirdPartyAppAnalyticsLinkIdentifier(proto.Message): to be modified after the creation of the link. This field is a member of `oneof`_ ``_app_id``. - app_vendor (google.ads.googleads.v19.enums.types.MobileAppVendorEnum.MobileAppVendor): + app_vendor (google.ads.googleads.v23.enums.types.MobileAppVendorEnum.MobileAppVendor): Immutable. The vendor of the app. This field should not be empty when creating a new third party app analytics link. It is unable diff --git a/google/ads/googleads/v19/resources/types/ad.py b/google/ads/googleads/v23/resources/types/ad.py similarity index 84% rename from google/ads/googleads/v19/resources/types/ad.py rename to google/ads/googleads/v23/resources/types/ad.py index 081e2c890..9ae42cdfc 100644 --- a/google/ads/googleads/v19/resources/types/ad.py +++ b/google/ads/googleads/v23/resources/types/ad.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import ad_type_infos -from google.ads.googleads.v19.common.types import custom_parameter -from google.ads.googleads.v19.common.types import final_app_url -from google.ads.googleads.v19.common.types import url_collection -from google.ads.googleads.v19.enums.types import ad_type -from google.ads.googleads.v19.enums.types import device -from google.ads.googleads.v19.enums.types import system_managed_entity_source +from google.ads.googleads.v23.common.types import ad_type_infos +from google.ads.googleads.v23.common.types import custom_parameter +from google.ads.googleads.v23.common.types import final_app_url +from google.ads.googleads.v23.common.types import url_collection +from google.ads.googleads.v23.enums.types import ad_type +from google.ads.googleads.v23.enums.types import device +from google.ads.googleads.v23.enums.types import system_managed_entity_source __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "Ad", }, @@ -60,7 +60,7 @@ class Ad(proto.Message): final_urls (MutableSequence[str]): The list of possible final URLs after all cross-domain redirects for the ad. - final_app_urls (MutableSequence[google.ads.googleads.v19.common.types.FinalAppUrl]): + final_app_urls (MutableSequence[google.ads.googleads.v23.common.types.FinalAppUrl]): A list of final app URLs that will be used on mobile if the user has the specific app installed. @@ -77,7 +77,7 @@ class Ad(proto.Message): URL. This field is a member of `oneof`_ ``_final_url_suffix``. - url_custom_parameters (MutableSequence[google.ads.googleads.v19.common.types.CustomParameter]): + url_custom_parameters (MutableSequence[google.ads.googleads.v23.common.types.CustomParameter]): The list of mappings that can be used to substitute custom parameter tags in a ``tracking_url_template``, ``final_urls``, or ``mobile_final_urls``. For mutates, use @@ -87,7 +87,7 @@ class Ad(proto.Message): for some ad formats. This field is a member of `oneof`_ ``_display_url``. - type_ (google.ads.googleads.v19.enums.types.AdTypeEnum.AdType): + type_ (google.ads.googleads.v23.enums.types.AdTypeEnum.AdType): Output only. The type of ad. added_by_google_ads (bool): Output only. Indicates if this ad was @@ -98,7 +98,7 @@ class Ad(proto.Message): performing. This field is a member of `oneof`_ ``_added_by_google_ads``. - device_preference (google.ads.googleads.v19.enums.types.DeviceEnum.Device): + device_preference (google.ads.googleads.v23.enums.types.DeviceEnum.Device): The device preference for the ad. You can only specify a preference for mobile devices. When this preference is set the ad will be @@ -108,7 +108,7 @@ class Ad(proto.Message): ads are available. If unspecified (no device preference), all devices are targeted. This is only supported by some ad types. - url_collections (MutableSequence[google.ads.googleads.v19.common.types.UrlCollection]): + url_collections (MutableSequence[google.ads.googleads.v23.common.types.UrlCollection]): Additional URLs for the ad that are tagged with a unique identifier that can be referenced from other fields in the ad. @@ -122,23 +122,19 @@ class Ad(proto.Message): VideoAd, VideoResponsiveAd and DemandGen ads. This field is a member of `oneof`_ ``_name``. - system_managed_resource_source (google.ads.googleads.v19.enums.types.SystemManagedResourceSourceEnum.SystemManagedResourceSource): + system_managed_resource_source (google.ads.googleads.v23.enums.types.SystemManagedResourceSourceEnum.SystemManagedResourceSource): Output only. If this ad is system managed, then this field will indicate the source. This field is read-only. - text_ad (google.ads.googleads.v19.common.types.TextAdInfo): + text_ad (google.ads.googleads.v23.common.types.TextAdInfo): Immutable. Details pertaining to a text ad. This field is a member of `oneof`_ ``ad_data``. - expanded_text_ad (google.ads.googleads.v19.common.types.ExpandedTextAdInfo): + expanded_text_ad (google.ads.googleads.v23.common.types.ExpandedTextAdInfo): Details pertaining to an expanded text ad. This field is a member of `oneof`_ ``ad_data``. - call_ad (google.ads.googleads.v19.common.types.CallAdInfo): - Details pertaining to a call ad. - - This field is a member of `oneof`_ ``ad_data``. - expanded_dynamic_search_ad (google.ads.googleads.v19.common.types.ExpandedDynamicSearchAdInfo): + expanded_dynamic_search_ad (google.ads.googleads.v23.common.types.ExpandedDynamicSearchAdInfo): Immutable. Details pertaining to an Expanded Dynamic Search Ad. This type of ad has its headline, final URLs, and display URL auto-generated at serving time according to @@ -146,100 +142,100 @@ class Ad(proto.Message): ``dynamic_search_ads_setting`` linked at the campaign level. This field is a member of `oneof`_ ``ad_data``. - hotel_ad (google.ads.googleads.v19.common.types.HotelAdInfo): + hotel_ad (google.ads.googleads.v23.common.types.HotelAdInfo): Details pertaining to a hotel ad. This field is a member of `oneof`_ ``ad_data``. - shopping_smart_ad (google.ads.googleads.v19.common.types.ShoppingSmartAdInfo): + shopping_smart_ad (google.ads.googleads.v23.common.types.ShoppingSmartAdInfo): Details pertaining to a Smart Shopping ad. This field is a member of `oneof`_ ``ad_data``. - shopping_product_ad (google.ads.googleads.v19.common.types.ShoppingProductAdInfo): + shopping_product_ad (google.ads.googleads.v23.common.types.ShoppingProductAdInfo): Details pertaining to a Shopping product ad. This field is a member of `oneof`_ ``ad_data``. - image_ad (google.ads.googleads.v19.common.types.ImageAdInfo): + image_ad (google.ads.googleads.v23.common.types.ImageAdInfo): Immutable. Details pertaining to an Image ad. This field is a member of `oneof`_ ``ad_data``. - video_ad (google.ads.googleads.v19.common.types.VideoAdInfo): + video_ad (google.ads.googleads.v23.common.types.VideoAdInfo): Details pertaining to a Video ad. This field is a member of `oneof`_ ``ad_data``. - video_responsive_ad (google.ads.googleads.v19.common.types.VideoResponsiveAdInfo): + video_responsive_ad (google.ads.googleads.v23.common.types.VideoResponsiveAdInfo): Details pertaining to a Video responsive ad. This field is a member of `oneof`_ ``ad_data``. - responsive_search_ad (google.ads.googleads.v19.common.types.ResponsiveSearchAdInfo): + responsive_search_ad (google.ads.googleads.v23.common.types.ResponsiveSearchAdInfo): Details pertaining to a responsive search ad. This field is a member of `oneof`_ ``ad_data``. - legacy_responsive_display_ad (google.ads.googleads.v19.common.types.LegacyResponsiveDisplayAdInfo): + legacy_responsive_display_ad (google.ads.googleads.v23.common.types.LegacyResponsiveDisplayAdInfo): Details pertaining to a legacy responsive display ad. This field is a member of `oneof`_ ``ad_data``. - app_ad (google.ads.googleads.v19.common.types.AppAdInfo): + app_ad (google.ads.googleads.v23.common.types.AppAdInfo): Details pertaining to an app ad. This field is a member of `oneof`_ ``ad_data``. - legacy_app_install_ad (google.ads.googleads.v19.common.types.LegacyAppInstallAdInfo): + legacy_app_install_ad (google.ads.googleads.v23.common.types.LegacyAppInstallAdInfo): Immutable. Details pertaining to a legacy app install ad. This field is a member of `oneof`_ ``ad_data``. - responsive_display_ad (google.ads.googleads.v19.common.types.ResponsiveDisplayAdInfo): + responsive_display_ad (google.ads.googleads.v23.common.types.ResponsiveDisplayAdInfo): Details pertaining to a responsive display ad. This field is a member of `oneof`_ ``ad_data``. - local_ad (google.ads.googleads.v19.common.types.LocalAdInfo): + local_ad (google.ads.googleads.v23.common.types.LocalAdInfo): Details pertaining to a local ad. This field is a member of `oneof`_ ``ad_data``. - display_upload_ad (google.ads.googleads.v19.common.types.DisplayUploadAdInfo): + display_upload_ad (google.ads.googleads.v23.common.types.DisplayUploadAdInfo): Details pertaining to a display upload ad. This field is a member of `oneof`_ ``ad_data``. - app_engagement_ad (google.ads.googleads.v19.common.types.AppEngagementAdInfo): + app_engagement_ad (google.ads.googleads.v23.common.types.AppEngagementAdInfo): Details pertaining to an app engagement ad. This field is a member of `oneof`_ ``ad_data``. - shopping_comparison_listing_ad (google.ads.googleads.v19.common.types.ShoppingComparisonListingAdInfo): + shopping_comparison_listing_ad (google.ads.googleads.v23.common.types.ShoppingComparisonListingAdInfo): Details pertaining to a Shopping Comparison Listing ad. This field is a member of `oneof`_ ``ad_data``. - smart_campaign_ad (google.ads.googleads.v19.common.types.SmartCampaignAdInfo): + smart_campaign_ad (google.ads.googleads.v23.common.types.SmartCampaignAdInfo): Details pertaining to a Smart campaign ad. This field is a member of `oneof`_ ``ad_data``. - app_pre_registration_ad (google.ads.googleads.v19.common.types.AppPreRegistrationAdInfo): + app_pre_registration_ad (google.ads.googleads.v23.common.types.AppPreRegistrationAdInfo): Details pertaining to an app pre-registration ad. This field is a member of `oneof`_ ``ad_data``. - demand_gen_multi_asset_ad (google.ads.googleads.v19.common.types.DemandGenMultiAssetAdInfo): + demand_gen_multi_asset_ad (google.ads.googleads.v23.common.types.DemandGenMultiAssetAdInfo): Details pertaining to a Demand Gen multi asset ad. This field is a member of `oneof`_ ``ad_data``. - demand_gen_carousel_ad (google.ads.googleads.v19.common.types.DemandGenCarouselAdInfo): + demand_gen_carousel_ad (google.ads.googleads.v23.common.types.DemandGenCarouselAdInfo): Details pertaining to a Demand Gen carousel ad. This field is a member of `oneof`_ ``ad_data``. - demand_gen_video_responsive_ad (google.ads.googleads.v19.common.types.DemandGenVideoResponsiveAdInfo): + demand_gen_video_responsive_ad (google.ads.googleads.v23.common.types.DemandGenVideoResponsiveAdInfo): Details pertaining to a Demand Gen video responsive ad. This field is a member of `oneof`_ ``ad_data``. - demand_gen_product_ad (google.ads.googleads.v19.common.types.DemandGenProductAdInfo): + demand_gen_product_ad (google.ads.googleads.v23.common.types.DemandGenProductAdInfo): Details pertaining to a Demand Gen product ad. This field is a member of `oneof`_ ``ad_data``. - travel_ad (google.ads.googleads.v19.common.types.TravelAdInfo): + travel_ad (google.ads.googleads.v23.common.types.TravelAdInfo): Details pertaining to a travel ad. This field is a member of `oneof`_ ``ad_data``. @@ -337,12 +333,6 @@ class Ad(proto.Message): oneof="ad_data", message=ad_type_infos.ExpandedTextAdInfo, ) - call_ad: ad_type_infos.CallAdInfo = proto.Field( - proto.MESSAGE, - number=49, - oneof="ad_data", - message=ad_type_infos.CallAdInfo, - ) expanded_dynamic_search_ad: ad_type_infos.ExpandedDynamicSearchAdInfo = ( proto.Field( proto.MESSAGE, diff --git a/google/ads/googleads/v23/resources/types/ad_group.py b/google/ads/googleads/v23/resources/types/ad_group.py new file mode 100644 index 000000000..4e4f1518a --- /dev/null +++ b/google/ads/googleads/v23/resources/types/ad_group.py @@ -0,0 +1,739 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import custom_parameter +from google.ads.googleads.v23.common.types import ( + targeting_setting as gagc_targeting_setting, +) +from google.ads.googleads.v23.enums.types import ad_group_ad_rotation_mode +from google.ads.googleads.v23.enums.types import ad_group_primary_status +from google.ads.googleads.v23.enums.types import ad_group_primary_status_reason +from google.ads.googleads.v23.enums.types import ad_group_status +from google.ads.googleads.v23.enums.types import ad_group_type +from google.ads.googleads.v23.enums.types import asset_field_type +from google.ads.googleads.v23.enums.types import asset_set_type +from google.ads.googleads.v23.enums.types import bidding_source +from google.ads.googleads.v23.enums.types import demand_gen_channel_config +from google.ads.googleads.v23.enums.types import demand_gen_channel_strategy +from google.ads.googleads.v23.enums.types import targeting_dimension + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "AdGroup", + }, +) + + +class AdGroup(proto.Message): + r"""An ad group. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the ad group. Ad group + resource names have the form: + + ``customers/{customer_id}/adGroups/{ad_group_id}`` + id (int): + Output only. The ID of the ad group. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the ad group. + + This field is required and should not be empty + when creating new ad groups. + + It must contain fewer than 255 UTF-8 full-width + characters. + + It must not contain any null (code point 0x0), + NL line feed (code point 0xA) or carriage return + (code point 0xD) characters. + + This field is a member of `oneof`_ ``_name``. + status (google.ads.googleads.v23.enums.types.AdGroupStatusEnum.AdGroupStatus): + The status of the ad group. + type_ (google.ads.googleads.v23.enums.types.AdGroupTypeEnum.AdGroupType): + Immutable. The type of the ad group. + ad_rotation_mode (google.ads.googleads.v23.enums.types.AdGroupAdRotationModeEnum.AdGroupAdRotationMode): + The ad rotation mode of the ad group. + base_ad_group (str): + Output only. For draft or experiment ad + groups, this field is the resource name of the + base ad group from which this ad group was + created. If a draft or experiment ad group does + not have a base ad group, then this field is + null. + + For base ad groups, this field equals the ad + group resource name. + + This field is read-only. + + This field is a member of `oneof`_ ``_base_ad_group``. + tracking_url_template (str): + The URL template for constructing a tracking + URL. + + This field is a member of `oneof`_ ``_tracking_url_template``. + url_custom_parameters (MutableSequence[google.ads.googleads.v23.common.types.CustomParameter]): + The list of mappings used to substitute custom parameter + tags in a ``tracking_url_template``, ``final_urls``, or + ``mobile_final_urls``. + campaign (str): + Immutable. The campaign to which the ad group + belongs. + + This field is a member of `oneof`_ ``_campaign``. + cpc_bid_micros (int): + The maximum CPC (cost-per-click) bid. This + field is used when the ad group's effective + bidding strategy is Manual CPC. This field is + not applicable and will be ignored if the ad + group's campaign is using a portfolio bidding + strategy. + + This field is a member of `oneof`_ ``_cpc_bid_micros``. + effective_cpc_bid_micros (int): + Output only. Value will be same as that of + the CPC (cost-per-click) bid value when the + bidding strategy is one of manual cpc, enhanced + cpc, page one promoted or target outrank share, + otherwise the value will be null. + + This field is a member of `oneof`_ ``_effective_cpc_bid_micros``. + cpm_bid_micros (int): + The maximum CPM (cost-per-thousand viewable + impressions) bid. + + This field is a member of `oneof`_ ``_cpm_bid_micros``. + target_cpa_micros (int): + The target CPA (cost-per-acquisition). If the ad group's + campaign bidding strategy is TargetCpa or + MaximizeConversions (with its target_cpa field set), then + this field overrides the target CPA specified in the + campaign's bidding strategy. Otherwise, this value is + ignored. + + This field is a member of `oneof`_ ``_target_cpa_micros``. + cpv_bid_micros (int): + The CPV (cost-per-view) bid. + + This field is a member of `oneof`_ ``_cpv_bid_micros``. + target_cpm_micros (int): + Average amount in micros that the advertiser + is willing to pay for every thousand times the + ad is shown. + + This field is a member of `oneof`_ ``_target_cpm_micros``. + target_roas (float): + The target ROAS (return-on-ad-spend) for this ad group. + + This field lets you override the target ROAS specified in + the campaign's bidding strategy, but only if the campaign is + using a standard (not portfolio) ``TargetRoas`` strategy or + a standard ``MaximizeConversionValue`` strategy with its + ``target_roas`` field set. + + If the campaign is using a portfolio bidding strategy, this + field cannot be set and attempting to do so will result in + an error. + + For any other bidding strategies, this value is ignored. + + To see the actual target ROAS being used by the ad group, + considering potential overrides, query the + ``effective_target_roas`` and + ``effective_target_roas_source`` fields. + + This field is a member of `oneof`_ ``_target_roas``. + percent_cpc_bid_micros (int): + The percent cpc bid amount, expressed as a fraction of the + advertised price for some good or service. The valid range + for the fraction is [0,1) and the value stored here is + 1,000,000 \* [fraction]. + + This field is a member of `oneof`_ ``_percent_cpc_bid_micros``. + fixed_cpm_micros (int): + The fixed amount in micros that the + advertiser pays for every thousand impressions + of the ad. + + This field is a member of `oneof`_ ``_fixed_cpm_micros``. + target_cpv_micros (int): + Average amount in micros that the advertiser + is willing to pay for every ad view. + + This field is a member of `oneof`_ ``_target_cpv_micros``. + target_cpc_micros (int): + Average amount in micros that the advertiser + is willing to pay for every ad click. Overrides + the target CPC configured at the campaign level. + + This field is a member of `oneof`_ ``_target_cpc_micros``. + optimized_targeting_enabled (bool): + True if optimized targeting is enabled. + Optimized Targeting is the replacement for + Audience Expansion. + exclude_demographic_expansion (bool): + When this value is true, demographics will be excluded from + the types of targeting which are expanded when + optimized_targeting_enabled is true. When + optimized_targeting_enabled is false, this field is ignored. + Default is false. + display_custom_bid_dimension (google.ads.googleads.v23.enums.types.TargetingDimensionEnum.TargetingDimension): + Lets advertisers specify a targeting + dimension on which to place absolute bids. This + is only applicable for campaigns that target + only the display network and not search. + final_url_suffix (str): + URL template for appending params to Final + URL. + + This field is a member of `oneof`_ ``_final_url_suffix``. + targeting_setting (google.ads.googleads.v23.common.types.TargetingSetting): + Setting for targeting related features. + audience_setting (google.ads.googleads.v23.resources.types.AdGroup.AudienceSetting): + Immutable. Setting for audience related + features. + effective_target_cpa_micros (int): + Output only. The effective target CPA + (cost-per-acquisition). This field is read-only. + + This field is a member of `oneof`_ ``_effective_target_cpa_micros``. + effective_target_cpa_source (google.ads.googleads.v23.enums.types.BiddingSourceEnum.BiddingSource): + Output only. Source of the effective target + CPA. This field is read-only. + effective_target_roas (float): + Output only. The effective target ROAS + (return-on-ad-spend). This field is read-only. + + This field is a member of `oneof`_ ``_effective_target_roas``. + effective_target_roas_source (google.ads.googleads.v23.enums.types.BiddingSourceEnum.BiddingSource): + Output only. Source of the effective target + ROAS. This field is read-only. + effective_target_cpc (int): + Output only. The effective target CPC + (cost-per-click). This field is read-only. + + This field is a member of `oneof`_ ``_effective_target_cpc``. + effective_target_cpc_source (google.ads.googleads.v23.enums.types.BiddingSourceEnum.BiddingSource): + Output only. Source of the effective target + CPC. This field is read-only. + labels (MutableSequence[str]): + Output only. The resource names of labels + attached to this ad group. + excluded_parent_asset_field_types (MutableSequence[google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType]): + The asset field types that should be excluded + from this ad group. Asset links with these field + types will not be inherited by this ad group + from the upper levels. + excluded_parent_asset_set_types (MutableSequence[google.ads.googleads.v23.enums.types.AssetSetTypeEnum.AssetSetType]): + The asset set types that should be excluded from this ad + group. Asset set links with these types will not be + inherited by this ad group from the upper levels. Location + group types (GMB_DYNAMIC_LOCATION_GROUP, + CHAIN_DYNAMIC_LOCATION_GROUP, and STATIC_LOCATION_GROUP) are + child types of LOCATION_SYNC. Therefore, if LOCATION_SYNC is + set for this field, all location group asset sets are not + allowed to be linked to this ad group, and all Location + Extension (LE) and Affiliate Location Extensions (ALE) will + not be served under this ad group. Only LOCATION_SYNC is + currently supported. + primary_status (google.ads.googleads.v23.enums.types.AdGroupPrimaryStatusEnum.AdGroupPrimaryStatus): + Output only. Provides aggregated view into + why an ad group is not serving or not serving + optimally. + primary_status_reasons (MutableSequence[google.ads.googleads.v23.enums.types.AdGroupPrimaryStatusReasonEnum.AdGroupPrimaryStatusReason]): + Output only. Provides reasons for why an ad + group is not serving or not serving optimally. + demand_gen_ad_group_settings (google.ads.googleads.v23.resources.types.AdGroup.DemandGenAdGroupSettings): + Settings for Demand Gen ad groups. + video_ad_group_settings (google.ads.googleads.v23.resources.types.AdGroup.VideoAdGroupSettings): + Settings for video ad groups. + ai_max_ad_group_setting (google.ads.googleads.v23.resources.types.AdGroup.AiMaxAdGroupSetting): + Settings for AI Max feature in standard + search adgroups. + vertical_ads_format_setting (google.ads.googleads.v23.resources.types.AdGroup.VerticalAdsFormatSetting): + Vertical ads setting feature to + enable/disable ad group format controls in + search campaigns. This setting requires + AiMaxAdGroupSetting to be enabled and a travel + feed to be attached to the campaign. + """ + + class AudienceSetting(proto.Message): + r"""Settings for the audience targeting. + + Attributes: + use_audience_grouped (bool): + Immutable. If true, this ad group uses an + Audience resource for audience targeting. If + false, this ad group may use audience segment + criteria instead. + """ + + use_audience_grouped: bool = proto.Field( + proto.BOOL, + number=1, + ) + + class DemandGenAdGroupSettings(proto.Message): + r"""Settings for Demand Gen ad groups. + + Attributes: + channel_controls (google.ads.googleads.v23.resources.types.AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls): + Channel controls for Demand Gen ad groups. + """ + + class DemandGenChannelControls(proto.Message): + r"""Channel controls for Demand Gen ad groups. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + channel_config (google.ads.googleads.v23.enums.types.DemandGenChannelConfigEnum.DemandGenChannelConfig): + Output only. Channel configuration reflecting + which field in the oneof is populated. + channel_strategy (google.ads.googleads.v23.enums.types.DemandGenChannelStrategyEnum.DemandGenChannelStrategy): + High level channel strategy. + + This field is a member of `oneof`_ ``channel_configuration``. + selected_channels (google.ads.googleads.v23.resources.types.AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls.DemandGenSelectedChannels): + Explicitly selected channels. This field + should be set with at least one true value when + present. + + This field is a member of `oneof`_ ``channel_configuration``. + """ + + class DemandGenSelectedChannels(proto.Message): + r"""Explicitly selected channels for channel controls in Demand + Gen ad groups. + + Attributes: + youtube_in_stream (bool): + Whether to enable ads on the YouTube + In-Stream channel. + youtube_in_feed (bool): + Whether to enable ads on the YouTube In-Feed + channel. + youtube_shorts (bool): + Whether to enable ads on the YouTube Shorts + channel. + discover (bool): + Whether to enable ads on the Discover + channel. + gmail (bool): + Whether to enable ads on the Gmail channel. + display (bool): + Whether to enable ads on the Display channel. + """ + + youtube_in_stream: bool = proto.Field( + proto.BOOL, + number=1, + ) + youtube_in_feed: bool = proto.Field( + proto.BOOL, + number=2, + ) + youtube_shorts: bool = proto.Field( + proto.BOOL, + number=3, + ) + discover: bool = proto.Field( + proto.BOOL, + number=4, + ) + gmail: bool = proto.Field( + proto.BOOL, + number=5, + ) + display: bool = proto.Field( + proto.BOOL, + number=6, + ) + + channel_config: ( + demand_gen_channel_config.DemandGenChannelConfigEnum.DemandGenChannelConfig + ) = proto.Field( + proto.ENUM, + number=1, + enum=demand_gen_channel_config.DemandGenChannelConfigEnum.DemandGenChannelConfig, + ) + channel_strategy: ( + demand_gen_channel_strategy.DemandGenChannelStrategyEnum.DemandGenChannelStrategy + ) = proto.Field( + proto.ENUM, + number=2, + oneof="channel_configuration", + enum=demand_gen_channel_strategy.DemandGenChannelStrategyEnum.DemandGenChannelStrategy, + ) + selected_channels: "AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls.DemandGenSelectedChannels" = proto.Field( + proto.MESSAGE, + number=3, + oneof="channel_configuration", + message="AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls.DemandGenSelectedChannels", + ) + + channel_controls: ( + "AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls" + ) = proto.Field( + proto.MESSAGE, + number=1, + message="AdGroup.DemandGenAdGroupSettings.DemandGenChannelControls", + ) + + class VideoAdGroupSettings(proto.Message): + r"""Settings for video ad groups. + + Attributes: + video_ad_sequence (google.ads.googleads.v23.resources.types.AdGroup.VideoAdGroupSettings.VideoAdSequenceStepSetting): + The video ads sequence step settings + containing step ID. + """ + + class VideoAdSequenceStepSetting(proto.Message): + r"""The video ads sequence step settings containing step ID. + + Attributes: + step_id (int): + The ID of this sequence step from an existing + ``campaign.video_campaign_settings.video_ad_sequence`` + definition. Only one Ad Group can point to a given + ``step_id``. + """ + + step_id: int = proto.Field( + proto.INT64, + number=1, + ) + + video_ad_sequence: ( + "AdGroup.VideoAdGroupSettings.VideoAdSequenceStepSetting" + ) = proto.Field( + proto.MESSAGE, + number=1, + message="AdGroup.VideoAdGroupSettings.VideoAdSequenceStepSetting", + ) + + class AiMaxAdGroupSetting(proto.Message): + r"""Settings for AI Max feature in standard search adgroups. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + disable_search_term_matching (bool): + Disable search term matching for this adgroup + when AI Max is enabled. Search term matching + uses broad match, asset-based, and landing + page-based technology to improve reach. + + This field is a member of `oneof`_ ``_disable_search_term_matching``. + """ + + disable_search_term_matching: bool = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + + class VerticalAdsFormatSetting(proto.Message): + r"""Vertical ads setting feature to enable/disable ad group + format controls in search campaigns. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + disable_text_ads (bool): + If true, text ads will be disabled for this + ad group. + + This field is a member of `oneof`_ ``_disable_text_ads``. + enable_booking_links (bool): + If true, booking links will be enabled for + this ad group. + + This field is a member of `oneof`_ ``_enable_booking_links``. + enable_vertical_promotion_ads (bool): + If true, vertical promotion ads will be + enabled for this ad group. + + This field is a member of `oneof`_ ``_enable_vertical_promotion_ads``. + """ + + disable_text_ads: bool = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + enable_booking_links: bool = proto.Field( + proto.BOOL, + number=2, + optional=True, + ) + enable_vertical_promotion_ads: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + id: int = proto.Field( + proto.INT64, + number=34, + optional=True, + ) + name: str = proto.Field( + proto.STRING, + number=35, + optional=True, + ) + status: ad_group_status.AdGroupStatusEnum.AdGroupStatus = proto.Field( + proto.ENUM, + number=5, + enum=ad_group_status.AdGroupStatusEnum.AdGroupStatus, + ) + type_: ad_group_type.AdGroupTypeEnum.AdGroupType = proto.Field( + proto.ENUM, + number=12, + enum=ad_group_type.AdGroupTypeEnum.AdGroupType, + ) + ad_rotation_mode: ( + ad_group_ad_rotation_mode.AdGroupAdRotationModeEnum.AdGroupAdRotationMode + ) = proto.Field( + proto.ENUM, + number=22, + enum=ad_group_ad_rotation_mode.AdGroupAdRotationModeEnum.AdGroupAdRotationMode, + ) + base_ad_group: str = proto.Field( + proto.STRING, + number=36, + optional=True, + ) + tracking_url_template: str = proto.Field( + proto.STRING, + number=37, + optional=True, + ) + url_custom_parameters: MutableSequence[custom_parameter.CustomParameter] = ( + proto.RepeatedField( + proto.MESSAGE, + number=6, + message=custom_parameter.CustomParameter, + ) + ) + campaign: str = proto.Field( + proto.STRING, + number=38, + optional=True, + ) + cpc_bid_micros: int = proto.Field( + proto.INT64, + number=39, + optional=True, + ) + effective_cpc_bid_micros: int = proto.Field( + proto.INT64, + number=57, + optional=True, + ) + cpm_bid_micros: int = proto.Field( + proto.INT64, + number=40, + optional=True, + ) + target_cpa_micros: int = proto.Field( + proto.INT64, + number=41, + optional=True, + ) + cpv_bid_micros: int = proto.Field( + proto.INT64, + number=42, + optional=True, + ) + target_cpm_micros: int = proto.Field( + proto.INT64, + number=43, + optional=True, + ) + target_roas: float = proto.Field( + proto.DOUBLE, + number=44, + optional=True, + ) + percent_cpc_bid_micros: int = proto.Field( + proto.INT64, + number=45, + optional=True, + ) + fixed_cpm_micros: int = proto.Field( + proto.INT64, + number=64, + optional=True, + ) + target_cpv_micros: int = proto.Field( + proto.INT64, + number=65, + optional=True, + ) + target_cpc_micros: int = proto.Field( + proto.INT64, + number=68, + optional=True, + ) + optimized_targeting_enabled: bool = proto.Field( + proto.BOOL, + number=59, + ) + exclude_demographic_expansion: bool = proto.Field( + proto.BOOL, + number=67, + ) + display_custom_bid_dimension: ( + targeting_dimension.TargetingDimensionEnum.TargetingDimension + ) = proto.Field( + proto.ENUM, + number=23, + enum=targeting_dimension.TargetingDimensionEnum.TargetingDimension, + ) + final_url_suffix: str = proto.Field( + proto.STRING, + number=46, + optional=True, + ) + targeting_setting: gagc_targeting_setting.TargetingSetting = proto.Field( + proto.MESSAGE, + number=25, + message=gagc_targeting_setting.TargetingSetting, + ) + audience_setting: AudienceSetting = proto.Field( + proto.MESSAGE, + number=56, + message=AudienceSetting, + ) + effective_target_cpa_micros: int = proto.Field( + proto.INT64, + number=47, + optional=True, + ) + effective_target_cpa_source: ( + bidding_source.BiddingSourceEnum.BiddingSource + ) = proto.Field( + proto.ENUM, + number=29, + enum=bidding_source.BiddingSourceEnum.BiddingSource, + ) + effective_target_roas: float = proto.Field( + proto.DOUBLE, + number=48, + optional=True, + ) + effective_target_roas_source: ( + bidding_source.BiddingSourceEnum.BiddingSource + ) = proto.Field( + proto.ENUM, + number=32, + enum=bidding_source.BiddingSourceEnum.BiddingSource, + ) + effective_target_cpc: int = proto.Field( + proto.INT64, + number=69, + optional=True, + ) + effective_target_cpc_source: ( + bidding_source.BiddingSourceEnum.BiddingSource + ) = proto.Field( + proto.ENUM, + number=70, + enum=bidding_source.BiddingSourceEnum.BiddingSource, + ) + labels: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=49, + ) + excluded_parent_asset_field_types: MutableSequence[ + asset_field_type.AssetFieldTypeEnum.AssetFieldType + ] = proto.RepeatedField( + proto.ENUM, + number=54, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + excluded_parent_asset_set_types: MutableSequence[ + asset_set_type.AssetSetTypeEnum.AssetSetType + ] = proto.RepeatedField( + proto.ENUM, + number=58, + enum=asset_set_type.AssetSetTypeEnum.AssetSetType, + ) + primary_status: ( + ad_group_primary_status.AdGroupPrimaryStatusEnum.AdGroupPrimaryStatus + ) = proto.Field( + proto.ENUM, + number=62, + enum=ad_group_primary_status.AdGroupPrimaryStatusEnum.AdGroupPrimaryStatus, + ) + primary_status_reasons: MutableSequence[ + ad_group_primary_status_reason.AdGroupPrimaryStatusReasonEnum.AdGroupPrimaryStatusReason + ] = proto.RepeatedField( + proto.ENUM, + number=63, + enum=ad_group_primary_status_reason.AdGroupPrimaryStatusReasonEnum.AdGroupPrimaryStatusReason, + ) + demand_gen_ad_group_settings: DemandGenAdGroupSettings = proto.Field( + proto.MESSAGE, + number=91, + message=DemandGenAdGroupSettings, + ) + video_ad_group_settings: VideoAdGroupSettings = proto.Field( + proto.MESSAGE, + number=92, + message=VideoAdGroupSettings, + ) + ai_max_ad_group_setting: AiMaxAdGroupSetting = proto.Field( + proto.MESSAGE, + number=71, + message=AiMaxAdGroupSetting, + ) + vertical_ads_format_setting: VerticalAdsFormatSetting = proto.Field( + proto.MESSAGE, + number=72, + message=VerticalAdsFormatSetting, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/ad_group_ad.py b/google/ads/googleads/v23/resources/types/ad_group_ad.py similarity index 83% rename from google/ads/googleads/v19/resources/types/ad_group_ad.py rename to google/ads/googleads/v23/resources/types/ad_group_ad.py index 80d2e633a..518901de9 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_ad.py +++ b/google/ads/googleads/v23/resources/types/ad_group_ad.py @@ -19,27 +19,27 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import policy -from google.ads.googleads.v19.enums.types import ad_group_ad_primary_status -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import policy +from google.ads.googleads.v23.enums.types import ad_group_ad_primary_status +from google.ads.googleads.v23.enums.types import ( ad_group_ad_primary_status_reason, ) -from google.ads.googleads.v19.enums.types import ad_group_ad_status -from google.ads.googleads.v19.enums.types import ad_strength as gage_ad_strength -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ad_group_ad_status +from google.ads.googleads.v23.enums.types import ad_strength as gage_ad_strength +from google.ads.googleads.v23.enums.types import ( asset_automation_status as gage_asset_automation_status, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( asset_automation_type as gage_asset_automation_type, ) -from google.ads.googleads.v19.enums.types import policy_approval_status -from google.ads.googleads.v19.enums.types import policy_review_status -from google.ads.googleads.v19.resources.types import ad as gagr_ad +from google.ads.googleads.v23.enums.types import policy_approval_status +from google.ads.googleads.v23.enums.types import policy_review_status +from google.ads.googleads.v23.resources.types import ad as gagr_ad __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAd", "AdGroupAdPolicySummary", @@ -59,18 +59,18 @@ class AdGroupAd(proto.Message): names have the form: ``customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}`` - status (google.ads.googleads.v19.enums.types.AdGroupAdStatusEnum.AdGroupAdStatus): + status (google.ads.googleads.v23.enums.types.AdGroupAdStatusEnum.AdGroupAdStatus): The status of the ad. ad_group (str): Immutable. The ad group to which the ad belongs. This field is a member of `oneof`_ ``_ad_group``. - ad (google.ads.googleads.v19.resources.types.Ad): + ad (google.ads.googleads.v23.resources.types.Ad): Immutable. The ad. - policy_summary (google.ads.googleads.v19.resources.types.AdGroupAdPolicySummary): + policy_summary (google.ads.googleads.v23.resources.types.AdGroupAdPolicySummary): Output only. Policy information for the ad. - ad_strength (google.ads.googleads.v19.enums.types.AdStrengthEnum.AdStrength): + ad_strength (google.ads.googleads.v23.enums.types.AdStrengthEnum.AdStrength): Output only. Overall ad strength for this ad group ad. action_items (MutableSequence[str]): @@ -81,15 +81,15 @@ class AdGroupAd(proto.Message): labels (MutableSequence[str]): Output only. The resource names of labels attached to this ad group ad. - primary_status (google.ads.googleads.v19.enums.types.AdGroupAdPrimaryStatusEnum.AdGroupAdPrimaryStatus): + primary_status (google.ads.googleads.v23.enums.types.AdGroupAdPrimaryStatusEnum.AdGroupAdPrimaryStatus): Output only. Provides aggregated view into why an ad group ad is not serving or not serving optimally. - primary_status_reasons (MutableSequence[google.ads.googleads.v19.enums.types.AdGroupAdPrimaryStatusReasonEnum.AdGroupAdPrimaryStatusReason]): + primary_status_reasons (MutableSequence[google.ads.googleads.v23.enums.types.AdGroupAdPrimaryStatusReasonEnum.AdGroupAdPrimaryStatusReason]): Output only. Provides reasons for why an ad group ad is not serving or not serving optimally. - ad_group_ad_asset_automation_settings (MutableSequence[google.ads.googleads.v19.resources.types.AdGroupAdAssetAutomationSetting]): + ad_group_ad_asset_automation_settings (MutableSequence[google.ads.googleads.v23.resources.types.AdGroupAdAssetAutomationSetting]): Settings that control the types of asset automation. See the AssetAutomationTypeEnum documentation for the default opt in/out @@ -162,13 +162,13 @@ class AdGroupAdPolicySummary(proto.Message): r"""Contains policy information for an ad. Attributes: - policy_topic_entries (MutableSequence[google.ads.googleads.v19.common.types.PolicyTopicEntry]): + policy_topic_entries (MutableSequence[google.ads.googleads.v23.common.types.PolicyTopicEntry]): Output only. The list of policy findings for this ad. - review_status (google.ads.googleads.v19.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): + review_status (google.ads.googleads.v23.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): Output only. Where in the review process this ad is. - approval_status (google.ads.googleads.v19.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): + approval_status (google.ads.googleads.v23.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): Output only. The overall approval status of this ad, calculated based on the status of its individual policy topic entries. @@ -203,12 +203,12 @@ class AdGroupAdAssetAutomationSetting(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - asset_automation_type (google.ads.googleads.v19.enums.types.AssetAutomationTypeEnum.AssetAutomationType): + asset_automation_type (google.ads.googleads.v23.enums.types.AssetAutomationTypeEnum.AssetAutomationType): The asset automation type that this setting configures. This field is a member of `oneof`_ ``_asset_automation_type``. - asset_automation_status (google.ads.googleads.v19.enums.types.AssetAutomationStatusEnum.AssetAutomationStatus): + asset_automation_status (google.ads.googleads.v23.enums.types.AssetAutomationStatusEnum.AssetAutomationStatus): The opt-in/out status for the specified asset automation type. diff --git a/google/ads/googleads/v19/resources/types/ad_group_ad_asset_combination_view.py b/google/ads/googleads/v23/resources/types/ad_group_ad_asset_combination_view.py similarity index 92% rename from google/ads/googleads/v19/resources/types/ad_group_ad_asset_combination_view.py rename to google/ads/googleads/v23/resources/types/ad_group_ad_asset_combination_view.py index 991aef6cd..a4f68c24f 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_ad_asset_combination_view.py +++ b/google/ads/googleads/v23/resources/types/ad_group_ad_asset_combination_view.py @@ -19,12 +19,12 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import asset_usage +from google.ads.googleads.v23.common.types import asset_usage __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAdAssetCombinationView", }, @@ -48,7 +48,7 @@ class AdGroupAdAssetCombinationView(proto.Message): asset_combination_id_low. AdGroupAd Asset Combination view resource names have the form: ``customers/{customer_id}/adGroupAdAssetCombinationViews/{AdGroupAd.ad_group_id}~{AdGroupAd.ad.ad_id}~{AssetCombination.asset_combination_id_low}~{AssetCombination.asset_combination_id_high}`` - served_assets (MutableSequence[google.ads.googleads.v19.common.types.AssetUsage]): + served_assets (MutableSequence[google.ads.googleads.v23.common.types.AssetUsage]): Output only. Served assets. enabled (bool): Output only. The status between the asset diff --git a/google/ads/googleads/v19/resources/types/ad_group_ad_asset_view.py b/google/ads/googleads/v23/resources/types/ad_group_ad_asset_view.py similarity index 85% rename from google/ads/googleads/v19/resources/types/ad_group_ad_asset_view.py rename to google/ads/googleads/v23/resources/types/ad_group_ad_asset_view.py index 87322bbe7..4fe19fde4 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_ad_asset_view.py +++ b/google/ads/googleads/v23/resources/types/ad_group_ad_asset_view.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import policy -from google.ads.googleads.v19.enums.types import asset_field_type -from google.ads.googleads.v19.enums.types import asset_performance_label -from google.ads.googleads.v19.enums.types import asset_source -from google.ads.googleads.v19.enums.types import policy_approval_status -from google.ads.googleads.v19.enums.types import policy_review_status -from google.ads.googleads.v19.enums.types import served_asset_field_type +from google.ads.googleads.v23.common.types import policy +from google.ads.googleads.v23.enums.types import asset_field_type +from google.ads.googleads.v23.enums.types import asset_performance_label +from google.ads.googleads.v23.enums.types import asset_source +from google.ads.googleads.v23.enums.types import policy_approval_status +from google.ads.googleads.v23.enums.types import policy_review_status +from google.ads.googleads.v23.enums.types import served_asset_field_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAdAssetView", "AdGroupAdAssetPolicySummary", @@ -68,7 +68,7 @@ class AdGroupAdAssetView(proto.Message): ad group ad. This field is a member of `oneof`_ ``_asset``. - field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): Output only. Role that the asset takes in the ad. enabled (bool): @@ -80,14 +80,14 @@ class AdGroupAdAssetView(proto.Message): latest version of the ad. This field is a member of `oneof`_ ``_enabled``. - policy_summary (google.ads.googleads.v19.resources.types.AdGroupAdAssetPolicySummary): + policy_summary (google.ads.googleads.v23.resources.types.AdGroupAdAssetPolicySummary): Output only. Policy information for the ad group ad asset. - performance_label (google.ads.googleads.v19.enums.types.AssetPerformanceLabelEnum.AssetPerformanceLabel): + performance_label (google.ads.googleads.v23.enums.types.AssetPerformanceLabelEnum.AssetPerformanceLabel): Output only. Performance of an asset linkage. - pinned_field (google.ads.googleads.v19.enums.types.ServedAssetFieldTypeEnum.ServedAssetFieldType): + pinned_field (google.ads.googleads.v23.enums.types.ServedAssetFieldTypeEnum.ServedAssetFieldType): Output only. Pinned field. - source (google.ads.googleads.v19.enums.types.AssetSourceEnum.AssetSource): + source (google.ads.googleads.v23.enums.types.AssetSourceEnum.AssetSource): Output only. Source of the ad group ad asset. """ @@ -147,13 +147,13 @@ class AdGroupAdAssetPolicySummary(proto.Message): r"""Contains policy information for an ad group ad asset. Attributes: - policy_topic_entries (MutableSequence[google.ads.googleads.v19.common.types.PolicyTopicEntry]): + policy_topic_entries (MutableSequence[google.ads.googleads.v23.common.types.PolicyTopicEntry]): Output only. The list of policy findings for the ad group ad asset. - review_status (google.ads.googleads.v19.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): + review_status (google.ads.googleads.v23.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): Output only. Where in the review process this ad group ad asset is. - approval_status (google.ads.googleads.v19.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): + approval_status (google.ads.googleads.v23.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): Output only. The overall approval status of this ad group ad asset, calculated based on the status of its individual policy topic entries. diff --git a/google/ads/googleads/v19/resources/types/ad_group_ad_label.py b/google/ads/googleads/v23/resources/types/ad_group_ad_label.py similarity index 95% rename from google/ads/googleads/v19/resources/types/ad_group_ad_label.py rename to google/ads/googleads/v23/resources/types/ad_group_ad_label.py index 8fe884ea1..fd5f228ec 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_ad_label.py +++ b/google/ads/googleads/v23/resources/types/ad_group_ad_label.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAdLabel", }, diff --git a/google/ads/googleads/v19/resources/types/ad_group_asset.py b/google/ads/googleads/v23/resources/types/ad_group_asset.py similarity index 83% rename from google/ads/googleads/v19/resources/types/ad_group_asset.py rename to google/ads/googleads/v23/resources/types/ad_group_asset.py index 0191d4299..61b4d48d0 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_asset.py +++ b/google/ads/googleads/v23/resources/types/ad_group_asset.py @@ -19,19 +19,19 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import asset_policy -from google.ads.googleads.v19.enums.types import asset_field_type -from google.ads.googleads.v19.enums.types import asset_link_primary_status -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import asset_policy +from google.ads.googleads.v23.enums.types import asset_field_type +from google.ads.googleads.v23.enums.types import asset_link_primary_status +from google.ads.googleads.v23.enums.types import ( asset_link_primary_status_reason, ) -from google.ads.googleads.v19.enums.types import asset_link_status -from google.ads.googleads.v19.enums.types import asset_source +from google.ads.googleads.v23.enums.types import asset_link_status +from google.ads.googleads.v23.enums.types import asset_source __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAsset", }, @@ -53,15 +53,15 @@ class AdGroupAsset(proto.Message): asset (str): Required. Immutable. The asset which is linked to the ad group. - field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): Required. Immutable. Role that the asset takes under the linked ad group. - source (google.ads.googleads.v19.enums.types.AssetSourceEnum.AssetSource): + source (google.ads.googleads.v23.enums.types.AssetSourceEnum.AssetSource): Output only. Source of the adgroup asset link. - status (google.ads.googleads.v19.enums.types.AssetLinkStatusEnum.AssetLinkStatus): + status (google.ads.googleads.v23.enums.types.AssetLinkStatusEnum.AssetLinkStatus): Status of the ad group asset. - primary_status (google.ads.googleads.v19.enums.types.AssetLinkPrimaryStatusEnum.AssetLinkPrimaryStatus): + primary_status (google.ads.googleads.v23.enums.types.AssetLinkPrimaryStatusEnum.AssetLinkPrimaryStatus): Output only. Provides the PrimaryStatus of this asset link. Primary status is meant essentially to differentiate between the plain @@ -71,10 +71,10 @@ class AdGroupAsset(proto.Message): assets its mainly policy and quality approvals) to come up with a more comprehensive status to indicate its serving state. - primary_status_details (MutableSequence[google.ads.googleads.v19.common.types.AssetLinkPrimaryStatusDetails]): + primary_status_details (MutableSequence[google.ads.googleads.v23.common.types.AssetLinkPrimaryStatusDetails]): Output only. Provides the details of the primary status and its associated reasons. - primary_status_reasons (MutableSequence[google.ads.googleads.v19.enums.types.AssetLinkPrimaryStatusReasonEnum.AssetLinkPrimaryStatusReason]): + primary_status_reasons (MutableSequence[google.ads.googleads.v23.enums.types.AssetLinkPrimaryStatusReasonEnum.AssetLinkPrimaryStatusReason]): Output only. Provides a list of reasons for why an asset is not serving or not serving at full capacity. diff --git a/google/ads/googleads/v19/resources/types/ad_group_asset_set.py b/google/ads/googleads/v23/resources/types/ad_group_asset_set.py similarity index 90% rename from google/ads/googleads/v19/resources/types/ad_group_asset_set.py rename to google/ads/googleads/v23/resources/types/ad_group_asset_set.py index 1596fd9f8..ae9aa8405 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_asset_set.py +++ b/google/ads/googleads/v23/resources/types/ad_group_asset_set.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import asset_set_link_status +from google.ads.googleads.v23.enums.types import asset_set_link_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAssetSet", }, @@ -47,7 +47,7 @@ class AdGroupAssetSet(proto.Message): asset_set (str): Immutable. The asset set which is linked to the ad group. - status (google.ads.googleads.v19.enums.types.AssetSetLinkStatusEnum.AssetSetLinkStatus): + status (google.ads.googleads.v23.enums.types.AssetSetLinkStatusEnum.AssetSetLinkStatus): Output only. The status of the ad group asset set. Read-only. """ diff --git a/google/ads/googleads/v19/resources/types/ad_group_audience_view.py b/google/ads/googleads/v23/resources/types/ad_group_audience_view.py similarity index 94% rename from google/ads/googleads/v19/resources/types/ad_group_audience_view.py rename to google/ads/googleads/v23/resources/types/ad_group_audience_view.py index d7a12c833..c5f01a305 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_audience_view.py +++ b/google/ads/googleads/v23/resources/types/ad_group_audience_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupAudienceView", }, diff --git a/google/ads/googleads/v19/resources/types/ad_group_bid_modifier.py b/google/ads/googleads/v23/resources/types/ad_group_bid_modifier.py similarity index 88% rename from google/ads/googleads/v19/resources/types/ad_group_bid_modifier.py rename to google/ads/googleads/v23/resources/types/ad_group_bid_modifier.py index 8bc77a83a..8e42d2b46 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_bid_modifier.py +++ b/google/ads/googleads/v23/resources/types/ad_group_bid_modifier.py @@ -18,15 +18,15 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import ( bid_modifier_source as gage_bid_modifier_source, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupBidModifier", }, @@ -63,9 +63,7 @@ class AdGroupBidModifier(proto.Message): bid_modifier (float): The modifier for the bid when the criterion matches. The modifier must be in the range: 0.1 - - 10.0. The range is 1.0 - 6.0 for - PreferredContent. Use 0 to opt out of a Device - type. + - 10.0. Use 0 to opt out of a Device type. This field is a member of `oneof`_ ``_bid_modifier``. base_ad_group (str): @@ -77,33 +75,33 @@ class AdGroupBidModifier(proto.Message): This field is readonly. This field is a member of `oneof`_ ``_base_ad_group``. - bid_modifier_source (google.ads.googleads.v19.enums.types.BidModifierSourceEnum.BidModifierSource): + bid_modifier_source (google.ads.googleads.v23.enums.types.BidModifierSourceEnum.BidModifierSource): Output only. Bid modifier source. - hotel_date_selection_type (google.ads.googleads.v19.common.types.HotelDateSelectionTypeInfo): + hotel_date_selection_type (google.ads.googleads.v23.common.types.HotelDateSelectionTypeInfo): Immutable. Criterion for hotel date selection (default dates versus user selected). This field is a member of `oneof`_ ``criterion``. - hotel_advance_booking_window (google.ads.googleads.v19.common.types.HotelAdvanceBookingWindowInfo): + hotel_advance_booking_window (google.ads.googleads.v23.common.types.HotelAdvanceBookingWindowInfo): Immutable. Criterion for number of days prior to the stay the booking is being made. This field is a member of `oneof`_ ``criterion``. - hotel_length_of_stay (google.ads.googleads.v19.common.types.HotelLengthOfStayInfo): + hotel_length_of_stay (google.ads.googleads.v23.common.types.HotelLengthOfStayInfo): Immutable. Criterion for length of hotel stay in nights. This field is a member of `oneof`_ ``criterion``. - hotel_check_in_day (google.ads.googleads.v19.common.types.HotelCheckInDayInfo): + hotel_check_in_day (google.ads.googleads.v23.common.types.HotelCheckInDayInfo): Immutable. Criterion for day of the week the booking is for. This field is a member of `oneof`_ ``criterion``. - device (google.ads.googleads.v19.common.types.DeviceInfo): + device (google.ads.googleads.v23.common.types.DeviceInfo): Immutable. A device criterion. This field is a member of `oneof`_ ``criterion``. - hotel_check_in_date_range (google.ads.googleads.v19.common.types.HotelCheckInDateRangeInfo): + hotel_check_in_date_range (google.ads.googleads.v23.common.types.HotelCheckInDateRangeInfo): Immutable. Criterion for a hotel check-in date range. diff --git a/google/ads/googleads/v19/resources/types/ad_group_criterion.py b/google/ads/googleads/v23/resources/types/ad_group_criterion.py similarity index 82% rename from google/ads/googleads/v19/resources/types/ad_group_criterion.py rename to google/ads/googleads/v23/resources/types/ad_group_criterion.py index 56d36d071..7d43d97ea 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_criterion.py +++ b/google/ads/googleads/v23/resources/types/ad_group_criterion.py @@ -19,27 +19,27 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.common.types import custom_parameter -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.common.types import custom_parameter +from google.ads.googleads.v23.enums.types import ( ad_group_criterion_approval_status, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( ad_group_criterion_primary_status, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( ad_group_criterion_primary_status_reason, ) -from google.ads.googleads.v19.enums.types import ad_group_criterion_status -from google.ads.googleads.v19.enums.types import bidding_source -from google.ads.googleads.v19.enums.types import criterion_system_serving_status -from google.ads.googleads.v19.enums.types import criterion_type -from google.ads.googleads.v19.enums.types import quality_score_bucket +from google.ads.googleads.v23.enums.types import ad_group_criterion_status +from google.ads.googleads.v23.enums.types import bidding_source +from google.ads.googleads.v23.enums.types import criterion_system_serving_status +from google.ads.googleads.v23.enums.types import criterion_type +from google.ads.googleads.v23.enums.types import quality_score_bucket __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCriterion", }, @@ -73,7 +73,7 @@ class AdGroupCriterion(proto.Message): Output only. The display name of the criterion. This field is ignored for mutates. - status (google.ads.googleads.v19.enums.types.AdGroupCriterionStatusEnum.AdGroupCriterionStatus): + status (google.ads.googleads.v23.enums.types.AdGroupCriterionStatusEnum.AdGroupCriterionStatus): The status of the criterion. This is the status of the ad group criterion @@ -88,7 +88,7 @@ class AdGroupCriterion(proto.Message): to see the ads; but AdGroupCriterion.status will show "removed", since no positive criterion was added. - quality_info (google.ads.googleads.v19.resources.types.AdGroupCriterion.QualityInfo): + quality_info (google.ads.googleads.v23.resources.types.AdGroupCriterion.QualityInfo): Output only. Information regarding the quality of the criterion. ad_group (str): @@ -96,7 +96,7 @@ class AdGroupCriterion(proto.Message): criterion belongs. This field is a member of `oneof`_ ``_ad_group``. - type_ (google.ads.googleads.v19.enums.types.CriterionTypeEnum.CriterionType): + type_ (google.ads.googleads.v23.enums.types.CriterionTypeEnum.CriterionType): Output only. The type of the criterion. negative (bool): Immutable. Whether to target (``false``) or exclude @@ -106,9 +106,9 @@ class AdGroupCriterion(proto.Message): to negative, remove then re-add it. This field is a member of `oneof`_ ``_negative``. - system_serving_status (google.ads.googleads.v19.enums.types.CriterionSystemServingStatusEnum.CriterionSystemServingStatus): + system_serving_status (google.ads.googleads.v23.enums.types.CriterionSystemServingStatusEnum.CriterionSystemServingStatus): Output only. Serving status of the criterion. - approval_status (google.ads.googleads.v19.enums.types.AdGroupCriterionApprovalStatusEnum.AdGroupCriterionApprovalStatus): + approval_status (google.ads.googleads.v23.enums.types.AdGroupCriterionApprovalStatusEnum.AdGroupCriterionApprovalStatus): Output only. Approval status of the criterion. disapproval_reasons (MutableSequence[str]): @@ -170,16 +170,16 @@ class AdGroupCriterion(proto.Message): amount. This field is a member of `oneof`_ ``_effective_percent_cpc_bid_micros``. - effective_cpc_bid_source (google.ads.googleads.v19.enums.types.BiddingSourceEnum.BiddingSource): + effective_cpc_bid_source (google.ads.googleads.v23.enums.types.BiddingSourceEnum.BiddingSource): Output only. Source of the effective CPC bid. - effective_cpm_bid_source (google.ads.googleads.v19.enums.types.BiddingSourceEnum.BiddingSource): + effective_cpm_bid_source (google.ads.googleads.v23.enums.types.BiddingSourceEnum.BiddingSource): Output only. Source of the effective CPM bid. - effective_cpv_bid_source (google.ads.googleads.v19.enums.types.BiddingSourceEnum.BiddingSource): + effective_cpv_bid_source (google.ads.googleads.v23.enums.types.BiddingSourceEnum.BiddingSource): Output only. Source of the effective CPV bid. - effective_percent_cpc_bid_source (google.ads.googleads.v19.enums.types.BiddingSourceEnum.BiddingSource): + effective_percent_cpc_bid_source (google.ads.googleads.v23.enums.types.BiddingSourceEnum.BiddingSource): Output only. Source of the effective Percent CPC bid. - position_estimates (google.ads.googleads.v19.resources.types.AdGroupCriterion.PositionEstimates): + position_estimates (google.ads.googleads.v23.resources.types.AdGroupCriterion.PositionEstimates): Output only. Estimates for criterion bids at various positions. final_urls (MutableSequence[str]): @@ -198,109 +198,130 @@ class AdGroupCriterion(proto.Message): URL. This field is a member of `oneof`_ ``_tracking_url_template``. - url_custom_parameters (MutableSequence[google.ads.googleads.v19.common.types.CustomParameter]): + url_custom_parameters (MutableSequence[google.ads.googleads.v23.common.types.CustomParameter]): The list of mappings used to substitute custom parameter tags in a ``tracking_url_template``, ``final_urls``, or ``mobile_final_urls``. - primary_status (google.ads.googleads.v19.enums.types.AdGroupCriterionPrimaryStatusEnum.AdGroupCriterionPrimaryStatus): + primary_status (google.ads.googleads.v23.enums.types.AdGroupCriterionPrimaryStatusEnum.AdGroupCriterionPrimaryStatus): Output only. The primary status for the ad group criterion. This field is a member of `oneof`_ ``_primary_status``. - primary_status_reasons (MutableSequence[google.ads.googleads.v19.enums.types.AdGroupCriterionPrimaryStatusReasonEnum.AdGroupCriterionPrimaryStatusReason]): + primary_status_reasons (MutableSequence[google.ads.googleads.v23.enums.types.AdGroupCriterionPrimaryStatusReasonEnum.AdGroupCriterionPrimaryStatusReason]): Output only. The primary status reasons for the ad group criterion. - keyword (google.ads.googleads.v19.common.types.KeywordInfo): + keyword (google.ads.googleads.v23.common.types.KeywordInfo): Immutable. Keyword. This field is a member of `oneof`_ ``criterion``. - placement (google.ads.googleads.v19.common.types.PlacementInfo): + placement (google.ads.googleads.v23.common.types.PlacementInfo): Immutable. Placement. This field is a member of `oneof`_ ``criterion``. - mobile_app_category (google.ads.googleads.v19.common.types.MobileAppCategoryInfo): + mobile_app_category (google.ads.googleads.v23.common.types.MobileAppCategoryInfo): Immutable. Mobile app category. This field is a member of `oneof`_ ``criterion``. - mobile_application (google.ads.googleads.v19.common.types.MobileApplicationInfo): + mobile_application (google.ads.googleads.v23.common.types.MobileApplicationInfo): Immutable. Mobile application. This field is a member of `oneof`_ ``criterion``. - listing_group (google.ads.googleads.v19.common.types.ListingGroupInfo): + listing_group (google.ads.googleads.v23.common.types.ListingGroupInfo): Immutable. Listing group. This field is a member of `oneof`_ ``criterion``. - age_range (google.ads.googleads.v19.common.types.AgeRangeInfo): + age_range (google.ads.googleads.v23.common.types.AgeRangeInfo): Immutable. Age range. This field is a member of `oneof`_ ``criterion``. - gender (google.ads.googleads.v19.common.types.GenderInfo): + gender (google.ads.googleads.v23.common.types.GenderInfo): Immutable. Gender. This field is a member of `oneof`_ ``criterion``. - income_range (google.ads.googleads.v19.common.types.IncomeRangeInfo): + income_range (google.ads.googleads.v23.common.types.IncomeRangeInfo): Immutable. Income range. This field is a member of `oneof`_ ``criterion``. - parental_status (google.ads.googleads.v19.common.types.ParentalStatusInfo): + parental_status (google.ads.googleads.v23.common.types.ParentalStatusInfo): Immutable. Parental status. This field is a member of `oneof`_ ``criterion``. - user_list (google.ads.googleads.v19.common.types.UserListInfo): + user_list (google.ads.googleads.v23.common.types.UserListInfo): Immutable. User List. This field is a member of `oneof`_ ``criterion``. - youtube_video (google.ads.googleads.v19.common.types.YouTubeVideoInfo): + youtube_video (google.ads.googleads.v23.common.types.YouTubeVideoInfo): Immutable. YouTube Video. This field is a member of `oneof`_ ``criterion``. - youtube_channel (google.ads.googleads.v19.common.types.YouTubeChannelInfo): + youtube_channel (google.ads.googleads.v23.common.types.YouTubeChannelInfo): Immutable. YouTube Channel. This field is a member of `oneof`_ ``criterion``. - topic (google.ads.googleads.v19.common.types.TopicInfo): + topic (google.ads.googleads.v23.common.types.TopicInfo): Immutable. Topic. This field is a member of `oneof`_ ``criterion``. - user_interest (google.ads.googleads.v19.common.types.UserInterestInfo): + user_interest (google.ads.googleads.v23.common.types.UserInterestInfo): Immutable. User Interest. This field is a member of `oneof`_ ``criterion``. - webpage (google.ads.googleads.v19.common.types.WebpageInfo): + webpage (google.ads.googleads.v23.common.types.WebpageInfo): Immutable. Webpage This field is a member of `oneof`_ ``criterion``. - app_payment_model (google.ads.googleads.v19.common.types.AppPaymentModelInfo): + app_payment_model (google.ads.googleads.v23.common.types.AppPaymentModelInfo): Immutable. App Payment Model. This field is a member of `oneof`_ ``criterion``. - custom_affinity (google.ads.googleads.v19.common.types.CustomAffinityInfo): + custom_affinity (google.ads.googleads.v23.common.types.CustomAffinityInfo): Immutable. Custom Affinity. This field is a member of `oneof`_ ``criterion``. - custom_intent (google.ads.googleads.v19.common.types.CustomIntentInfo): + custom_intent (google.ads.googleads.v23.common.types.CustomIntentInfo): Immutable. Custom Intent. This field is a member of `oneof`_ ``criterion``. - custom_audience (google.ads.googleads.v19.common.types.CustomAudienceInfo): + custom_audience (google.ads.googleads.v23.common.types.CustomAudienceInfo): Immutable. Custom Audience. This field is a member of `oneof`_ ``criterion``. - combined_audience (google.ads.googleads.v19.common.types.CombinedAudienceInfo): + combined_audience (google.ads.googleads.v23.common.types.CombinedAudienceInfo): Immutable. Combined Audience. This field is a member of `oneof`_ ``criterion``. - audience (google.ads.googleads.v19.common.types.AudienceInfo): + audience (google.ads.googleads.v23.common.types.AudienceInfo): Immutable. Audience. This field is a member of `oneof`_ ``criterion``. - location (google.ads.googleads.v19.common.types.LocationInfo): + location (google.ads.googleads.v23.common.types.LocationInfo): Immutable. Location. This field is a member of `oneof`_ ``criterion``. - language (google.ads.googleads.v19.common.types.LanguageInfo): + language (google.ads.googleads.v23.common.types.LanguageInfo): Immutable. Language. + This field is a member of `oneof`_ ``criterion``. + life_event (google.ads.googleads.v23.common.types.LifeEventInfo): + Immutable. Life event campaign criterion. + + This field is a member of `oneof`_ ``criterion``. + video_lineup (google.ads.googleads.v23.common.types.VideoLineupInfo): + Immutable. Video lineup criterion. + + This field is a member of `oneof`_ ``criterion``. + extended_demographic (google.ads.googleads.v23.common.types.ExtendedDemographicInfo): + Immutable. Extended demographic criterion. + + This field is a member of `oneof`_ ``criterion``. + brand_list (google.ads.googleads.v23.common.types.BrandListInfo): + Immutable. Brand list criterion. + + This field is a member of `oneof`_ ``criterion``. + vertical_ads_item_group_rule_list (google.ads.googleads.v23.common.types.VerticalAdsItemGroupRuleListInfo): + Immutable. Vertical ads item group rule list + criterion. + This field is a member of `oneof`_ ``criterion``. """ @@ -318,13 +339,13 @@ class QualityInfo(proto.Message): value. This field is a member of `oneof`_ ``_quality_score``. - creative_quality_score (google.ads.googleads.v19.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + creative_quality_score (google.ads.googleads.v23.enums.types.QualityScoreBucketEnum.QualityScoreBucket): Output only. The performance of the ad compared to other advertisers. - post_click_quality_score (google.ads.googleads.v19.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + post_click_quality_score (google.ads.googleads.v23.enums.types.QualityScoreBucketEnum.QualityScoreBucket): Output only. The quality score of the landing page. - search_predicted_ctr (google.ads.googleads.v19.enums.types.QualityScoreBucketEnum.QualityScoreBucket): + search_predicted_ctr (google.ads.googleads.v23.enums.types.QualityScoreBucketEnum.QualityScoreBucket): Output only. The click-through rate compared to that of other advertisers. """ @@ -739,6 +760,38 @@ class PositionEstimates(proto.Message): oneof="criterion", message=criteria.LanguageInfo, ) + life_event: criteria.LifeEventInfo = proto.Field( + proto.MESSAGE, + number=84, + oneof="criterion", + message=criteria.LifeEventInfo, + ) + video_lineup: criteria.VideoLineupInfo = proto.Field( + proto.MESSAGE, + number=88, + oneof="criterion", + message=criteria.VideoLineupInfo, + ) + extended_demographic: criteria.ExtendedDemographicInfo = proto.Field( + proto.MESSAGE, + number=90, + oneof="criterion", + message=criteria.ExtendedDemographicInfo, + ) + brand_list: criteria.BrandListInfo = proto.Field( + proto.MESSAGE, + number=89, + oneof="criterion", + message=criteria.BrandListInfo, + ) + vertical_ads_item_group_rule_list: ( + criteria.VerticalAdsItemGroupRuleListInfo + ) = proto.Field( + proto.MESSAGE, + number=91, + oneof="criterion", + message=criteria.VerticalAdsItemGroupRuleListInfo, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/ad_group_criterion_customizer.py b/google/ads/googleads/v23/resources/types/ad_group_criterion_customizer.py similarity index 89% rename from google/ads/googleads/v19/resources/types/ad_group_criterion_customizer.py rename to google/ads/googleads/v23/resources/types/ad_group_criterion_customizer.py index 8c197cafc..76de28574 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_criterion_customizer.py +++ b/google/ads/googleads/v23/resources/types/ad_group_criterion_customizer.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import customizer_value -from google.ads.googleads.v19.enums.types import customizer_value_status +from google.ads.googleads.v23.common.types import customizer_value +from google.ads.googleads.v23.enums.types import customizer_value_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCriterionCustomizer", }, @@ -54,10 +54,10 @@ class AdGroupCriterionCustomizer(proto.Message): customizer_attribute (str): Required. Immutable. The customizer attribute which is linked to the ad group criterion. - status (google.ads.googleads.v19.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): + status (google.ads.googleads.v23.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): Output only. The status of the ad group criterion customizer. - value (google.ads.googleads.v19.common.types.CustomizerValue): + value (google.ads.googleads.v23.common.types.CustomizerValue): Required. The value to associate with the customizer attribute at this level. The value must be of the type specified for the diff --git a/google/ads/googleads/v19/resources/types/ad_group_criterion_label.py b/google/ads/googleads/v23/resources/types/ad_group_criterion_label.py similarity index 95% rename from google/ads/googleads/v19/resources/types/ad_group_criterion_label.py rename to google/ads/googleads/v23/resources/types/ad_group_criterion_label.py index bde5dfd00..7dcdc9d68 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_criterion_label.py +++ b/google/ads/googleads/v23/resources/types/ad_group_criterion_label.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCriterionLabel", }, diff --git a/google/ads/googleads/v19/resources/types/ad_group_criterion_simulation.py b/google/ads/googleads/v23/resources/types/ad_group_criterion_simulation.py similarity index 90% rename from google/ads/googleads/v19/resources/types/ad_group_criterion_simulation.py rename to google/ads/googleads/v23/resources/types/ad_group_criterion_simulation.py index e0f2bafc9..a066ea4a6 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_criterion_simulation.py +++ b/google/ads/googleads/v23/resources/types/ad_group_criterion_simulation.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import simulation -from google.ads.googleads.v19.enums.types import simulation_modification_method -from google.ads.googleads.v19.enums.types import simulation_type +from google.ads.googleads.v23.common.types import simulation +from google.ads.googleads.v23.enums.types import simulation_modification_method +from google.ads.googleads.v23.enums.types import simulation_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCriterionSimulation", }, @@ -66,10 +66,10 @@ class AdGroupCriterionSimulation(proto.Message): Output only. Criterion ID of the simulation. This field is a member of `oneof`_ ``_criterion_id``. - type_ (google.ads.googleads.v19.enums.types.SimulationTypeEnum.SimulationType): + type_ (google.ads.googleads.v23.enums.types.SimulationTypeEnum.SimulationType): Output only. The field that the simulation modifies. - modification_method (google.ads.googleads.v19.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): + modification_method (google.ads.googleads.v23.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): Output only. How the simulation modifies the field. start_date (str): @@ -82,12 +82,12 @@ class AdGroupCriterionSimulation(proto.Message): is based, in YYYY-MM-DD format. This field is a member of `oneof`_ ``_end_date``. - cpc_bid_point_list (google.ads.googleads.v19.common.types.CpcBidSimulationPointList): + cpc_bid_point_list (google.ads.googleads.v23.common.types.CpcBidSimulationPointList): Output only. Simulation points if the simulation type is CPC_BID. This field is a member of `oneof`_ ``point_list``. - percent_cpc_bid_point_list (google.ads.googleads.v19.common.types.PercentCpcBidSimulationPointList): + percent_cpc_bid_point_list (google.ads.googleads.v23.common.types.PercentCpcBidSimulationPointList): Output only. Simulation points if the simulation type is PERCENT_CPC_BID. diff --git a/google/ads/googleads/v19/resources/types/ad_group_customizer.py b/google/ads/googleads/v23/resources/types/ad_group_customizer.py similarity index 87% rename from google/ads/googleads/v19/resources/types/ad_group_customizer.py rename to google/ads/googleads/v23/resources/types/ad_group_customizer.py index 57ed90cca..d10817299 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_customizer.py +++ b/google/ads/googleads/v23/resources/types/ad_group_customizer.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import customizer_value -from google.ads.googleads.v19.enums.types import customizer_value_status +from google.ads.googleads.v23.common.types import customizer_value +from google.ads.googleads.v23.enums.types import customizer_value_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupCustomizer", }, @@ -47,10 +47,10 @@ class AdGroupCustomizer(proto.Message): customizer_attribute (str): Required. Immutable. The customizer attribute which is linked to the ad group. - status (google.ads.googleads.v19.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): + status (google.ads.googleads.v23.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): Output only. The status of the ad group customizer. - value (google.ads.googleads.v19.common.types.CustomizerValue): + value (google.ads.googleads.v23.common.types.CustomizerValue): Required. The value to associate with the customizer attribute at this level. The value must be of the type specified for the diff --git a/google/ads/googleads/v19/resources/types/ad_group_label.py b/google/ads/googleads/v23/resources/types/ad_group_label.py similarity index 95% rename from google/ads/googleads/v19/resources/types/ad_group_label.py rename to google/ads/googleads/v23/resources/types/ad_group_label.py index fbecb98e7..87d76a4ec 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_label.py +++ b/google/ads/googleads/v23/resources/types/ad_group_label.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupLabel", }, diff --git a/google/ads/googleads/v19/resources/types/ad_group_simulation.py b/google/ads/googleads/v23/resources/types/ad_group_simulation.py similarity index 88% rename from google/ads/googleads/v19/resources/types/ad_group_simulation.py rename to google/ads/googleads/v23/resources/types/ad_group_simulation.py index 7dd62c29c..83c54321a 100644 --- a/google/ads/googleads/v19/resources/types/ad_group_simulation.py +++ b/google/ads/googleads/v23/resources/types/ad_group_simulation.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import simulation -from google.ads.googleads.v19.enums.types import simulation_modification_method -from google.ads.googleads.v19.enums.types import simulation_type +from google.ads.googleads.v23.common.types import simulation +from google.ads.googleads.v23.enums.types import simulation_modification_method +from google.ads.googleads.v23.enums.types import simulation_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdGroupSimulation", }, @@ -38,11 +38,17 @@ class AdGroupSimulation(proto.Message): detailed below respectively. 1. SEARCH - CPC_BID - DEFAULT + 2. SEARCH - CPC_BID - UNIFORM + 3. SEARCH - TARGET_CPA - UNIFORM + 4. SEARCH - TARGET_ROAS - UNIFORM + 5. DISPLAY - CPC_BID - DEFAULT + 6. DISPLAY - CPC_BID - UNIFORM + 7. DISPLAY - TARGET_CPA - UNIFORM This message has `oneof`_ fields (mutually exclusive fields). @@ -62,10 +68,10 @@ class AdGroupSimulation(proto.Message): Output only. Ad group id of the simulation. This field is a member of `oneof`_ ``_ad_group_id``. - type_ (google.ads.googleads.v19.enums.types.SimulationTypeEnum.SimulationType): + type_ (google.ads.googleads.v23.enums.types.SimulationTypeEnum.SimulationType): Output only. The field that the simulation modifies. - modification_method (google.ads.googleads.v19.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): + modification_method (google.ads.googleads.v23.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): Output only. How the simulation modifies the field. start_date (str): @@ -78,22 +84,22 @@ class AdGroupSimulation(proto.Message): is based, in YYYY-MM-DD format This field is a member of `oneof`_ ``_end_date``. - cpc_bid_point_list (google.ads.googleads.v19.common.types.CpcBidSimulationPointList): + cpc_bid_point_list (google.ads.googleads.v23.common.types.CpcBidSimulationPointList): Output only. Simulation points if the simulation type is CPC_BID. This field is a member of `oneof`_ ``point_list``. - cpv_bid_point_list (google.ads.googleads.v19.common.types.CpvBidSimulationPointList): + cpv_bid_point_list (google.ads.googleads.v23.common.types.CpvBidSimulationPointList): Output only. Simulation points if the simulation type is CPV_BID. This field is a member of `oneof`_ ``point_list``. - target_cpa_point_list (google.ads.googleads.v19.common.types.TargetCpaSimulationPointList): + target_cpa_point_list (google.ads.googleads.v23.common.types.TargetCpaSimulationPointList): Output only. Simulation points if the simulation type is TARGET_CPA. This field is a member of `oneof`_ ``point_list``. - target_roas_point_list (google.ads.googleads.v19.common.types.TargetRoasSimulationPointList): + target_roas_point_list (google.ads.googleads.v23.common.types.TargetRoasSimulationPointList): Output only. Simulation points if the simulation type is TARGET_ROAS. diff --git a/google/ads/googleads/v19/resources/types/ad_parameter.py b/google/ads/googleads/v23/resources/types/ad_parameter.py similarity index 97% rename from google/ads/googleads/v19/resources/types/ad_parameter.py rename to google/ads/googleads/v23/resources/types/ad_parameter.py index 179b03918..d64c3659d 100644 --- a/google/ads/googleads/v19/resources/types/ad_parameter.py +++ b/google/ads/googleads/v23/resources/types/ad_parameter.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdParameter", }, diff --git a/google/ads/googleads/v19/resources/types/ad_schedule_view.py b/google/ads/googleads/v23/resources/types/ad_schedule_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/ad_schedule_view.py rename to google/ads/googleads/v23/resources/types/ad_schedule_view.py index e3743fd7d..1ff6a5cbe 100644 --- a/google/ads/googleads/v19/resources/types/ad_schedule_view.py +++ b/google/ads/googleads/v23/resources/types/ad_schedule_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AdScheduleView", }, diff --git a/google/ads/googleads/v19/resources/types/age_range_view.py b/google/ads/googleads/v23/resources/types/age_range_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/age_range_view.py rename to google/ads/googleads/v23/resources/types/age_range_view.py index d0f9f4402..f38730416 100644 --- a/google/ads/googleads/v19/resources/types/age_range_view.py +++ b/google/ads/googleads/v23/resources/types/age_range_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AgeRangeView", }, diff --git a/google/ads/googleads/v23/resources/types/ai_max_search_term_ad_combination_view.py b/google/ads/googleads/v23/resources/types/ai_max_search_term_ad_combination_view.py new file mode 100644 index 000000000..b09304f3b --- /dev/null +++ b/google/ads/googleads/v23/resources/types/ai_max_search_term_ad_combination_view.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "AiMaxSearchTermAdCombinationView", + }, +) + + +class AiMaxSearchTermAdCombinationView(proto.Message): + r"""AiMaxSearchTermAdCombinationView Resource. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Output only. The resource name of the AI Max Search Term Ad + Combination view AI Max Search Term Ad Combination view + resource names have the form: + + ``customers/{customer_id}/aiMaxSearchTermAdCombinationViews/{ad_group_id}~{URL-base64_search_term}~{URL-base64_landing_page}~{URL-base64_headline}`` + ad_group (str): + Output only. Ad group where the search term + served. + + This field is a member of `oneof`_ ``_ad_group``. + search_term (str): + Output only. The search term that triggered + the ad. This field is read-only. + + This field is a member of `oneof`_ ``_search_term``. + landing_page (str): + Output only. The destination URL, which was + dynamically generated. This field is read-only. + + This field is a member of `oneof`_ ``_landing_page``. + headline (str): + Output only. The concatenated string containing headline + assets for the ad. Up to three headline assets are + concatenated, separated by " \| ". This field is read-only. + + This field is a member of `oneof`_ ``_headline``. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + ad_group: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + search_term: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + landing_page: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + headline: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/android_privacy_shared_key_google_ad_group.py b/google/ads/googleads/v23/resources/types/android_privacy_shared_key_google_ad_group.py similarity index 92% rename from google/ads/googleads/v19/resources/types/android_privacy_shared_key_google_ad_group.py rename to google/ads/googleads/v23/resources/types/android_privacy_shared_key_google_ad_group.py index 008103168..4bd85e48f 100644 --- a/google/ads/googleads/v19/resources/types/android_privacy_shared_key_google_ad_group.py +++ b/google/ads/googleads/v23/resources/types/android_privacy_shared_key_google_ad_group.py @@ -18,17 +18,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( android_privacy_interaction_type as gage_android_privacy_interaction_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( android_privacy_network_type as gage_android_privacy_network_type, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AndroidPrivacySharedKeyGoogleAdGroup", }, @@ -48,14 +48,14 @@ class AndroidPrivacySharedKeyGoogleAdGroup(proto.Message): campaign_id (int): Output only. The campaign ID used in the share key encoding. - android_privacy_interaction_type (google.ads.googleads.v19.enums.types.AndroidPrivacyInteractionTypeEnum.AndroidPrivacyInteractionType): + android_privacy_interaction_type (google.ads.googleads.v23.enums.types.AndroidPrivacyInteractionTypeEnum.AndroidPrivacyInteractionType): Output only. The interaction type enum used in the share key encoding. android_privacy_interaction_date (str): Output only. The interaction date used in the shared key encoding in the format of "YYYY-MM-DD" in UTC timezone. - android_privacy_network_type (google.ads.googleads.v19.enums.types.AndroidPrivacyNetworkTypeEnum.AndroidPrivacyNetworkType): + android_privacy_network_type (google.ads.googleads.v23.enums.types.AndroidPrivacyNetworkTypeEnum.AndroidPrivacyNetworkType): Output only. The network type enum used in the share key encoding. ad_group_id (int): diff --git a/google/ads/googleads/v19/resources/types/android_privacy_shared_key_google_campaign.py b/google/ads/googleads/v23/resources/types/android_privacy_shared_key_google_campaign.py similarity index 93% rename from google/ads/googleads/v19/resources/types/android_privacy_shared_key_google_campaign.py rename to google/ads/googleads/v23/resources/types/android_privacy_shared_key_google_campaign.py index 9d7501a2a..e7d828f58 100644 --- a/google/ads/googleads/v19/resources/types/android_privacy_shared_key_google_campaign.py +++ b/google/ads/googleads/v23/resources/types/android_privacy_shared_key_google_campaign.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( android_privacy_interaction_type as gage_android_privacy_interaction_type, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AndroidPrivacySharedKeyGoogleCampaign", }, @@ -45,7 +45,7 @@ class AndroidPrivacySharedKeyGoogleCampaign(proto.Message): campaign_id (int): Output only. The campaign ID used in the share key encoding. - android_privacy_interaction_type (google.ads.googleads.v19.enums.types.AndroidPrivacyInteractionTypeEnum.AndroidPrivacyInteractionType): + android_privacy_interaction_type (google.ads.googleads.v23.enums.types.AndroidPrivacyInteractionTypeEnum.AndroidPrivacyInteractionType): Output only. The interaction type enum used in the share key encoding. android_privacy_interaction_date (str): diff --git a/google/ads/googleads/v19/resources/types/android_privacy_shared_key_google_network_type.py b/google/ads/googleads/v23/resources/types/android_privacy_shared_key_google_network_type.py similarity index 91% rename from google/ads/googleads/v19/resources/types/android_privacy_shared_key_google_network_type.py rename to google/ads/googleads/v23/resources/types/android_privacy_shared_key_google_network_type.py index eb01af828..b4b546323 100644 --- a/google/ads/googleads/v19/resources/types/android_privacy_shared_key_google_network_type.py +++ b/google/ads/googleads/v23/resources/types/android_privacy_shared_key_google_network_type.py @@ -18,17 +18,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( android_privacy_interaction_type as gage_android_privacy_interaction_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( android_privacy_network_type as gage_android_privacy_network_type, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AndroidPrivacySharedKeyGoogleNetworkType", }, @@ -49,14 +49,14 @@ class AndroidPrivacySharedKeyGoogleNetworkType(proto.Message): campaign_id (int): Output only. The campaign ID used in the share key encoding. - android_privacy_interaction_type (google.ads.googleads.v19.enums.types.AndroidPrivacyInteractionTypeEnum.AndroidPrivacyInteractionType): + android_privacy_interaction_type (google.ads.googleads.v23.enums.types.AndroidPrivacyInteractionTypeEnum.AndroidPrivacyInteractionType): Output only. The interaction type enum used in the share key encoding. android_privacy_interaction_date (str): Output only. The interaction date used in the shared key encoding in the format of "YYYY-MM-DD" in UTC timezone. - android_privacy_network_type (google.ads.googleads.v19.enums.types.AndroidPrivacyNetworkTypeEnum.AndroidPrivacyNetworkType): + android_privacy_network_type (google.ads.googleads.v23.enums.types.AndroidPrivacyNetworkTypeEnum.AndroidPrivacyNetworkType): Output only. The network type enum used in the share key encoding. shared_network_type_key (str): diff --git a/google/ads/googleads/v23/resources/types/applied_incentive.py b/google/ads/googleads/v23/resources/types/applied_incentive.py new file mode 100644 index 000000000..d51e97272 --- /dev/null +++ b/google/ads/googleads/v23/resources/types/applied_incentive.py @@ -0,0 +1,186 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.ads.googleads.v23.enums.types import ( + incentive_state as gage_incentive_state, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "AppliedIncentive", + }, +) + + +class AppliedIncentive(proto.Message): + r"""Represents an applied incentive. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Output only. The resource name of the incentive. Incentive + resource names have the form: + + ``customers/{customer_id}/appliedIncentives/{coupon_code}`` + coupon_code (str): + Output only. The coupon code of the + incentive. + + This field is a member of `oneof`_ ``_coupon_code``. + incentive_state (google.ads.googleads.v23.enums.types.IncentiveStateEnum.IncentiveState): + Output only. The current state of the + incentive. + + This field is a member of `oneof`_ ``_incentive_state``. + redemption_date_time (str): + Output only. The redemption time of the + incentive in "YYYY-MM-DD HH:MM:SS" format in + UTC. + + This field is a member of `oneof`_ ``_redemption_date_time``. + fulfillment_expiration_date_time (str): + Output only. The time by which the + incentive's fulfillment requirements must be + met, in "YYYY-MM-DD HH:MM:SS" format in UTC. + + This field is a member of `oneof`_ ``_fulfillment_expiration_date_time``. + reward_grant_date_time (str): + Output only. The time when the reward was + granted in "YYYY-MM-DD HH:MM:SS" format in UTC. + This field is not set if the reward has not been + granted. + + This field is a member of `oneof`_ ``_reward_grant_date_time``. + reward_expiration_date_time (str): + Output only. The time when the granted reward + expires in "YYYY-MM-DD HH:MM:SS" format in UTC. + This field is not set if the reward has not been + granted. + + This field is a member of `oneof`_ ``_reward_expiration_date_time``. + currency_code (str): + Output only. The currency code for all + monetary amounts (for example, "USD"). + + This field is a member of `oneof`_ ``_currency_code``. + reward_amount_micros (int): + Output only. The maximum potential reward + amount in micros for the incentive. + + This field is a member of `oneof`_ ``_reward_amount_micros``. + granted_amount_micros (int): + Output only. The amount of the reward granted + in micros. This field is not set if the reward + has not been granted. + + This field is a member of `oneof`_ ``_granted_amount_micros``. + required_min_spend_micros (int): + Output only. The minimum amount that must be + spent to fulfill the coupon requirements, in + micros. + + This field is a member of `oneof`_ ``_required_min_spend_micros``. + current_spend_towards_fulfillment_micros (int): + Output only. The current amount spent towards + the fulfillment requirements, in micros. + + This field is a member of `oneof`_ ``_current_spend_towards_fulfillment_micros``. + reward_balance_remaining_micros (int): + Output only. The remaining balance of the + granted reward in micros. This field is not set + if the reward has not been granted. + + This field is a member of `oneof`_ ``_reward_balance_remaining_micros``. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + coupon_code: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + incentive_state: gage_incentive_state.IncentiveStateEnum.IncentiveState = ( + proto.Field( + proto.ENUM, + number=3, + optional=True, + enum=gage_incentive_state.IncentiveStateEnum.IncentiveState, + ) + ) + redemption_date_time: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + fulfillment_expiration_date_time: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + reward_grant_date_time: str = proto.Field( + proto.STRING, + number=6, + optional=True, + ) + reward_expiration_date_time: str = proto.Field( + proto.STRING, + number=7, + optional=True, + ) + currency_code: str = proto.Field( + proto.STRING, + number=8, + optional=True, + ) + reward_amount_micros: int = proto.Field( + proto.INT64, + number=9, + optional=True, + ) + granted_amount_micros: int = proto.Field( + proto.INT64, + number=10, + optional=True, + ) + required_min_spend_micros: int = proto.Field( + proto.INT64, + number=11, + optional=True, + ) + current_spend_towards_fulfillment_micros: int = proto.Field( + proto.INT64, + number=12, + optional=True, + ) + reward_balance_remaining_micros: int = proto.Field( + proto.INT64, + number=13, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/asset.py b/google/ads/googleads/v23/resources/types/asset.py similarity index 80% rename from google/ads/googleads/v19/resources/types/asset.py rename to google/ads/googleads/v23/resources/types/asset.py index 54a39f44e..74cbb424e 100644 --- a/google/ads/googleads/v19/resources/types/asset.py +++ b/google/ads/googleads/v23/resources/types/asset.py @@ -19,23 +19,24 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import asset_types -from google.ads.googleads.v19.common.types import custom_parameter -from google.ads.googleads.v19.common.types import policy -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import asset_types +from google.ads.googleads.v23.common.types import custom_parameter +from google.ads.googleads.v23.common.types import policy +from google.ads.googleads.v23.enums.types import ( asset_field_type as gage_asset_field_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import asset_orientation +from google.ads.googleads.v23.enums.types import ( asset_source as gage_asset_source, ) -from google.ads.googleads.v19.enums.types import asset_type -from google.ads.googleads.v19.enums.types import policy_approval_status -from google.ads.googleads.v19.enums.types import policy_review_status +from google.ads.googleads.v23.enums.types import asset_type +from google.ads.googleads.v23.enums.types import policy_approval_status +from google.ads.googleads.v23.enums.types import policy_review_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "Asset", "AssetFieldTypePolicySummary", @@ -72,7 +73,7 @@ class Asset(proto.Message): Optional name of the asset. This field is a member of `oneof`_ ``_name``. - type_ (google.ads.googleads.v19.enums.types.AssetTypeEnum.AssetType): + type_ (google.ads.googleads.v23.enums.types.AssetTypeEnum.AssetType): Output only. Type of the asset. final_urls (MutableSequence[str]): A list of possible final URLs after all cross @@ -84,7 +85,7 @@ class Asset(proto.Message): URL template for constructing a tracking URL. This field is a member of `oneof`_ ``_tracking_url_template``. - url_custom_parameters (MutableSequence[google.ads.googleads.v19.common.types.CustomParameter]): + url_custom_parameters (MutableSequence[google.ads.googleads.v23.common.types.CustomParameter]): A list of mappings to be used for substituting URL custom parameter tags in the tracking_url_template, final_urls, and/or final_mobile_urls. @@ -93,129 +94,138 @@ class Asset(proto.Message): page URLs served with parallel tracking. This field is a member of `oneof`_ ``_final_url_suffix``. - source (google.ads.googleads.v19.enums.types.AssetSourceEnum.AssetSource): + source (google.ads.googleads.v23.enums.types.AssetSourceEnum.AssetSource): Output only. Source of the asset. - policy_summary (google.ads.googleads.v19.resources.types.AssetPolicySummary): + policy_summary (google.ads.googleads.v23.resources.types.AssetPolicySummary): Output only. Policy information for the asset. - field_type_policy_summaries (MutableSequence[google.ads.googleads.v19.resources.types.AssetFieldTypePolicySummary]): + field_type_policy_summaries (MutableSequence[google.ads.googleads.v23.resources.types.AssetFieldTypePolicySummary]): Output only. Policy information for the asset for each FieldType. - youtube_video_asset (google.ads.googleads.v19.common.types.YoutubeVideoAsset): + orientation (google.ads.googleads.v23.enums.types.AssetOrientationEnum.AssetOrientation): + Output only. Orientation of the asset. This + is only supported for image and video assets. + + This field is a member of `oneof`_ ``_orientation``. + youtube_video_asset (google.ads.googleads.v23.common.types.YoutubeVideoAsset): Immutable. A YouTube video asset. This field is a member of `oneof`_ ``asset_data``. - media_bundle_asset (google.ads.googleads.v19.common.types.MediaBundleAsset): + media_bundle_asset (google.ads.googleads.v23.common.types.MediaBundleAsset): Immutable. A media bundle asset. This field is a member of `oneof`_ ``asset_data``. - image_asset (google.ads.googleads.v19.common.types.ImageAsset): + image_asset (google.ads.googleads.v23.common.types.ImageAsset): Output only. An image asset. This field is a member of `oneof`_ ``asset_data``. - text_asset (google.ads.googleads.v19.common.types.TextAsset): + text_asset (google.ads.googleads.v23.common.types.TextAsset): Immutable. A text asset. This field is a member of `oneof`_ ``asset_data``. - lead_form_asset (google.ads.googleads.v19.common.types.LeadFormAsset): + lead_form_asset (google.ads.googleads.v23.common.types.LeadFormAsset): A lead form asset. This field is a member of `oneof`_ ``asset_data``. - book_on_google_asset (google.ads.googleads.v19.common.types.BookOnGoogleAsset): + book_on_google_asset (google.ads.googleads.v23.common.types.BookOnGoogleAsset): A book on google asset. This field is a member of `oneof`_ ``asset_data``. - promotion_asset (google.ads.googleads.v19.common.types.PromotionAsset): + promotion_asset (google.ads.googleads.v23.common.types.PromotionAsset): A promotion asset. This field is a member of `oneof`_ ``asset_data``. - callout_asset (google.ads.googleads.v19.common.types.CalloutAsset): + callout_asset (google.ads.googleads.v23.common.types.CalloutAsset): A callout asset. This field is a member of `oneof`_ ``asset_data``. - structured_snippet_asset (google.ads.googleads.v19.common.types.StructuredSnippetAsset): + structured_snippet_asset (google.ads.googleads.v23.common.types.StructuredSnippetAsset): A structured snippet asset. This field is a member of `oneof`_ ``asset_data``. - sitelink_asset (google.ads.googleads.v19.common.types.SitelinkAsset): + sitelink_asset (google.ads.googleads.v23.common.types.SitelinkAsset): A sitelink asset. This field is a member of `oneof`_ ``asset_data``. - page_feed_asset (google.ads.googleads.v19.common.types.PageFeedAsset): + page_feed_asset (google.ads.googleads.v23.common.types.PageFeedAsset): A page feed asset. This field is a member of `oneof`_ ``asset_data``. - dynamic_education_asset (google.ads.googleads.v19.common.types.DynamicEducationAsset): + dynamic_education_asset (google.ads.googleads.v23.common.types.DynamicEducationAsset): A dynamic education asset. This field is a member of `oneof`_ ``asset_data``. - mobile_app_asset (google.ads.googleads.v19.common.types.MobileAppAsset): + mobile_app_asset (google.ads.googleads.v23.common.types.MobileAppAsset): A mobile app asset. This field is a member of `oneof`_ ``asset_data``. - hotel_callout_asset (google.ads.googleads.v19.common.types.HotelCalloutAsset): + hotel_callout_asset (google.ads.googleads.v23.common.types.HotelCalloutAsset): A hotel callout asset. This field is a member of `oneof`_ ``asset_data``. - call_asset (google.ads.googleads.v19.common.types.CallAsset): + call_asset (google.ads.googleads.v23.common.types.CallAsset): A call asset. This field is a member of `oneof`_ ``asset_data``. - price_asset (google.ads.googleads.v19.common.types.PriceAsset): + price_asset (google.ads.googleads.v23.common.types.PriceAsset): A price asset. This field is a member of `oneof`_ ``asset_data``. - call_to_action_asset (google.ads.googleads.v19.common.types.CallToActionAsset): + call_to_action_asset (google.ads.googleads.v23.common.types.CallToActionAsset): Immutable. A call to action asset. This field is a member of `oneof`_ ``asset_data``. - dynamic_real_estate_asset (google.ads.googleads.v19.common.types.DynamicRealEstateAsset): + dynamic_real_estate_asset (google.ads.googleads.v23.common.types.DynamicRealEstateAsset): A dynamic real estate asset. This field is a member of `oneof`_ ``asset_data``. - dynamic_custom_asset (google.ads.googleads.v19.common.types.DynamicCustomAsset): + dynamic_custom_asset (google.ads.googleads.v23.common.types.DynamicCustomAsset): A dynamic custom asset. This field is a member of `oneof`_ ``asset_data``. - dynamic_hotels_and_rentals_asset (google.ads.googleads.v19.common.types.DynamicHotelsAndRentalsAsset): + dynamic_hotels_and_rentals_asset (google.ads.googleads.v23.common.types.DynamicHotelsAndRentalsAsset): A dynamic hotels and rentals asset. This field is a member of `oneof`_ ``asset_data``. - dynamic_flights_asset (google.ads.googleads.v19.common.types.DynamicFlightsAsset): + dynamic_flights_asset (google.ads.googleads.v23.common.types.DynamicFlightsAsset): A dynamic flights asset. This field is a member of `oneof`_ ``asset_data``. - demand_gen_carousel_card_asset (google.ads.googleads.v19.common.types.DemandGenCarouselCardAsset): + demand_gen_carousel_card_asset (google.ads.googleads.v23.common.types.DemandGenCarouselCardAsset): Immutable. A Demand Gen carousel card asset. This field is a member of `oneof`_ ``asset_data``. - dynamic_travel_asset (google.ads.googleads.v19.common.types.DynamicTravelAsset): + dynamic_travel_asset (google.ads.googleads.v23.common.types.DynamicTravelAsset): A dynamic travel asset. This field is a member of `oneof`_ ``asset_data``. - dynamic_local_asset (google.ads.googleads.v19.common.types.DynamicLocalAsset): + dynamic_local_asset (google.ads.googleads.v23.common.types.DynamicLocalAsset): A dynamic local asset. This field is a member of `oneof`_ ``asset_data``. - dynamic_jobs_asset (google.ads.googleads.v19.common.types.DynamicJobsAsset): + dynamic_jobs_asset (google.ads.googleads.v23.common.types.DynamicJobsAsset): A dynamic jobs asset. This field is a member of `oneof`_ ``asset_data``. - location_asset (google.ads.googleads.v19.common.types.LocationAsset): + location_asset (google.ads.googleads.v23.common.types.LocationAsset): Output only. A location asset. This field is a member of `oneof`_ ``asset_data``. - hotel_property_asset (google.ads.googleads.v19.common.types.HotelPropertyAsset): + hotel_property_asset (google.ads.googleads.v23.common.types.HotelPropertyAsset): Immutable. A hotel property asset. This field is a member of `oneof`_ ``asset_data``. - business_message_asset (google.ads.googleads.v19.common.types.BusinessMessageAsset): + business_message_asset (google.ads.googleads.v23.common.types.BusinessMessageAsset): A business message asset. This field is a member of `oneof`_ ``asset_data``. - app_deep_link_asset (google.ads.googleads.v19.common.types.AppDeepLinkAsset): + app_deep_link_asset (google.ads.googleads.v23.common.types.AppDeepLinkAsset): Immutable. An app deep link asset. + This field is a member of `oneof`_ ``asset_data``. + youtube_video_list_asset (google.ads.googleads.v23.common.types.YouTubeVideoListAsset): + Immutable. A YouTube video list asset. + This field is a member of `oneof`_ ``asset_data``. """ @@ -280,6 +290,14 @@ class Asset(proto.Message): number=40, message="AssetFieldTypePolicySummary", ) + orientation: asset_orientation.AssetOrientationEnum.AssetOrientation = ( + proto.Field( + proto.ENUM, + number=54, + optional=True, + enum=asset_orientation.AssetOrientationEnum.AssetOrientation, + ) + ) youtube_video_asset: asset_types.YoutubeVideoAsset = proto.Field( proto.MESSAGE, number=5, @@ -458,6 +476,12 @@ class Asset(proto.Message): oneof="asset_data", message=asset_types.AppDeepLinkAsset, ) + youtube_video_list_asset: asset_types.YouTubeVideoListAsset = proto.Field( + proto.MESSAGE, + number=53, + oneof="asset_data", + message=asset_types.YouTubeVideoListAsset, + ) class AssetFieldTypePolicySummary(proto.Message): @@ -468,15 +492,15 @@ class AssetFieldTypePolicySummary(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - asset_field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + asset_field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): Output only. FieldType of this asset. This field is a member of `oneof`_ ``_asset_field_type``. - asset_source (google.ads.googleads.v19.enums.types.AssetSourceEnum.AssetSource): + asset_source (google.ads.googleads.v23.enums.types.AssetSourceEnum.AssetSource): Output only. Source of this asset. This field is a member of `oneof`_ ``_asset_source``. - policy_summary_info (google.ads.googleads.v19.resources.types.AssetPolicySummary): + policy_summary_info (google.ads.googleads.v23.resources.types.AssetPolicySummary): Output only. Policy summary. This field is a member of `oneof`_ ``_policy_summary_info``. @@ -508,13 +532,13 @@ class AssetPolicySummary(proto.Message): r"""Contains policy information for an asset. Attributes: - policy_topic_entries (MutableSequence[google.ads.googleads.v19.common.types.PolicyTopicEntry]): + policy_topic_entries (MutableSequence[google.ads.googleads.v23.common.types.PolicyTopicEntry]): Output only. The list of policy findings for this asset. - review_status (google.ads.googleads.v19.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): + review_status (google.ads.googleads.v23.enums.types.PolicyReviewStatusEnum.PolicyReviewStatus): Output only. Where in the review process this asset is. - approval_status (google.ads.googleads.v19.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): + approval_status (google.ads.googleads.v23.enums.types.PolicyApprovalStatusEnum.PolicyApprovalStatus): Output only. The overall approval status of this asset, calculated based on the status of its individual policy topic entries. diff --git a/google/ads/googleads/v19/resources/types/asset_field_type_view.py b/google/ads/googleads/v23/resources/types/asset_field_type_view.py similarity index 88% rename from google/ads/googleads/v19/resources/types/asset_field_type_view.py rename to google/ads/googleads/v23/resources/types/asset_field_type_view.py index 1b40b006f..3fe55aa9c 100644 --- a/google/ads/googleads/v19/resources/types/asset_field_type_view.py +++ b/google/ads/googleads/v23/resources/types/asset_field_type_view.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import asset_field_type +from google.ads.googleads.v23.enums.types import asset_field_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AssetFieldTypeView", }, @@ -41,7 +41,7 @@ class AssetFieldTypeView(proto.Message): Asset field type view resource names have the form: ``customers/{customer_id}/assetFieldTypeViews/{field_type}`` - field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): Output only. The asset field type of the asset field type view. """ diff --git a/google/ads/googleads/v19/resources/types/asset_group.py b/google/ads/googleads/v23/resources/types/asset_group.py similarity index 88% rename from google/ads/googleads/v19/resources/types/asset_group.py rename to google/ads/googleads/v23/resources/types/asset_group.py index 0b46d61c3..cc0fd3a8b 100644 --- a/google/ads/googleads/v19/resources/types/asset_group.py +++ b/google/ads/googleads/v23/resources/types/asset_group.py @@ -19,24 +19,24 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ad_strength as gage_ad_strength -from google.ads.googleads.v19.enums.types import ad_strength_action_item_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ad_strength as gage_ad_strength +from google.ads.googleads.v23.enums.types import ad_strength_action_item_type +from google.ads.googleads.v23.enums.types import ( asset_coverage_video_aspect_ratio_requirement, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( asset_field_type as gage_asset_field_type, ) -from google.ads.googleads.v19.enums.types import asset_group_primary_status -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import asset_group_primary_status +from google.ads.googleads.v23.enums.types import ( asset_group_primary_status_reason, ) -from google.ads.googleads.v19.enums.types import asset_group_status +from google.ads.googleads.v23.enums.types import asset_group_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AssetGroup", "AssetCoverage", @@ -78,13 +78,13 @@ class AssetGroup(proto.Message): domain redirects. In performance max, by default, the urls are eligible for expansion unless opted out. - status (google.ads.googleads.v19.enums.types.AssetGroupStatusEnum.AssetGroupStatus): + status (google.ads.googleads.v23.enums.types.AssetGroupStatusEnum.AssetGroupStatus): The status of the asset group. - primary_status (google.ads.googleads.v19.enums.types.AssetGroupPrimaryStatusEnum.AssetGroupPrimaryStatus): + primary_status (google.ads.googleads.v23.enums.types.AssetGroupPrimaryStatusEnum.AssetGroupPrimaryStatus): Output only. The primary status of the asset group. Provides insights into why an asset group is not serving or not serving optimally. - primary_status_reasons (MutableSequence[google.ads.googleads.v19.enums.types.AssetGroupPrimaryStatusReasonEnum.AssetGroupPrimaryStatusReason]): + primary_status_reasons (MutableSequence[google.ads.googleads.v23.enums.types.AssetGroupPrimaryStatusReasonEnum.AssetGroupPrimaryStatusReason]): Output only. Provides reasons into why an asset group is not serving or not serving optimally. It will be empty when the asset group @@ -96,10 +96,10 @@ class AssetGroup(proto.Message): Second part of text that may appear appended to the url displayed in the ad. This field can only be set when path1 is set. - ad_strength (google.ads.googleads.v19.enums.types.AdStrengthEnum.AdStrength): + ad_strength (google.ads.googleads.v23.enums.types.AdStrengthEnum.AdStrength): Output only. Overall ad strength of this asset group. - asset_coverage (google.ads.googleads.v19.resources.types.AssetCoverage): + asset_coverage (google.ads.googleads.v23.resources.types.AssetCoverage): Output only. The asset coverage of this asset group. """ @@ -173,7 +173,7 @@ class AssetCoverage(proto.Message): r"""Information about the asset coverage of an asset group. Attributes: - ad_strength_action_items (MutableSequence[google.ads.googleads.v19.resources.types.AdStrengthActionItem]): + ad_strength_action_items (MutableSequence[google.ads.googleads.v23.resources.types.AdStrengthActionItem]): Output only. A list of action items to improve the ad strength of an asset group. """ @@ -193,9 +193,9 @@ class AdStrengthActionItem(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - action_item_type (google.ads.googleads.v19.enums.types.AdStrengthActionItemTypeEnum.AdStrengthActionItemType): + action_item_type (google.ads.googleads.v23.enums.types.AdStrengthActionItemTypeEnum.AdStrengthActionItemType): Output only. The action item type. - add_asset_details (google.ads.googleads.v19.resources.types.AdStrengthActionItem.AddAssetDetails): + add_asset_details (google.ads.googleads.v23.resources.types.AdStrengthActionItem.AddAssetDetails): Output only. The action item details for action item type ADD_ASSET. @@ -208,14 +208,14 @@ class AddAssetDetails(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - asset_field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + asset_field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): Output only. The asset field type of the asset(s) to add. asset_count (int): Output only. The number of assets to add. This field is a member of `oneof`_ ``_asset_count``. - video_aspect_ratio_requirement (google.ads.googleads.v19.enums.types.AssetCoverageVideoAspectRatioRequirementEnum.AssetCoverageVideoAspectRatioRequirement): + video_aspect_ratio_requirement (google.ads.googleads.v23.enums.types.AssetCoverageVideoAspectRatioRequirementEnum.AssetCoverageVideoAspectRatioRequirement): Output only. For video field types, the required aspect ratio of the video. When unset and asset_field_type is YOUTUBE_VIDEO, the system recommends the advertiser upload diff --git a/google/ads/googleads/v19/resources/types/asset_group_asset.py b/google/ads/googleads/v23/resources/types/asset_group_asset.py similarity index 76% rename from google/ads/googleads/v19/resources/types/asset_group_asset.py rename to google/ads/googleads/v23/resources/types/asset_group_asset.py index 488dc6099..f24b721f9 100644 --- a/google/ads/googleads/v19/resources/types/asset_group_asset.py +++ b/google/ads/googleads/v23/resources/types/asset_group_asset.py @@ -19,23 +19,22 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import asset_policy -from google.ads.googleads.v19.common.types import ( +from google.ads.googleads.v23.common.types import asset_policy +from google.ads.googleads.v23.common.types import ( policy_summary as gagc_policy_summary, ) -from google.ads.googleads.v19.enums.types import asset_field_type -from google.ads.googleads.v19.enums.types import asset_link_primary_status -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import asset_field_type +from google.ads.googleads.v23.enums.types import asset_link_primary_status +from google.ads.googleads.v23.enums.types import ( asset_link_primary_status_reason, ) -from google.ads.googleads.v19.enums.types import asset_link_status -from google.ads.googleads.v19.enums.types import asset_performance_label -from google.ads.googleads.v19.enums.types import asset_source +from google.ads.googleads.v23.enums.types import asset_link_status +from google.ads.googleads.v23.enums.types import asset_source __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupAsset", }, @@ -59,13 +58,13 @@ class AssetGroupAsset(proto.Message): asset (str): Immutable. The asset which this asset group asset is linking. - field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): The description of the placement of the asset within the asset group. For example: HEADLINE, YOUTUBE_VIDEO etc - status (google.ads.googleads.v19.enums.types.AssetLinkStatusEnum.AssetLinkStatus): + status (google.ads.googleads.v23.enums.types.AssetLinkStatusEnum.AssetLinkStatus): The status of the link between an asset and asset group. - primary_status (google.ads.googleads.v19.enums.types.AssetLinkPrimaryStatusEnum.AssetLinkPrimaryStatus): + primary_status (google.ads.googleads.v23.enums.types.AssetLinkPrimaryStatusEnum.AssetLinkPrimaryStatus): Output only. Provides the PrimaryStatus of this asset link. Primary status is meant essentially to differentiate between the plain @@ -75,20 +74,17 @@ class AssetGroupAsset(proto.Message): assets its mainly policy and quality approvals) to come up with a more comprehensive status to indicate its serving state. - primary_status_reasons (MutableSequence[google.ads.googleads.v19.enums.types.AssetLinkPrimaryStatusReasonEnum.AssetLinkPrimaryStatusReason]): + primary_status_reasons (MutableSequence[google.ads.googleads.v23.enums.types.AssetLinkPrimaryStatusReasonEnum.AssetLinkPrimaryStatusReason]): Output only. Provides a list of reasons for why an asset is not serving or not serving at full capacity. - primary_status_details (MutableSequence[google.ads.googleads.v19.common.types.AssetLinkPrimaryStatusDetails]): + primary_status_details (MutableSequence[google.ads.googleads.v23.common.types.AssetLinkPrimaryStatusDetails]): Output only. Provides the details of the primary status and its associated reasons. - performance_label (google.ads.googleads.v19.enums.types.AssetPerformanceLabelEnum.AssetPerformanceLabel): - Output only. The performance of this asset - group asset. - policy_summary (google.ads.googleads.v19.common.types.PolicySummary): + policy_summary (google.ads.googleads.v23.common.types.PolicySummary): Output only. The policy information for this asset group asset. - source (google.ads.googleads.v19.enums.types.AssetSourceEnum.AssetSource): + source (google.ads.googleads.v23.enums.types.AssetSourceEnum.AssetSource): Output only. Source of the asset group asset. """ @@ -137,13 +133,6 @@ class AssetGroupAsset(proto.Message): number=10, message=asset_policy.AssetLinkPrimaryStatusDetails, ) - performance_label: ( - asset_performance_label.AssetPerformanceLabelEnum.AssetPerformanceLabel - ) = proto.Field( - proto.ENUM, - number=6, - enum=asset_performance_label.AssetPerformanceLabelEnum.AssetPerformanceLabel, - ) policy_summary: gagc_policy_summary.PolicySummary = proto.Field( proto.MESSAGE, number=7, diff --git a/google/ads/googleads/v19/resources/types/asset_group_listing_group_filter.py b/google/ads/googleads/v23/resources/types/asset_group_listing_group_filter.py similarity index 90% rename from google/ads/googleads/v19/resources/types/asset_group_listing_group_filter.py rename to google/ads/googleads/v23/resources/types/asset_group_listing_group_filter.py index 94f88dc2b..a12035ea2 100644 --- a/google/ads/googleads/v19/resources/types/asset_group_listing_group_filter.py +++ b/google/ads/googleads/v23/resources/types/asset_group_listing_group_filter.py @@ -19,30 +19,30 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( listing_group_filter_custom_attribute_index, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( listing_group_filter_listing_source, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( listing_group_filter_product_category_level, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( listing_group_filter_product_channel, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( listing_group_filter_product_condition, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( listing_group_filter_product_type_level, ) -from google.ads.googleads.v19.enums.types import listing_group_filter_type_enum +from google.ads.googleads.v23.enums.types import listing_group_filter_type_enum __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupListingGroupFilter", "ListingGroupFilterDimensionPath", @@ -68,13 +68,13 @@ class AssetGroupListingGroupFilter(proto.Message): id (int): Output only. The ID of the ListingGroupFilter. - type_ (google.ads.googleads.v19.enums.types.ListingGroupFilterTypeEnum.ListingGroupFilterType): + type_ (google.ads.googleads.v23.enums.types.ListingGroupFilterTypeEnum.ListingGroupFilterType): Immutable. Type of a listing group filter node. - listing_source (google.ads.googleads.v19.enums.types.ListingGroupFilterListingSourceEnum.ListingGroupFilterListingSource): + listing_source (google.ads.googleads.v23.enums.types.ListingGroupFilterListingSourceEnum.ListingGroupFilterListingSource): Immutable. The source of listings filtered by this listing group filter. - case_value (google.ads.googleads.v19.resources.types.ListingGroupFilterDimension): + case_value (google.ads.googleads.v23.resources.types.ListingGroupFilterDimension): Dimension value with which this listing group is refining its parent. Undefined for the root group. @@ -82,7 +82,7 @@ class AssetGroupListingGroupFilter(proto.Message): Immutable. Resource name of the parent listing group subdivision. Null for the root listing group filter node. - path (google.ads.googleads.v19.resources.types.ListingGroupFilterDimensionPath): + path (google.ads.googleads.v23.resources.types.ListingGroupFilterDimensionPath): Output only. The path of dimensions defining this listing group filter. """ @@ -134,7 +134,7 @@ class ListingGroupFilterDimensionPath(proto.Message): filter. Attributes: - dimensions (MutableSequence[google.ads.googleads.v19.resources.types.ListingGroupFilterDimension]): + dimensions (MutableSequence[google.ads.googleads.v23.resources.types.ListingGroupFilterDimension]): Output only. The complete path of dimensions through the listing group filter hierarchy (excluding the root node) to this listing group @@ -161,35 +161,35 @@ class ListingGroupFilterDimension(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - product_category (google.ads.googleads.v19.resources.types.ListingGroupFilterDimension.ProductCategory): + product_category (google.ads.googleads.v23.resources.types.ListingGroupFilterDimension.ProductCategory): Category of a product offer. This field is a member of `oneof`_ ``dimension``. - product_brand (google.ads.googleads.v19.resources.types.ListingGroupFilterDimension.ProductBrand): + product_brand (google.ads.googleads.v23.resources.types.ListingGroupFilterDimension.ProductBrand): Brand of a product offer. This field is a member of `oneof`_ ``dimension``. - product_channel (google.ads.googleads.v19.resources.types.ListingGroupFilterDimension.ProductChannel): + product_channel (google.ads.googleads.v23.resources.types.ListingGroupFilterDimension.ProductChannel): Locality of a product offer. This field is a member of `oneof`_ ``dimension``. - product_condition (google.ads.googleads.v19.resources.types.ListingGroupFilterDimension.ProductCondition): + product_condition (google.ads.googleads.v23.resources.types.ListingGroupFilterDimension.ProductCondition): Condition of a product offer. This field is a member of `oneof`_ ``dimension``. - product_custom_attribute (google.ads.googleads.v19.resources.types.ListingGroupFilterDimension.ProductCustomAttribute): + product_custom_attribute (google.ads.googleads.v23.resources.types.ListingGroupFilterDimension.ProductCustomAttribute): Custom attribute of a product offer. This field is a member of `oneof`_ ``dimension``. - product_item_id (google.ads.googleads.v19.resources.types.ListingGroupFilterDimension.ProductItemId): + product_item_id (google.ads.googleads.v23.resources.types.ListingGroupFilterDimension.ProductItemId): Item id of a product offer. This field is a member of `oneof`_ ``dimension``. - product_type (google.ads.googleads.v19.resources.types.ListingGroupFilterDimension.ProductType): + product_type (google.ads.googleads.v23.resources.types.ListingGroupFilterDimension.ProductType): Type of a product offer. This field is a member of `oneof`_ ``dimension``. - webpage (google.ads.googleads.v19.resources.types.ListingGroupFilterDimension.Webpage): + webpage (google.ads.googleads.v23.resources.types.ListingGroupFilterDimension.Webpage): Filters for URLs in a page feed and URLs from the advertiser web domain. @@ -216,7 +216,7 @@ class ProductCategory(proto.Message): https://support.google.com/merchants/answer/6324436 This field is a member of `oneof`_ ``_category_id``. - level (google.ads.googleads.v19.enums.types.ListingGroupFilterProductCategoryLevelEnum.ListingGroupFilterProductCategoryLevel): + level (google.ads.googleads.v23.enums.types.ListingGroupFilterProductCategoryLevelEnum.ListingGroupFilterProductCategoryLevel): Indicates the level of the category in the taxonomy. """ @@ -256,7 +256,7 @@ class ProductChannel(proto.Message): r"""Locality of a product offer. Attributes: - channel (google.ads.googleads.v19.enums.types.ListingGroupFilterProductChannelEnum.ListingGroupFilterProductChannel): + channel (google.ads.googleads.v23.enums.types.ListingGroupFilterProductChannelEnum.ListingGroupFilterProductChannel): Value of the locality. """ @@ -272,7 +272,7 @@ class ProductCondition(proto.Message): r"""Condition of a product offer. Attributes: - condition (google.ads.googleads.v19.enums.types.ListingGroupFilterProductConditionEnum.ListingGroupFilterProductCondition): + condition (google.ads.googleads.v23.enums.types.ListingGroupFilterProductConditionEnum.ListingGroupFilterProductCondition): Value of the condition. """ @@ -294,7 +294,7 @@ class ProductCustomAttribute(proto.Message): String value of the product custom attribute. This field is a member of `oneof`_ ``_value``. - index (google.ads.googleads.v19.enums.types.ListingGroupFilterCustomAttributeIndexEnum.ListingGroupFilterCustomAttributeIndex): + index (google.ads.googleads.v23.enums.types.ListingGroupFilterCustomAttributeIndexEnum.ListingGroupFilterCustomAttributeIndex): Indicates the index of the custom attribute. """ @@ -339,7 +339,7 @@ class ProductType(proto.Message): Value of the type. This field is a member of `oneof`_ ``_value``. - level (google.ads.googleads.v19.enums.types.ListingGroupFilterProductTypeLevelEnum.ListingGroupFilterProductTypeLevel): + level (google.ads.googleads.v23.enums.types.ListingGroupFilterProductTypeLevelEnum.ListingGroupFilterProductTypeLevel): Level of the type. """ @@ -362,7 +362,7 @@ class Webpage(proto.Message): in an asset group and their conditions are considered in OR. Attributes: - conditions (MutableSequence[google.ads.googleads.v19.resources.types.ListingGroupFilterDimension.WebpageCondition]): + conditions (MutableSequence[google.ads.googleads.v23.resources.types.ListingGroupFilterDimension.WebpageCondition]): The webpage conditions are case sensitive and these are and-ed together when evaluated for filtering. All the conditions should be of same type. Example1: for URL1 = diff --git a/google/ads/googleads/v19/resources/types/asset_group_product_group_view.py b/google/ads/googleads/v23/resources/types/asset_group_product_group_view.py similarity index 95% rename from google/ads/googleads/v19/resources/types/asset_group_product_group_view.py rename to google/ads/googleads/v23/resources/types/asset_group_product_group_view.py index bd8c1cdb1..157fb8220 100644 --- a/google/ads/googleads/v19/resources/types/asset_group_product_group_view.py +++ b/google/ads/googleads/v23/resources/types/asset_group_product_group_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupProductGroupView", }, diff --git a/google/ads/googleads/v19/resources/types/asset_group_signal.py b/google/ads/googleads/v23/resources/types/asset_group_signal.py similarity index 91% rename from google/ads/googleads/v19/resources/types/asset_group_signal.py rename to google/ads/googleads/v23/resources/types/asset_group_signal.py index b88e4db7a..ade0ccf65 100644 --- a/google/ads/googleads/v19/resources/types/asset_group_signal.py +++ b/google/ads/googleads/v23/resources/types/asset_group_signal.py @@ -19,15 +19,15 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import ( asset_group_signal_approval_status, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupSignal", }, @@ -57,7 +57,7 @@ class AssetGroupSignal(proto.Message): asset_group (str): Immutable. The asset group which this asset group signal belongs to. - approval_status (google.ads.googleads.v19.enums.types.AssetGroupSignalApprovalStatusEnum.AssetGroupSignalApprovalStatus): + approval_status (google.ads.googleads.v23.enums.types.AssetGroupSignalApprovalStatusEnum.AssetGroupSignalApprovalStatus): Output only. Approval status is the output value for search theme signal after Google ads policy review. When using Audience signal, this @@ -66,12 +66,12 @@ class AssetGroupSignal(proto.Message): Output only. Computed for SearchTheme signals. When using Audience signal, this field is not used and will be absent. - audience (google.ads.googleads.v19.common.types.AudienceInfo): + audience (google.ads.googleads.v23.common.types.AudienceInfo): Immutable. The audience signal to be used by the performance max campaign. This field is a member of `oneof`_ ``signal``. - search_theme (google.ads.googleads.v19.common.types.SearchThemeInfo): + search_theme (google.ads.googleads.v23.common.types.SearchThemeInfo): Immutable. The search_theme signal to be used by the performance max campaign. Mutate errors of search_theme criterion includes AssetGroupSignalError.UNSPECIFIED diff --git a/google/ads/googleads/v19/resources/types/asset_group_top_combination_view.py b/google/ads/googleads/v23/resources/types/asset_group_top_combination_view.py similarity index 89% rename from google/ads/googleads/v19/resources/types/asset_group_top_combination_view.py rename to google/ads/googleads/v23/resources/types/asset_group_top_combination_view.py index 5d47038d4..99d86def0 100644 --- a/google/ads/googleads/v19/resources/types/asset_group_top_combination_view.py +++ b/google/ads/googleads/v23/resources/types/asset_group_top_combination_view.py @@ -19,12 +19,12 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import asset_usage +from google.ads.googleads.v23.common.types import asset_usage __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AssetGroupTopCombinationView", "AssetGroupAssetCombinationData", @@ -41,7 +41,7 @@ class AssetGroupTopCombinationView(proto.Message): combination view. AssetGroup Top Combination view resource names have the form: \`"customers/{customer_id}/assetGroupTopCombinationViews/{asset_group_id}~{asset_combination_category}". - asset_group_top_combinations (MutableSequence[google.ads.googleads.v19.resources.types.AssetGroupAssetCombinationData]): + asset_group_top_combinations (MutableSequence[google.ads.googleads.v23.resources.types.AssetGroupAssetCombinationData]): Output only. The top combinations of assets that served together. """ @@ -63,7 +63,7 @@ class AssetGroupAssetCombinationData(proto.Message): r"""Asset group asset combination data Attributes: - asset_combination_served_assets (MutableSequence[google.ads.googleads.v19.common.types.AssetUsage]): + asset_combination_served_assets (MutableSequence[google.ads.googleads.v23.common.types.AssetUsage]): Output only. Served assets. """ diff --git a/google/ads/googleads/v19/resources/types/asset_set.py b/google/ads/googleads/v23/resources/types/asset_set.py similarity index 86% rename from google/ads/googleads/v19/resources/types/asset_set.py rename to google/ads/googleads/v23/resources/types/asset_set.py index 2c4e41074..b549c6d68 100644 --- a/google/ads/googleads/v19/resources/types/asset_set.py +++ b/google/ads/googleads/v23/resources/types/asset_set.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import asset_set_types -from google.ads.googleads.v19.enums.types import asset_set_status -from google.ads.googleads.v19.enums.types import asset_set_type +from google.ads.googleads.v23.common.types import asset_set_types +from google.ads.googleads.v23.enums.types import asset_set_status +from google.ads.googleads.v23.enums.types import asset_set_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AssetSet", }, @@ -55,39 +55,39 @@ class AssetSet(proto.Message): Required. Name of the asset set. Required. It must have a minimum length of 1 and maximum length of 128. - type_ (google.ads.googleads.v19.enums.types.AssetSetTypeEnum.AssetSetType): + type_ (google.ads.googleads.v23.enums.types.AssetSetTypeEnum.AssetSetType): Required. Immutable. The type of the asset set. Required. - status (google.ads.googleads.v19.enums.types.AssetSetStatusEnum.AssetSetStatus): + status (google.ads.googleads.v23.enums.types.AssetSetStatusEnum.AssetSetStatus): Output only. The status of the asset set. Read-only. - merchant_center_feed (google.ads.googleads.v19.resources.types.AssetSet.MerchantCenterFeed): + merchant_center_feed (google.ads.googleads.v23.resources.types.AssetSet.MerchantCenterFeed): Merchant ID and Feed Label from Google Merchant Center. location_group_parent_asset_set_id (int): - Immutable. Parent asset set id for the asset + Immutable. Parent asset set ID for the asset set where the elements of this asset set come from. For example: the sync level location - AssetSet id where the the elements in - LocationGroup AssetSet come from. This field is - required and only applicable for Location Group - typed AssetSet. - hotel_property_data (google.ads.googleads.v19.resources.types.AssetSet.HotelPropertyData): + AssetSet id where the elements in LocationGroup + AssetSet come from. This field is required and + only applicable for Location Group typed + AssetSet. + hotel_property_data (google.ads.googleads.v23.resources.types.AssetSet.HotelPropertyData): Output only. For Performance Max for travel goals campaigns with a Hotel Center account link. Read-only. - location_set (google.ads.googleads.v19.common.types.LocationSet): + location_set (google.ads.googleads.v23.common.types.LocationSet): Location asset set data. This will be used for sync level location set. This can only be set if AssetSet's type is LOCATION_SYNC. This field is a member of `oneof`_ ``asset_set_source``. - business_profile_location_group (google.ads.googleads.v19.common.types.BusinessProfileLocationGroup): + business_profile_location_group (google.ads.googleads.v23.common.types.BusinessProfileLocationGroup): Business Profile location group asset set data. This field is a member of `oneof`_ ``asset_set_source``. - chain_location_group (google.ads.googleads.v19.common.types.ChainLocationGroup): + chain_location_group (google.ads.googleads.v23.common.types.ChainLocationGroup): Represents information about a Chain dynamic location group. Only applicable if the sync level AssetSet's type is LOCATION_SYNC and sync source is chain. diff --git a/google/ads/googleads/v19/resources/types/asset_set_asset.py b/google/ads/googleads/v23/resources/types/asset_set_asset.py similarity index 90% rename from google/ads/googleads/v19/resources/types/asset_set_asset.py rename to google/ads/googleads/v23/resources/types/asset_set_asset.py index b35e9944b..d0ed1ee91 100644 --- a/google/ads/googleads/v19/resources/types/asset_set_asset.py +++ b/google/ads/googleads/v23/resources/types/asset_set_asset.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import asset_set_asset_status +from google.ads.googleads.v23.enums.types import asset_set_asset_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AssetSetAsset", }, @@ -46,7 +46,7 @@ class AssetSetAsset(proto.Message): asset (str): Immutable. The asset which this asset set asset is linking to. - status (google.ads.googleads.v19.enums.types.AssetSetAssetStatusEnum.AssetSetAssetStatus): + status (google.ads.googleads.v23.enums.types.AssetSetAssetStatusEnum.AssetSetAssetStatus): Output only. The status of the asset set asset. Read-only. """ diff --git a/google/ads/googleads/v19/resources/types/asset_set_type_view.py b/google/ads/googleads/v23/resources/types/asset_set_type_view.py similarity index 89% rename from google/ads/googleads/v19/resources/types/asset_set_type_view.py rename to google/ads/googleads/v23/resources/types/asset_set_type_view.py index ac6a8c559..4ad8a7054 100644 --- a/google/ads/googleads/v19/resources/types/asset_set_type_view.py +++ b/google/ads/googleads/v23/resources/types/asset_set_type_view.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( asset_set_type as gage_asset_set_type, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "AssetSetTypeView", }, @@ -44,7 +44,7 @@ class AssetSetTypeView(proto.Message): Asset set type view resource names have the form: ``customers/{customer_id}/assetSetTypeViews/{asset_set_type}`` - asset_set_type (google.ads.googleads.v19.enums.types.AssetSetTypeEnum.AssetSetType): + asset_set_type (google.ads.googleads.v23.enums.types.AssetSetTypeEnum.AssetSetType): Output only. The asset set type of the asset set type view. """ diff --git a/google/ads/googleads/v19/resources/types/audience.py b/google/ads/googleads/v23/resources/types/audience.py similarity index 88% rename from google/ads/googleads/v19/resources/types/audience.py rename to google/ads/googleads/v23/resources/types/audience.py index 26e03170e..2a294b2e9 100644 --- a/google/ads/googleads/v19/resources/types/audience.py +++ b/google/ads/googleads/v23/resources/types/audience.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import audiences -from google.ads.googleads.v19.enums.types import audience_scope -from google.ads.googleads.v19.enums.types import audience_status +from google.ads.googleads.v23.common.types import audiences +from google.ads.googleads.v23.enums.types import audience_scope +from google.ads.googleads.v23.enums.types import audience_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "Audience", }, @@ -50,7 +50,7 @@ class Audience(proto.Message): ``customers/{customer_id}/audiences/{audience_id}`` id (int): Output only. ID of the audience. - status (google.ads.googleads.v19.enums.types.AudienceStatusEnum.AudienceStatus): + status (google.ads.googleads.v23.enums.types.AudienceStatusEnum.AudienceStatus): Output only. Status of this audience. Indicates whether the audience is enabled or removed. @@ -64,13 +64,13 @@ class Audience(proto.Message): This field is a member of `oneof`_ ``_name``. description (str): Description of this audience. - dimensions (MutableSequence[google.ads.googleads.v19.common.types.AudienceDimension]): + dimensions (MutableSequence[google.ads.googleads.v23.common.types.AudienceDimension]): Positive dimensions specifying the audience composition. - exclusion_dimension (google.ads.googleads.v19.common.types.AudienceExclusionDimension): + exclusion_dimension (google.ads.googleads.v23.common.types.AudienceExclusionDimension): Negative dimension specifying the audience composition. - scope (google.ads.googleads.v19.enums.types.AudienceScopeEnum.AudienceScope): + scope (google.ads.googleads.v23.enums.types.AudienceScopeEnum.AudienceScope): Defines the scope this audience can be used in. By default, the scope is CUSTOMER. Audiences can be created with a scope of ASSET_GROUP for exclusive use by a single asset_group. diff --git a/google/ads/googleads/v19/resources/types/batch_job.py b/google/ads/googleads/v23/resources/types/batch_job.py similarity index 95% rename from google/ads/googleads/v19/resources/types/batch_job.py rename to google/ads/googleads/v23/resources/types/batch_job.py index ccb130082..a4d68fda3 100644 --- a/google/ads/googleads/v19/resources/types/batch_job.py +++ b/google/ads/googleads/v23/resources/types/batch_job.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import batch_job_status +from google.ads.googleads.v23.enums.types import batch_job_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "BatchJob", }, @@ -55,10 +55,10 @@ class BatchJob(proto.Message): job status is PENDING. This field is a member of `oneof`_ ``_next_add_sequence_token``. - metadata (google.ads.googleads.v19.resources.types.BatchJob.BatchJobMetadata): + metadata (google.ads.googleads.v23.resources.types.BatchJob.BatchJobMetadata): Output only. Contains additional information about this batch job. - status (google.ads.googleads.v19.enums.types.BatchJobStatusEnum.BatchJobStatus): + status (google.ads.googleads.v23.enums.types.BatchJobStatusEnum.BatchJobStatus): Output only. Status of this batch job. long_running_operation (str): Output only. The resource name of the diff --git a/google/ads/googleads/v19/resources/types/bidding_data_exclusion.py b/google/ads/googleads/v23/resources/types/bidding_data_exclusion.py similarity index 89% rename from google/ads/googleads/v19/resources/types/bidding_data_exclusion.py rename to google/ads/googleads/v23/resources/types/bidding_data_exclusion.py index 7d42c244d..f7020b518 100644 --- a/google/ads/googleads/v19/resources/types/bidding_data_exclusion.py +++ b/google/ads/googleads/v23/resources/types/bidding_data_exclusion.py @@ -19,15 +19,15 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import advertising_channel_type -from google.ads.googleads.v19.enums.types import device -from google.ads.googleads.v19.enums.types import seasonality_event_scope -from google.ads.googleads.v19.enums.types import seasonality_event_status +from google.ads.googleads.v23.enums.types import advertising_channel_type +from google.ads.googleads.v23.enums.types import device +from google.ads.googleads.v23.enums.types import seasonality_event_scope +from google.ads.googleads.v23.enums.types import seasonality_event_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "BiddingDataExclusion", }, @@ -50,9 +50,9 @@ class BiddingDataExclusion(proto.Message): ``customers/{customer_id}/biddingDataExclusions/{data_exclusion_id}`` data_exclusion_id (int): Output only. The ID of the data exclusion. - scope (google.ads.googleads.v19.enums.types.SeasonalityEventScopeEnum.SeasonalityEventScope): + scope (google.ads.googleads.v23.enums.types.SeasonalityEventScopeEnum.SeasonalityEventScope): The scope of the data exclusion. - status (google.ads.googleads.v19.enums.types.SeasonalityEventStatusEnum.SeasonalityEventStatus): + status (google.ads.googleads.v23.enums.types.SeasonalityEventStatusEnum.SeasonalityEventStatus): Output only. The status of the data exclusion. start_date_time (str): @@ -74,7 +74,7 @@ class BiddingDataExclusion(proto.Message): description (str): The description of the data exclusion. The description can be at most 2048 characters. - devices (MutableSequence[google.ads.googleads.v19.enums.types.DeviceEnum.Device]): + devices (MutableSequence[google.ads.googleads.v23.enums.types.DeviceEnum.Device]): If not specified, all devices will be included in this exclusion. Otherwise, only the specified targeted devices will be included in @@ -85,7 +85,7 @@ class BiddingDataExclusion(proto.Message): of campaigns per event is 2000. Note: a data exclusion with both advertising_channel_types and campaign_ids is not supported. - advertising_channel_types (MutableSequence[google.ads.googleads.v19.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType]): + advertising_channel_types (MutableSequence[google.ads.googleads.v23.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType]): The data_exclusion will apply to all the campaigns under the listed channels retroactively as well as going forward when the scope of this exclusion is CHANNEL. The supported diff --git a/google/ads/googleads/v19/resources/types/bidding_seasonality_adjustment.py b/google/ads/googleads/v23/resources/types/bidding_seasonality_adjustment.py similarity index 90% rename from google/ads/googleads/v19/resources/types/bidding_seasonality_adjustment.py rename to google/ads/googleads/v23/resources/types/bidding_seasonality_adjustment.py index 9428c2aec..404fa3609 100644 --- a/google/ads/googleads/v19/resources/types/bidding_seasonality_adjustment.py +++ b/google/ads/googleads/v23/resources/types/bidding_seasonality_adjustment.py @@ -19,15 +19,15 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import advertising_channel_type -from google.ads.googleads.v19.enums.types import device -from google.ads.googleads.v19.enums.types import seasonality_event_scope -from google.ads.googleads.v19.enums.types import seasonality_event_status +from google.ads.googleads.v23.enums.types import advertising_channel_type +from google.ads.googleads.v23.enums.types import device +from google.ads.googleads.v23.enums.types import seasonality_event_scope +from google.ads.googleads.v23.enums.types import seasonality_event_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "BiddingSeasonalityAdjustment", }, @@ -50,9 +50,9 @@ class BiddingSeasonalityAdjustment(proto.Message): seasonality_adjustment_id (int): Output only. The ID of the seasonality adjustment. - scope (google.ads.googleads.v19.enums.types.SeasonalityEventScopeEnum.SeasonalityEventScope): + scope (google.ads.googleads.v23.enums.types.SeasonalityEventScopeEnum.SeasonalityEventScope): The scope of the seasonality adjustment. - status (google.ads.googleads.v19.enums.types.SeasonalityEventStatusEnum.SeasonalityEventStatus): + status (google.ads.googleads.v23.enums.types.SeasonalityEventStatusEnum.SeasonalityEventStatus): Output only. The status of the seasonality adjustment. start_date_time (str): @@ -76,7 +76,7 @@ class BiddingSeasonalityAdjustment(proto.Message): The description of the seasonality adjustment. The description can be at most 2048 characters. - devices (MutableSequence[google.ads.googleads.v19.enums.types.DeviceEnum.Device]): + devices (MutableSequence[google.ads.googleads.v23.enums.types.DeviceEnum.Device]): If not specified, all devices will be included in this adjustment. Otherwise, only the specified targeted devices will be included in @@ -93,7 +93,7 @@ class BiddingSeasonalityAdjustment(proto.Message): maximum number of campaigns per event is 2000. Note: a seasonality adjustment with both advertising_channel_types and campaign_ids is not supported. - advertising_channel_types (MutableSequence[google.ads.googleads.v19.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType]): + advertising_channel_types (MutableSequence[google.ads.googleads.v23.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType]): The seasonality adjustment will apply to all the campaigns under the listed channels retroactively as well as going forward when the scope of this adjustment is CHANNEL. The diff --git a/google/ads/googleads/v19/resources/types/bidding_strategy.py b/google/ads/googleads/v23/resources/types/bidding_strategy.py similarity index 90% rename from google/ads/googleads/v19/resources/types/bidding_strategy.py rename to google/ads/googleads/v23/resources/types/bidding_strategy.py index c2bc02de3..8feb82852 100644 --- a/google/ads/googleads/v19/resources/types/bidding_strategy.py +++ b/google/ads/googleads/v23/resources/types/bidding_strategy.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import bidding -from google.ads.googleads.v19.enums.types import bidding_strategy_status -from google.ads.googleads.v19.enums.types import bidding_strategy_type +from google.ads.googleads.v23.common.types import bidding +from google.ads.googleads.v23.enums.types import bidding_strategy_status +from google.ads.googleads.v23.enums.types import bidding_strategy_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "BiddingStrategy", }, @@ -61,11 +61,11 @@ class BiddingStrategy(proto.Message): and 255, inclusive, in UTF-8 bytes, (trimmed). This field is a member of `oneof`_ ``_name``. - status (google.ads.googleads.v19.enums.types.BiddingStrategyStatusEnum.BiddingStrategyStatus): + status (google.ads.googleads.v23.enums.types.BiddingStrategyStatusEnum.BiddingStrategyStatus): Output only. The status of the bidding strategy. This field is read-only. - type_ (google.ads.googleads.v19.enums.types.BiddingStrategyTypeEnum.BiddingStrategyType): + type_ (google.ads.googleads.v23.enums.types.BiddingStrategyTypeEnum.BiddingStrategyType): Output only. The type of the bidding strategy. Create a bidding strategy by setting the bidding scheme. @@ -117,44 +117,44 @@ class BiddingStrategy(proto.Message): This field is read-only. This field is a member of `oneof`_ ``_non_removed_campaign_count``. - enhanced_cpc (google.ads.googleads.v19.common.types.EnhancedCpc): + enhanced_cpc (google.ads.googleads.v23.common.types.EnhancedCpc): A bidding strategy that raises bids for clicks that seem more likely to lead to a conversion and lowers them for clicks where they seem less likely. This field is a member of `oneof`_ ``scheme``. - maximize_conversion_value (google.ads.googleads.v19.common.types.MaximizeConversionValue): + maximize_conversion_value (google.ads.googleads.v23.common.types.MaximizeConversionValue): An automated bidding strategy to help get the most conversion value for your campaigns while spending your budget. This field is a member of `oneof`_ ``scheme``. - maximize_conversions (google.ads.googleads.v19.common.types.MaximizeConversions): + maximize_conversions (google.ads.googleads.v23.common.types.MaximizeConversions): An automated bidding strategy to help get the most conversions for your campaigns while spending your budget. This field is a member of `oneof`_ ``scheme``. - target_cpa (google.ads.googleads.v19.common.types.TargetCpa): + target_cpa (google.ads.googleads.v23.common.types.TargetCpa): A bidding strategy that sets bids to help get as many conversions as possible at the target cost-per-acquisition (CPA) you set. This field is a member of `oneof`_ ``scheme``. - target_impression_share (google.ads.googleads.v19.common.types.TargetImpressionShare): + target_impression_share (google.ads.googleads.v23.common.types.TargetImpressionShare): A bidding strategy that automatically optimizes towards a chosen percentage of impressions. This field is a member of `oneof`_ ``scheme``. - target_roas (google.ads.googleads.v19.common.types.TargetRoas): + target_roas (google.ads.googleads.v23.common.types.TargetRoas): A bidding strategy that helps you maximize revenue while averaging a specific target Return On Ad Spend (ROAS). This field is a member of `oneof`_ ``scheme``. - target_spend (google.ads.googleads.v19.common.types.TargetSpend): + target_spend (google.ads.googleads.v23.common.types.TargetSpend): A bid strategy that sets your bids to help get as many clicks as possible within your budget. diff --git a/google/ads/googleads/v19/resources/types/bidding_strategy_simulation.py b/google/ads/googleads/v23/resources/types/bidding_strategy_simulation.py similarity index 88% rename from google/ads/googleads/v19/resources/types/bidding_strategy_simulation.py rename to google/ads/googleads/v23/resources/types/bidding_strategy_simulation.py index 9aa7dfb9a..b4b196bb4 100644 --- a/google/ads/googleads/v19/resources/types/bidding_strategy_simulation.py +++ b/google/ads/googleads/v23/resources/types/bidding_strategy_simulation.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import simulation -from google.ads.googleads.v19.enums.types import simulation_modification_method -from google.ads.googleads.v19.enums.types import simulation_type +from google.ads.googleads.v23.common.types import simulation +from google.ads.googleads.v23.enums.types import simulation_modification_method +from google.ads.googleads.v23.enums.types import simulation_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "BiddingStrategySimulation", }, @@ -57,10 +57,10 @@ class BiddingStrategySimulation(proto.Message): bidding_strategy_id (int): Output only. Bidding strategy shared set id of the simulation. - type_ (google.ads.googleads.v19.enums.types.SimulationTypeEnum.SimulationType): + type_ (google.ads.googleads.v23.enums.types.SimulationTypeEnum.SimulationType): Output only. The field that the simulation modifies. - modification_method (google.ads.googleads.v19.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): + modification_method (google.ads.googleads.v23.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): Output only. How the simulation modifies the field. start_date (str): @@ -69,12 +69,12 @@ class BiddingStrategySimulation(proto.Message): end_date (str): Output only. Last day on which the simulation is based, in YYYY-MM-DD format - target_cpa_point_list (google.ads.googleads.v19.common.types.TargetCpaSimulationPointList): + target_cpa_point_list (google.ads.googleads.v23.common.types.TargetCpaSimulationPointList): Output only. Simulation points if the simulation type is TARGET_CPA. This field is a member of `oneof`_ ``point_list``. - target_roas_point_list (google.ads.googleads.v19.common.types.TargetRoasSimulationPointList): + target_roas_point_list (google.ads.googleads.v23.common.types.TargetRoasSimulationPointList): Output only. Simulation points if the simulation type is TARGET_ROAS. diff --git a/google/ads/googleads/v19/resources/types/billing_setup.py b/google/ads/googleads/v23/resources/types/billing_setup.py similarity index 94% rename from google/ads/googleads/v19/resources/types/billing_setup.py rename to google/ads/googleads/v23/resources/types/billing_setup.py index 376451020..118609d3b 100644 --- a/google/ads/googleads/v19/resources/types/billing_setup.py +++ b/google/ads/googleads/v23/resources/types/billing_setup.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import billing_setup_status -from google.ads.googleads.v19.enums.types import time_type +from google.ads.googleads.v23.enums.types import billing_setup_status +from google.ads.googleads.v23.enums.types import time_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "BillingSetup", }, @@ -52,7 +52,7 @@ class BillingSetup(proto.Message): Output only. The ID of the billing setup. This field is a member of `oneof`_ ``_id``. - status (google.ads.googleads.v19.enums.types.BillingSetupStatusEnum.BillingSetupStatus): + status (google.ads.googleads.v23.enums.types.BillingSetupStatusEnum.BillingSetupStatus): Output only. The status of the billing setup. payments_account (str): Immutable. The resource name of the payments account @@ -66,7 +66,7 @@ class BillingSetup(proto.Message): payments_account_info will be populated. This field is a member of `oneof`_ ``_payments_account``. - payments_account_info (google.ads.googleads.v19.resources.types.BillingSetup.PaymentsAccountInfo): + payments_account_info (google.ads.googleads.v23.resources.types.BillingSetup.PaymentsAccountInfo): Immutable. The payments account information associated with this billing setup. When setting up billing, this is used to signup with a new payments account (and then @@ -78,7 +78,7 @@ class BillingSetup(proto.Message): time is allowed. This field is a member of `oneof`_ ``start_time``. - start_time_type (google.ads.googleads.v19.enums.types.TimeTypeEnum.TimeType): + start_time_type (google.ads.googleads.v23.enums.types.TimeTypeEnum.TimeType): Immutable. The start time as a type. Only NOW is allowed. @@ -88,7 +88,7 @@ class BillingSetup(proto.Message): or yyyy-MM-dd HH:mm:ss format. This field is a member of `oneof`_ ``end_time``. - end_time_type (google.ads.googleads.v19.enums.types.TimeTypeEnum.TimeType): + end_time_type (google.ads.googleads.v23.enums.types.TimeTypeEnum.TimeType): Output only. The end time as a type. The only possible value is FOREVER. diff --git a/google/ads/googleads/v19/resources/types/call_view.py b/google/ads/googleads/v23/resources/types/call_view.py similarity index 88% rename from google/ads/googleads/v19/resources/types/call_view.py rename to google/ads/googleads/v23/resources/types/call_view.py index 4cbbef1fa..cb3d70ab7 100644 --- a/google/ads/googleads/v19/resources/types/call_view.py +++ b/google/ads/googleads/v23/resources/types/call_view.py @@ -18,16 +18,16 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( call_tracking_display_location as gage_call_tracking_display_location, ) -from google.ads.googleads.v19.enums.types import call_type -from google.ads.googleads.v19.enums.types import google_voice_call_status +from google.ads.googleads.v23.enums.types import call_type +from google.ads.googleads.v23.enums.types import google_voice_call_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CallView", }, @@ -58,12 +58,12 @@ class CallView(proto.Message): end_call_date_time (str): Output only. The advertiser-provided call end date time. - call_tracking_display_location (google.ads.googleads.v19.enums.types.CallTrackingDisplayLocationEnum.CallTrackingDisplayLocation): + call_tracking_display_location (google.ads.googleads.v23.enums.types.CallTrackingDisplayLocationEnum.CallTrackingDisplayLocation): Output only. The call tracking display location. - type_ (google.ads.googleads.v19.enums.types.CallTypeEnum.CallType): + type_ (google.ads.googleads.v23.enums.types.CallTypeEnum.CallType): Output only. The type of the call. - call_status (google.ads.googleads.v19.enums.types.GoogleVoiceCallStatusEnum.GoogleVoiceCallStatus): + call_status (google.ads.googleads.v23.enums.types.GoogleVoiceCallStatusEnum.GoogleVoiceCallStatus): Output only. The status of the call. """ diff --git a/google/ads/googleads/v23/resources/types/campaign.py b/google/ads/googleads/v23/resources/types/campaign.py new file mode 100644 index 000000000..e1d43fd6d --- /dev/null +++ b/google/ads/googleads/v23/resources/types/campaign.py @@ -0,0 +1,1938 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import bidding +from google.ads.googleads.v23.common.types import custom_parameter +from google.ads.googleads.v23.common.types import frequency_cap +from google.ads.googleads.v23.common.types import ( + real_time_bidding_setting as gagc_real_time_bidding_setting, +) +from google.ads.googleads.v23.common.types import ( + targeting_setting as gagc_targeting_setting, +) +from google.ads.googleads.v23.common.types import ( + third_party_integration_partners as gagc_third_party_integration_partners, +) +from google.ads.googleads.v23.enums.types import ( + ad_group_type as gage_ad_group_type, +) +from google.ads.googleads.v23.enums.types import ( + ad_serving_optimization_status as gage_ad_serving_optimization_status, +) +from google.ads.googleads.v23.enums.types import ( + advertising_channel_sub_type as gage_advertising_channel_sub_type, +) +from google.ads.googleads.v23.enums.types import ( + advertising_channel_type as gage_advertising_channel_type, +) +from google.ads.googleads.v23.enums.types import app_campaign_app_store +from google.ads.googleads.v23.enums.types import ( + app_campaign_bidding_strategy_goal_type, +) +from google.ads.googleads.v23.enums.types import ( + asset_automation_status as gage_asset_automation_status, +) +from google.ads.googleads.v23.enums.types import ( + asset_automation_type as gage_asset_automation_type, +) +from google.ads.googleads.v23.enums.types import asset_field_type +from google.ads.googleads.v23.enums.types import asset_set_type +from google.ads.googleads.v23.enums.types import ( + bidding_strategy_system_status as gage_bidding_strategy_system_status, +) +from google.ads.googleads.v23.enums.types import ( + bidding_strategy_type as gage_bidding_strategy_type, +) +from google.ads.googleads.v23.enums.types import brand_safety_suitability +from google.ads.googleads.v23.enums.types import campaign_experiment_type +from google.ads.googleads.v23.enums.types import campaign_keyword_match_type +from google.ads.googleads.v23.enums.types import campaign_primary_status +from google.ads.googleads.v23.enums.types import campaign_primary_status_reason +from google.ads.googleads.v23.enums.types import campaign_serving_status +from google.ads.googleads.v23.enums.types import campaign_status +from google.ads.googleads.v23.enums.types import eu_political_advertising_status +from google.ads.googleads.v23.enums.types import ( + listing_type as gage_listing_type, +) +from google.ads.googleads.v23.enums.types import ( + location_source_type as gage_location_source_type, +) +from google.ads.googleads.v23.enums.types import ( + negative_geo_target_type as gage_negative_geo_target_type, +) +from google.ads.googleads.v23.enums.types import non_skippable_max_duration +from google.ads.googleads.v23.enums.types import non_skippable_min_duration +from google.ads.googleads.v23.enums.types import optimization_goal_type +from google.ads.googleads.v23.enums.types import ( + payment_mode as gage_payment_mode, +) +from google.ads.googleads.v23.enums.types import performance_max_upgrade_status +from google.ads.googleads.v23.enums.types import ( + positive_geo_target_type as gage_positive_geo_target_type, +) +from google.ads.googleads.v23.enums.types import ( + vanity_pharma_display_url_mode as gage_vanity_pharma_display_url_mode, +) +from google.ads.googleads.v23.enums.types import ( + vanity_pharma_text as gage_vanity_pharma_text, +) +from google.ads.googleads.v23.enums.types import video_ad_format_restriction +from google.ads.googleads.v23.enums.types import ( + video_ad_sequence_interaction_type, +) +from google.ads.googleads.v23.enums.types import ( + video_ad_sequence_minimum_duration, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "Campaign", + }, +) + + +class Campaign(proto.Message): + r"""A campaign. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign. Campaign + resource names have the form: + + ``customers/{customer_id}/campaigns/{campaign_id}`` + id (int): + Output only. The ID of the campaign. + + This field is a member of `oneof`_ ``_id``. + name (str): + The name of the campaign. + + This field is required and should not be empty + when creating new campaigns. + + It must not contain any null (code point 0x0), + NL line feed (code point 0xA) or carriage return + (code point 0xD) characters. + + This field is a member of `oneof`_ ``_name``. + primary_status (google.ads.googleads.v23.enums.types.CampaignPrimaryStatusEnum.CampaignPrimaryStatus): + Output only. The primary status of the + campaign. + Provides insight into why a campaign is not + serving or not serving optimally. Modification + to the campaign and its related entities might + take a while to be reflected in this status. + primary_status_reasons (MutableSequence[google.ads.googleads.v23.enums.types.CampaignPrimaryStatusReasonEnum.CampaignPrimaryStatusReason]): + Output only. The primary status reasons of + the campaign. + Provides insight into why a campaign is not + serving or not serving optimally. These reasons + are aggregated to determine an overall + CampaignPrimaryStatus. + status (google.ads.googleads.v23.enums.types.CampaignStatusEnum.CampaignStatus): + The status of the campaign. + + When a new campaign is added, the status + defaults to ENABLED. + serving_status (google.ads.googleads.v23.enums.types.CampaignServingStatusEnum.CampaignServingStatus): + Output only. The ad serving status of the + campaign. + bidding_strategy_system_status (google.ads.googleads.v23.enums.types.BiddingStrategySystemStatusEnum.BiddingStrategySystemStatus): + Output only. The system status of the + campaign's bidding strategy. + ad_serving_optimization_status (google.ads.googleads.v23.enums.types.AdServingOptimizationStatusEnum.AdServingOptimizationStatus): + The ad serving optimization status of the + campaign. + advertising_channel_type (google.ads.googleads.v23.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): + Immutable. The primary serving target for ads within the + campaign. The targeting options can be refined in + ``network_settings``. + + This field is required and should not be empty when creating + new campaigns. + + Can be set only when creating campaigns. After the campaign + is created, the field can not be changed. + advertising_channel_sub_type (google.ads.googleads.v23.enums.types.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType): + Immutable. Optional refinement to + ``advertising_channel_type``. Must be a valid sub-type of + the parent channel type. + + Can be set only when creating campaigns. After campaign is + created, the field can not be changed. + tracking_url_template (str): + The URL template for constructing a tracking + URL. + + This field is a member of `oneof`_ ``_tracking_url_template``. + url_custom_parameters (MutableSequence[google.ads.googleads.v23.common.types.CustomParameter]): + The list of mappings used to substitute custom parameter + tags in a ``tracking_url_template``, ``final_urls``, or + ``mobile_final_urls``. + local_services_campaign_settings (google.ads.googleads.v23.resources.types.Campaign.LocalServicesCampaignSettings): + The Local Services Campaign related settings. + travel_campaign_settings (google.ads.googleads.v23.resources.types.Campaign.TravelCampaignSettings): + Settings for Travel campaign. + demand_gen_campaign_settings (google.ads.googleads.v23.resources.types.Campaign.DemandGenCampaignSettings): + Settings for Demand Gen campaign. + video_campaign_settings (google.ads.googleads.v23.resources.types.Campaign.VideoCampaignSettings): + Settings for Video campaign. + pmax_campaign_settings (google.ads.googleads.v23.resources.types.Campaign.PmaxCampaignSettings): + Settings for Performance Max campaign. + real_time_bidding_setting (google.ads.googleads.v23.common.types.RealTimeBiddingSetting): + Settings for Real-Time Bidding, a feature + only available for campaigns targeting the Ad + Exchange network. + network_settings (google.ads.googleads.v23.resources.types.Campaign.NetworkSettings): + The network settings for the campaign. + hotel_setting (google.ads.googleads.v23.resources.types.Campaign.HotelSettingInfo): + Immutable. The hotel setting for the + campaign. + dynamic_search_ads_setting (google.ads.googleads.v23.resources.types.Campaign.DynamicSearchAdsSetting): + The setting for controlling Dynamic Search + Ads (DSA). + shopping_setting (google.ads.googleads.v23.resources.types.Campaign.ShoppingSetting): + The setting for controlling Shopping + campaigns. + targeting_setting (google.ads.googleads.v23.common.types.TargetingSetting): + Setting for targeting related features. + audience_setting (google.ads.googleads.v23.resources.types.Campaign.AudienceSetting): + Immutable. Setting for audience related + features. + + This field is a member of `oneof`_ ``_audience_setting``. + geo_target_type_setting (google.ads.googleads.v23.resources.types.Campaign.GeoTargetTypeSetting): + The setting for ads geotargeting. + local_campaign_setting (google.ads.googleads.v23.resources.types.Campaign.LocalCampaignSetting): + The setting for local campaign. + app_campaign_setting (google.ads.googleads.v23.resources.types.Campaign.AppCampaignSetting): + The setting related to App Campaign. + labels (MutableSequence[str]): + Output only. The resource names of labels + attached to this campaign. + experiment_type (google.ads.googleads.v23.enums.types.CampaignExperimentTypeEnum.CampaignExperimentType): + Output only. The type of campaign: normal, + draft, or experiment. + base_campaign (str): + Output only. The resource name of the base campaign of a + draft or experiment campaign. For base campaigns, this is + equal to ``resource_name``. + + This field is read-only. + + This field is a member of `oneof`_ ``_base_campaign``. + campaign_budget (str): + The resource name of the campaign budget of + the campaign. + + This field is a member of `oneof`_ ``_campaign_budget``. + bidding_strategy_type (google.ads.googleads.v23.enums.types.BiddingStrategyTypeEnum.BiddingStrategyType): + Output only. The type of bidding strategy. + + A bidding strategy can be created by setting either the + bidding scheme to create a standard bidding strategy or the + ``bidding_strategy`` field to create a portfolio bidding + strategy. + + This field is read-only. + accessible_bidding_strategy (str): + Output only. Resource name of AccessibleBiddingStrategy, a + read-only view of the unrestricted attributes of the + attached portfolio bidding strategy identified by + 'bidding_strategy'. Empty, if the campaign does not use a + portfolio strategy. Unrestricted strategy attributes are + available to all customers with whom the strategy is shared + and are read from the AccessibleBiddingStrategy resource. In + contrast, restricted attributes are only available to the + owner customer of the strategy and their managers. + Restricted attributes can only be read from the + BiddingStrategy resource. + campaign_group (str): + The resource name of the campaign group that + this campaign belongs to. + + This field is a member of `oneof`_ ``_campaign_group``. + start_date_time (str): + The date and time when campaign started in + serving. The timestamp is in the customer's time + zone and in "yyyy-MM-dd HH:mm:ss" format. Set + the time component to 00:00:00 for daily + granularity, time granularity is only supported + for some campaign types. + + This field is a member of `oneof`_ ``_start_date_time``. + end_date_time (str): + The last day and time of the campaign in + serving customer's timezone in "yyyy-MM-dd + HH:mm:ss" format. Set the time component to + 23:59:59 for daily granularity, time granularity + is only supported for some campaign types. On + create, defaults to running indefinitely. To set + an existing campaign to run indefinitely, clear + this field. + + This field is a member of `oneof`_ ``_end_date_time``. + final_url_suffix (str): + Suffix used to append query parameters to + landing pages that are served with parallel + tracking. + + This field is a member of `oneof`_ ``_final_url_suffix``. + frequency_caps (MutableSequence[google.ads.googleads.v23.common.types.FrequencyCapEntry]): + A list that limits how often each user will + see this campaign's ads. + video_brand_safety_suitability (google.ads.googleads.v23.enums.types.BrandSafetySuitabilityEnum.BrandSafetySuitability): + Brand Safety setting at the individual + campaign level. Allows for selecting an + inventory type to show your ads on content that + is the right fit for your brand. See + https://support.google.com/google-ads/answer/7515513. + vanity_pharma (google.ads.googleads.v23.resources.types.Campaign.VanityPharma): + Describes how unbranded pharma ads will be + displayed. + selective_optimization (google.ads.googleads.v23.resources.types.Campaign.SelectiveOptimization): + Selective optimization setting for this campaign, which + includes a set of conversion actions to optimize this + campaign towards. This feature only applies to app campaigns + that use MULTI_CHANNEL as AdvertisingChannelType and + APP_CAMPAIGN or APP_CAMPAIGN_FOR_ENGAGEMENT as + AdvertisingChannelSubType. + optimization_goal_setting (google.ads.googleads.v23.resources.types.Campaign.OptimizationGoalSetting): + Optimization goal setting for this campaign, + which includes a set of optimization goal types. + tracking_setting (google.ads.googleads.v23.resources.types.Campaign.TrackingSetting): + Output only. Campaign-level settings for + tracking information. + payment_mode (google.ads.googleads.v23.enums.types.PaymentModeEnum.PaymentMode): + Payment mode for the campaign. + optimization_score (float): + Output only. Optimization score of the + campaign. + Optimization score is an estimate of how well a + campaign is set to perform. It ranges from 0% + (0.0) to 100% (1.0), with 100% indicating that + the campaign is performing at full potential. + This field is null for unscored campaigns. + + See "About optimization score" at + https://support.google.com/google-ads/answer/9061546. + + This field is read-only. + + This field is a member of `oneof`_ ``_optimization_score``. + excluded_parent_asset_field_types (MutableSequence[google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType]): + The asset field types that should be excluded + from this campaign. Asset links with these field + types will not be inherited by this campaign + from the upper level. + excluded_parent_asset_set_types (MutableSequence[google.ads.googleads.v23.enums.types.AssetSetTypeEnum.AssetSetType]): + The asset set types that should be excluded from this + campaign. Asset set links with these types will not be + inherited by this campaign from the upper level. Location + group types (GMB_DYNAMIC_LOCATION_GROUP, + CHAIN_DYNAMIC_LOCATION_GROUP, and STATIC_LOCATION_GROUP) are + child types of LOCATION_SYNC. Therefore, if LOCATION_SYNC is + set for this field, all location group asset sets are not + allowed to be linked to this campaign, and all Location + Extension (LE) and Affiliate Location Extensions (ALE) will + not be served under this campaign. Only LOCATION_SYNC is + currently supported. + performance_max_upgrade (google.ads.googleads.v23.resources.types.Campaign.PerformanceMaxUpgrade): + Output only. Information about campaigns + being upgraded to Performance Max. + hotel_property_asset_set (str): + Immutable. The resource name for a set of + hotel properties for Performance Max for travel + goals campaigns. + + This field is a member of `oneof`_ ``_hotel_property_asset_set``. + listing_type (google.ads.googleads.v23.enums.types.ListingTypeEnum.ListingType): + Immutable. Listing type of ads served for + this campaign. Field is restricted for usage + with Performance Max campaigns. + + This field is a member of `oneof`_ ``_listing_type``. + asset_automation_settings (MutableSequence[google.ads.googleads.v23.resources.types.Campaign.AssetAutomationSetting]): + Contains the opt-in/out status of each + AssetAutomationType. See documentation of each + asset automation type enum for default opt + in/out behavior. + keyword_match_type (google.ads.googleads.v23.enums.types.CampaignKeywordMatchTypeEnum.CampaignKeywordMatchType): + Keyword match type of Campaign. Set to BROAD + to set broad matching for all keywords in a + campaign. + brand_guidelines_enabled (bool): + Immutable. Whether Brand Guidelines are + enabled for this Campaign. Only applicable to + Performance Max campaigns. If enabled, business + name and logo assets must be linked as + CampaignAssets instead of AssetGroupAssets. + + Writable only at campaign creation. Set to true + to enable Brand Guidelines when creating a new + Performance Max campaign. + + Immutable after creation. This field cannot be + modified using standard update operations after + the campaign has been created. + + For existing campaigns: To enable Brand + Guidelines on a campaign after it has been + created, use the + CampaignService.EnablePMaxBrandGuidelines + method, which is a separate operation. It is not + possible to disable Brand Guidelines for an + existing campaign. + + Incompatible with Travel Goals: This feature is + not supported for Performance Max campaigns with + Travel Goals. Attempting to set this field to + true for a Travel Goals campaign will result in + an error. + + This field is a member of `oneof`_ ``_brand_guidelines_enabled``. + brand_guidelines (google.ads.googleads.v23.resources.types.Campaign.BrandGuidelines): + These settings control how your brand appears + in automatically generated assets and formats + within this campaign. Note: These settings can + only be used for Performance Max campaigns that + have Brand Guidelines enabled. + third_party_integration_partners (google.ads.googleads.v23.common.types.CampaignThirdPartyIntegrationPartners): + Third-Party integration partners. + ai_max_setting (google.ads.googleads.v23.resources.types.Campaign.AiMaxSetting): + Settings for AI Max in search campaigns. + contains_eu_political_advertising (google.ads.googleads.v23.enums.types.EuPoliticalAdvertisingStatusEnum.EuPoliticalAdvertisingStatus): + The advertiser should self-declare whether + this campaign contains political advertising + content targeted towards the European Union. + feed_types (MutableSequence[google.ads.googleads.v23.enums.types.AssetSetTypeEnum.AssetSetType]): + Output only. Types of feeds that are attached + directly to this campaign. + bidding_strategy (str): + The resource name of the portfolio bidding + strategy used by the campaign. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + commission (google.ads.googleads.v23.common.types.Commission): + Commission is an automatic bidding strategy + in which the advertiser pays a certain portion + of the conversion value. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + manual_cpa (google.ads.googleads.v23.common.types.ManualCpa): + Standard Manual CPA bidding strategy. + Manual bidding strategy that allows advertiser + to set the bid per advertiser-specified action. + Supported only for Local Services campaigns. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + manual_cpc (google.ads.googleads.v23.common.types.ManualCpc): + Standard Manual CPC bidding strategy. + Manual click-based bidding where user pays per + click. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + manual_cpm (google.ads.googleads.v23.common.types.ManualCpm): + Standard Manual CPM bidding strategy. + Manual impression-based bidding where user pays + per thousand impressions. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + manual_cpv (google.ads.googleads.v23.common.types.ManualCpv): + A bidding strategy that pays a configurable + amount per video view. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + maximize_conversions (google.ads.googleads.v23.common.types.MaximizeConversions): + Standard Maximize Conversions bidding + strategy that automatically maximizes number of + conversions while spending your budget. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + maximize_conversion_value (google.ads.googleads.v23.common.types.MaximizeConversionValue): + Standard Maximize Conversion Value bidding + strategy that automatically sets bids to + maximize revenue while spending your budget. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_cpa (google.ads.googleads.v23.common.types.TargetCpa): + Standard Target CPA bidding strategy that + automatically sets bids to help get as many + conversions as possible at the target + cost-per-acquisition (CPA) you set. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_impression_share (google.ads.googleads.v23.common.types.TargetImpressionShare): + Target Impression Share bidding strategy. An + automated bidding strategy that sets bids to + achieve a chosen percentage of impressions. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_roas (google.ads.googleads.v23.common.types.TargetRoas): + Standard Target ROAS bidding strategy that + automatically maximizes revenue while averaging + a specific target return on ad spend (ROAS). + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_spend (google.ads.googleads.v23.common.types.TargetSpend): + Standard Target Spend bidding strategy that + automatically sets your bids to help get as many + clicks as possible within your budget. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + percent_cpc (google.ads.googleads.v23.common.types.PercentCpc): + Standard Percent Cpc bidding strategy where + bids are a fraction of the advertised price for + some good or service. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_cpm (google.ads.googleads.v23.common.types.TargetCpm): + A bidding strategy that automatically + optimizes cost per thousand impressions. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + fixed_cpm (google.ads.googleads.v23.common.types.FixedCpm): + A manual bidding strategy with a fixed CPM. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_cpv (google.ads.googleads.v23.common.types.TargetCpv): + An automated bidding strategy that sets bids + to optimize performance given the target CPV you + set. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + target_cpc (google.ads.googleads.v23.common.types.TargetCpc): + An automated bidding strategy that sets bids + to help get as many clicks as possible at the + target cost-per-click (CPC) you set. + + This field is a member of `oneof`_ ``campaign_bidding_strategy``. + """ + + class PerformanceMaxUpgrade(proto.Message): + r"""Information about a campaign being upgraded to Performance + Max. + + Attributes: + performance_max_campaign (str): + Output only. The resource name of the + Performance Max campaign the campaign is + upgraded to. + pre_upgrade_campaign (str): + Output only. The resource name of the legacy + campaign upgraded to Performance Max. + status (google.ads.googleads.v23.enums.types.PerformanceMaxUpgradeStatusEnum.PerformanceMaxUpgradeStatus): + Output only. The upgrade status of a campaign + requested to be upgraded to Performance Max. + """ + + performance_max_campaign: str = proto.Field( + proto.STRING, + number=1, + ) + pre_upgrade_campaign: str = proto.Field( + proto.STRING, + number=2, + ) + status: ( + performance_max_upgrade_status.PerformanceMaxUpgradeStatusEnum.PerformanceMaxUpgradeStatus + ) = proto.Field( + proto.ENUM, + number=3, + enum=performance_max_upgrade_status.PerformanceMaxUpgradeStatusEnum.PerformanceMaxUpgradeStatus, + ) + + class NetworkSettings(proto.Message): + r"""The network settings for the campaign. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + target_google_search (bool): + Whether ads will be served with google.com + search results. + + This field is a member of `oneof`_ ``_target_google_search``. + target_search_network (bool): + Whether ads will be served on partner sites in the Google + Search Network (requires ``target_google_search`` to also be + ``true``). + + This field is a member of `oneof`_ ``_target_search_network``. + target_content_network (bool): + Whether ads will be served on specified + placements in the Google Display Network. + Placements are specified using the Placement + criterion. + + This field is a member of `oneof`_ ``_target_content_network``. + target_partner_search_network (bool): + Whether ads will be served on the Google + Partner Network. This is available only to some + select Google partner accounts. + + This field is a member of `oneof`_ ``_target_partner_search_network``. + target_youtube (bool): + Whether ads will be served on YouTube. + + This field is a member of `oneof`_ ``_target_youtube``. + target_google_tv_network (bool): + Whether ads will be served on the Google TV + network. + + This field is a member of `oneof`_ ``_target_google_tv_network``. + """ + + target_google_search: bool = proto.Field( + proto.BOOL, + number=5, + optional=True, + ) + target_search_network: bool = proto.Field( + proto.BOOL, + number=6, + optional=True, + ) + target_content_network: bool = proto.Field( + proto.BOOL, + number=7, + optional=True, + ) + target_partner_search_network: bool = proto.Field( + proto.BOOL, + number=8, + optional=True, + ) + target_youtube: bool = proto.Field( + proto.BOOL, + number=9, + optional=True, + ) + target_google_tv_network: bool = proto.Field( + proto.BOOL, + number=10, + optional=True, + ) + + class HotelSettingInfo(proto.Message): + r"""Campaign-level settings for hotel ads. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + hotel_center_id (int): + Immutable. The linked Hotel Center account. + + This field is a member of `oneof`_ ``_hotel_center_id``. + """ + + hotel_center_id: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + + class DynamicSearchAdsSetting(proto.Message): + r"""The setting for controlling Dynamic Search Ads (DSA). + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + domain_name (str): + Required. The Internet domain name that this + setting represents, for example, "google.com" or + "www.google.com". + language_code (str): + Required. The language code specifying the + language of the domain, for example, "en". + use_supplied_urls_only (bool): + Whether the campaign uses advertiser supplied + URLs exclusively. + + This field is a member of `oneof`_ ``_use_supplied_urls_only``. + """ + + domain_name: str = proto.Field( + proto.STRING, + number=6, + ) + language_code: str = proto.Field( + proto.STRING, + number=7, + ) + use_supplied_urls_only: bool = proto.Field( + proto.BOOL, + number=8, + optional=True, + ) + + class ShoppingSetting(proto.Message): + r"""The setting for Shopping campaigns. Defines the universe of + products that can be advertised by the campaign, and how this + campaign interacts with other Shopping campaigns. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + merchant_id (int): + ID of the Merchant Center account. + This field is required for create operations. + This field is immutable for Shopping campaigns. + + This field is a member of `oneof`_ ``_merchant_id``. + feed_label (str): + Feed label of products to include in the campaign. Valid + feed labels may contain a maximum of 20 characters including + uppercase letters, numbers, hyphens, and underscores. If you + previously used the deprecated ``sales_country`` in the + two-letter country code (``XX``) format, the ``feed_label`` + field should be used instead. For more information see the + `feed + label `__ + support article. + campaign_priority (int): + Priority of the campaign. Campaigns with + numerically higher priorities take precedence + over those with lower priorities. This field is + required for Shopping campaigns, with values + between 0 and 2, inclusive. + This field is optional for Smart Shopping + campaigns, but must be equal to 3 if set. + + This field is a member of `oneof`_ ``_campaign_priority``. + enable_local (bool): + Whether to include local products. + + This field is a member of `oneof`_ ``_enable_local``. + use_vehicle_inventory (bool): + Immutable. Whether to target Vehicle Listing inventory. This + field is supported only in Smart Shopping Campaigns. For + setting Vehicle Listing inventory in Performance Max + campaigns, use ``listing_type`` instead. + advertising_partner_ids (MutableSequence[int]): + The list of Google Ads accounts IDs of + advertising partners cooperating within the + campaign. This feature is currently available + only for accounts having an advertising partner + link. Once set, the field is immutable. This + feature is currently supported only for + Performance Max, Shopping, Search and Demand Gen + campaign types. + disable_product_feed (bool): + Disable the optional product feed. This field + is currently supported only for Demand Gen + campaigns. See + https://support.google.com/google-ads/answer/13721750 + to learn more about this feature. + + This field is a member of `oneof`_ ``_disable_product_feed``. + """ + + merchant_id: int = proto.Field( + proto.INT64, + number=5, + optional=True, + ) + feed_label: str = proto.Field( + proto.STRING, + number=10, + ) + campaign_priority: int = proto.Field( + proto.INT32, + number=7, + optional=True, + ) + enable_local: bool = proto.Field( + proto.BOOL, + number=8, + optional=True, + ) + use_vehicle_inventory: bool = proto.Field( + proto.BOOL, + number=9, + ) + advertising_partner_ids: MutableSequence[int] = proto.RepeatedField( + proto.INT64, + number=11, + ) + disable_product_feed: bool = proto.Field( + proto.BOOL, + number=12, + optional=True, + ) + + class TrackingSetting(proto.Message): + r"""Campaign-level settings for tracking information. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + tracking_url (str): + Output only. The url used for dynamic + tracking. + + This field is a member of `oneof`_ ``_tracking_url``. + """ + + tracking_url: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + class GeoTargetTypeSetting(proto.Message): + r"""Represents a collection of settings related to ads + geotargeting. + + Attributes: + positive_geo_target_type (google.ads.googleads.v23.enums.types.PositiveGeoTargetTypeEnum.PositiveGeoTargetType): + The setting used for positive geotargeting in + this particular campaign. + negative_geo_target_type (google.ads.googleads.v23.enums.types.NegativeGeoTargetTypeEnum.NegativeGeoTargetType): + The setting used for negative geotargeting in + this particular campaign. + """ + + positive_geo_target_type: ( + gage_positive_geo_target_type.PositiveGeoTargetTypeEnum.PositiveGeoTargetType + ) = proto.Field( + proto.ENUM, + number=1, + enum=gage_positive_geo_target_type.PositiveGeoTargetTypeEnum.PositiveGeoTargetType, + ) + negative_geo_target_type: ( + gage_negative_geo_target_type.NegativeGeoTargetTypeEnum.NegativeGeoTargetType + ) = proto.Field( + proto.ENUM, + number=2, + enum=gage_negative_geo_target_type.NegativeGeoTargetTypeEnum.NegativeGeoTargetType, + ) + + class LocalCampaignSetting(proto.Message): + r"""Campaign setting for local campaigns. + + Attributes: + location_source_type (google.ads.googleads.v23.enums.types.LocationSourceTypeEnum.LocationSourceType): + The location source type for this local + campaign. + """ + + location_source_type: ( + gage_location_source_type.LocationSourceTypeEnum.LocationSourceType + ) = proto.Field( + proto.ENUM, + number=1, + enum=gage_location_source_type.LocationSourceTypeEnum.LocationSourceType, + ) + + class AppCampaignSetting(proto.Message): + r"""Campaign-level settings for App Campaigns. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + bidding_strategy_goal_type (google.ads.googleads.v23.enums.types.AppCampaignBiddingStrategyGoalTypeEnum.AppCampaignBiddingStrategyGoalType): + Represents the goal which the bidding + strategy of this app campaign should optimize + towards. + app_id (str): + Immutable. A string that uniquely identifies + a mobile application. + + This field is a member of `oneof`_ ``_app_id``. + app_store (google.ads.googleads.v23.enums.types.AppCampaignAppStoreEnum.AppCampaignAppStore): + Immutable. The application store that + distributes this specific app. + """ + + bidding_strategy_goal_type: ( + app_campaign_bidding_strategy_goal_type.AppCampaignBiddingStrategyGoalTypeEnum.AppCampaignBiddingStrategyGoalType + ) = proto.Field( + proto.ENUM, + number=1, + enum=app_campaign_bidding_strategy_goal_type.AppCampaignBiddingStrategyGoalTypeEnum.AppCampaignBiddingStrategyGoalType, + ) + app_id: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + app_store: ( + app_campaign_app_store.AppCampaignAppStoreEnum.AppCampaignAppStore + ) = proto.Field( + proto.ENUM, + number=3, + enum=app_campaign_app_store.AppCampaignAppStoreEnum.AppCampaignAppStore, + ) + + class VanityPharma(proto.Message): + r"""Describes how unbranded pharma ads will be displayed. + + Attributes: + vanity_pharma_display_url_mode (google.ads.googleads.v23.enums.types.VanityPharmaDisplayUrlModeEnum.VanityPharmaDisplayUrlMode): + The display mode for vanity pharma URLs. + vanity_pharma_text (google.ads.googleads.v23.enums.types.VanityPharmaTextEnum.VanityPharmaText): + The text that will be displayed in display + URL of the text ad when website description is + the selected display mode for vanity pharma + URLs. + """ + + vanity_pharma_display_url_mode: ( + gage_vanity_pharma_display_url_mode.VanityPharmaDisplayUrlModeEnum.VanityPharmaDisplayUrlMode + ) = proto.Field( + proto.ENUM, + number=1, + enum=gage_vanity_pharma_display_url_mode.VanityPharmaDisplayUrlModeEnum.VanityPharmaDisplayUrlMode, + ) + vanity_pharma_text: ( + gage_vanity_pharma_text.VanityPharmaTextEnum.VanityPharmaText + ) = proto.Field( + proto.ENUM, + number=2, + enum=gage_vanity_pharma_text.VanityPharmaTextEnum.VanityPharmaText, + ) + + class SelectiveOptimization(proto.Message): + r"""Selective optimization setting for this campaign, which includes a + set of conversion actions to optimize this campaign towards. This + feature only applies to app campaigns that use MULTI_CHANNEL as + AdvertisingChannelType and APP_CAMPAIGN or + APP_CAMPAIGN_FOR_ENGAGEMENT as AdvertisingChannelSubType. + + Attributes: + conversion_actions (MutableSequence[str]): + The selected set of resource names for + conversion actions for optimizing this campaign. + """ + + conversion_actions: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + class OptimizationGoalSetting(proto.Message): + r"""Optimization goal setting for this campaign, which includes a + set of optimization goal types. + + Attributes: + optimization_goal_types (MutableSequence[google.ads.googleads.v23.enums.types.OptimizationGoalTypeEnum.OptimizationGoalType]): + The list of optimization goal types. + """ + + optimization_goal_types: MutableSequence[ + optimization_goal_type.OptimizationGoalTypeEnum.OptimizationGoalType + ] = proto.RepeatedField( + proto.ENUM, + number=1, + enum=optimization_goal_type.OptimizationGoalTypeEnum.OptimizationGoalType, + ) + + class AudienceSetting(proto.Message): + r"""Settings for the audience targeting. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + use_audience_grouped (bool): + Immutable. If true, this campaign uses an + Audience resource for audience targeting. If + false, this campaign may use audience segment + criteria instead. + + This field is a member of `oneof`_ ``_use_audience_grouped``. + """ + + use_audience_grouped: bool = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + + class LocalServicesCampaignSettings(proto.Message): + r"""Settings for LocalServicesCampaign subresource. + + Attributes: + category_bids (MutableSequence[google.ads.googleads.v23.resources.types.Campaign.CategoryBid]): + Categorical level bids associated with MANUAL_CPA bidding + strategy. + """ + + category_bids: MutableSequence["Campaign.CategoryBid"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Campaign.CategoryBid", + ) + ) + + class CategoryBid(proto.Message): + r"""Category bids in LocalServicesReportingCampaignSettings. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + category_id (str): + Category for which the bid will be associated with. For + example, xcat:service_area_business_plumber. + + This field is a member of `oneof`_ ``_category_id``. + manual_cpa_bid_micros (int): + Manual CPA bid for the category. Bid must be + greater than the reserve price associated for + that category. Value is in micros and in the + advertiser's currency. + + This field is a member of `oneof`_ ``_manual_cpa_bid_micros``. + target_cpa_bid_micros (int): + Target CPA bid for the category. Value is in + micros and in the advertiser's currency. + + This field is a member of `oneof`_ ``_target_cpa_bid_micros``. + """ + + category_id: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + manual_cpa_bid_micros: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + target_cpa_bid_micros: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + + class TravelCampaignSettings(proto.Message): + r"""Settings for Travel campaign. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + travel_account_id (int): + Immutable. The Travel account ID associated + with the Travel campaign. + + This field is a member of `oneof`_ ``_travel_account_id``. + """ + + travel_account_id: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + + class DemandGenCampaignSettings(proto.Message): + r"""Settings for Demand Gen campaign. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + upgraded_targeting (bool): + Immutable. Specifies whether this campaign uses upgraded + targeting options. When this field is set to ``true``, you + can use location and language targeting at the ad group + level as opposed to the standard campaign-level targeting. + This field defaults to ``true``, and can only be set when + creating a campaign. + + This field is a member of `oneof`_ ``_upgraded_targeting``. + """ + + upgraded_targeting: bool = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + + class VideoCampaignSettings(proto.Message): + r"""Settings for Video campaign. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + video_ad_sequence (google.ads.googleads.v23.resources.types.Campaign.VideoCampaignSettings.VideoAdSequence): + Container for video ads sequencing + definition. + video_ad_inventory_control (google.ads.googleads.v23.resources.types.Campaign.VideoCampaignSettings.VideoAdInventoryControl): + Inventory control for video responsive ads in + reach campaigns. + + This field is a member of `oneof`_ ``fluidity_control``. + video_ad_format_control (google.ads.googleads.v23.resources.types.Campaign.VideoCampaignSettings.VideoAdFormatControl): + Format-restricting control enabling usage of + video responsive ads in format defined Video + campaigns (for example, non-skippable). + + This field is a member of `oneof`_ ``fluidity_control``. + """ + + class VideoAdInventoryControl(proto.Message): + r"""For campaigns using video responsive ads inventory controls + determine on which inventories the ads can be shown. This only + applies for campaigns with the bidding strategies TARGET_CPM and + FIXED_CPM. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + allow_in_stream (bool): + Determine if video responsive ads can be used + for in-stream video ads. + + This field is a member of `oneof`_ ``_allow_in_stream``. + allow_in_feed (bool): + Determine if video responsive ads can be used + for in-feed video ads. + + This field is a member of `oneof`_ ``_allow_in_feed``. + allow_shorts (bool): + Determine if video responsive ads can be used + as shorts format. + + This field is a member of `oneof`_ ``_allow_shorts``. + allow_non_skippable_in_stream (bool): + Determine if video responsive ads can be used + for non-skippable in-stream ads. This is only + available for campaigns that allow mixing of + non-skippable with other formats (Video reach + campaign with Target Frequency bidding strategy + goal). + + This field is a member of `oneof`_ ``_allow_non_skippable_in_stream``. + """ + + allow_in_stream: bool = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + allow_in_feed: bool = proto.Field( + proto.BOOL, + number=2, + optional=True, + ) + allow_shorts: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + allow_non_skippable_in_stream: bool = proto.Field( + proto.BOOL, + number=4, + optional=True, + ) + + class VideoAdFormatControl(proto.Message): + r"""Format-restricting control enabling usage of video responsive + ads in format defined Video campaigns (for example, + non-skippable). + + Attributes: + format_restriction (google.ads.googleads.v23.enums.types.VideoAdFormatRestrictionEnum.VideoAdFormatRestriction): + All contained responsive ads are expected to + respect this restriction. + non_skippable_in_stream_restrictions (google.ads.googleads.v23.resources.types.Campaign.VideoCampaignSettings.NonSkippableInStreamRestrictions): + Restrictions for non-skippable format. + """ + + format_restriction: ( + video_ad_format_restriction.VideoAdFormatRestrictionEnum.VideoAdFormatRestriction + ) = proto.Field( + proto.ENUM, + number=1, + enum=video_ad_format_restriction.VideoAdFormatRestrictionEnum.VideoAdFormatRestriction, + ) + non_skippable_in_stream_restrictions: "Campaign.VideoCampaignSettings.NonSkippableInStreamRestrictions" = proto.Field( + proto.MESSAGE, + number=2, + message="Campaign.VideoCampaignSettings.NonSkippableInStreamRestrictions", + ) + + class NonSkippableInStreamRestrictions(proto.Message): + r"""Restrictions for non-skippable format. + + Attributes: + min_duration (google.ads.googleads.v23.enums.types.NonSkippableMinDurationEnum.NonSkippableMinDuration): + The minimum allowed duration for + non-skippable ads. + max_duration (google.ads.googleads.v23.enums.types.NonSkippableMaxDurationEnum.NonSkippableMaxDuration): + The maximum allowed duration for + non-skippable ads. + """ + + min_duration: ( + non_skippable_min_duration.NonSkippableMinDurationEnum.NonSkippableMinDuration + ) = proto.Field( + proto.ENUM, + number=1, + enum=non_skippable_min_duration.NonSkippableMinDurationEnum.NonSkippableMinDuration, + ) + max_duration: ( + non_skippable_max_duration.NonSkippableMaxDurationEnum.NonSkippableMaxDuration + ) = proto.Field( + proto.ENUM, + number=2, + enum=non_skippable_max_duration.NonSkippableMaxDurationEnum.NonSkippableMaxDuration, + ) + + class VideoAdSequence(proto.Message): + r"""Container for video ads sequencing definition. + + Attributes: + steps (MutableSequence[google.ads.googleads.v23.resources.types.Campaign.VideoCampaignSettings.VideoAdSequenceStep]): + The list of sequence steps and data + associated with them. + minimum_duration (google.ads.googleads.v23.enums.types.VideoAdSequenceMinimumDurationEnum.VideoAdSequenceMinimumDuration): + Users are eligible to repeat sequence after + this period. Defaults to WEEK if not specified. + """ + + steps: MutableSequence[ + "Campaign.VideoCampaignSettings.VideoAdSequenceStep" + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="Campaign.VideoCampaignSettings.VideoAdSequenceStep", + ) + minimum_duration: ( + video_ad_sequence_minimum_duration.VideoAdSequenceMinimumDurationEnum.VideoAdSequenceMinimumDuration + ) = proto.Field( + proto.ENUM, + number=2, + enum=video_ad_sequence_minimum_duration.VideoAdSequenceMinimumDurationEnum.VideoAdSequenceMinimumDuration, + ) + + class VideoAdSequenceStep(proto.Message): + r"""Information about a step within a video sequence. + + Attributes: + video_ad_sequence_step_id (int): + The ID of this sequence step. + asset_id (int): + The ID of the Asset for this step. The asset must be type + YOUTUBE_VIDEO. + ad_group_type (google.ads.googleads.v23.enums.types.AdGroupTypeEnum.AdGroupType): + The ad group type for this step (denoting the + video format). + previous_step_id (int): + The ID of the previous step. This field is + required for all steps except the first one. It + must point to a step that appears in the step + definition list before this step. + previous_step_interaction_type (google.ads.googleads.v23.enums.types.VideoAdSequenceInteractionTypeEnum.VideoAdSequenceInteractionType): + Type of interaction *on the previous step* required in order + for the user to advance to this step. As with the previous + step ID, it's required for every step except for the first + one. + """ + + video_ad_sequence_step_id: int = proto.Field( + proto.INT64, + number=1, + ) + asset_id: int = proto.Field( + proto.INT64, + number=2, + ) + ad_group_type: gage_ad_group_type.AdGroupTypeEnum.AdGroupType = ( + proto.Field( + proto.ENUM, + number=3, + enum=gage_ad_group_type.AdGroupTypeEnum.AdGroupType, + ) + ) + previous_step_id: int = proto.Field( + proto.INT64, + number=4, + ) + previous_step_interaction_type: ( + video_ad_sequence_interaction_type.VideoAdSequenceInteractionTypeEnum.VideoAdSequenceInteractionType + ) = proto.Field( + proto.ENUM, + number=5, + enum=video_ad_sequence_interaction_type.VideoAdSequenceInteractionTypeEnum.VideoAdSequenceInteractionType, + ) + + video_ad_sequence: "Campaign.VideoCampaignSettings.VideoAdSequence" = ( + proto.Field( + proto.MESSAGE, + number=4, + message="Campaign.VideoCampaignSettings.VideoAdSequence", + ) + ) + video_ad_inventory_control: ( + "Campaign.VideoCampaignSettings.VideoAdInventoryControl" + ) = proto.Field( + proto.MESSAGE, + number=2, + oneof="fluidity_control", + message="Campaign.VideoCampaignSettings.VideoAdInventoryControl", + ) + video_ad_format_control: ( + "Campaign.VideoCampaignSettings.VideoAdFormatControl" + ) = proto.Field( + proto.MESSAGE, + number=3, + oneof="fluidity_control", + message="Campaign.VideoCampaignSettings.VideoAdFormatControl", + ) + + class PmaxCampaignSettings(proto.Message): + r"""Settings for Performance Max campaigns. + + Attributes: + brand_targeting_overrides (google.ads.googleads.v23.resources.types.Campaign.PmaxCampaignSettings.BrandTargetingOverrides): + Overrides of brand targeting for various ad + types. + """ + + class BrandTargetingOverrides(proto.Message): + r"""Overrides of brand targeting for various ad types. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + ignore_exclusions_for_shopping_ads (bool): + If true, brand exclusions are ignored for + Shopping ads. + + This field is a member of `oneof`_ ``_ignore_exclusions_for_shopping_ads``. + """ + + ignore_exclusions_for_shopping_ads: bool = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + + brand_targeting_overrides: ( + "Campaign.PmaxCampaignSettings.BrandTargetingOverrides" + ) = proto.Field( + proto.MESSAGE, + number=1, + message="Campaign.PmaxCampaignSettings.BrandTargetingOverrides", + ) + + class AssetAutomationSetting(proto.Message): + r"""Asset automation setting contains pair of AssetAutomationType + and the asset automation opt-in/out status + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + asset_automation_type (google.ads.googleads.v23.enums.types.AssetAutomationTypeEnum.AssetAutomationType): + The asset automation type advertiser would + like to opt-in/out. + + This field is a member of `oneof`_ ``_asset_automation_type``. + asset_automation_status (google.ads.googleads.v23.enums.types.AssetAutomationStatusEnum.AssetAutomationStatus): + The opt-in/out status of asset automation + type. + + This field is a member of `oneof`_ ``_asset_automation_status``. + """ + + asset_automation_type: ( + gage_asset_automation_type.AssetAutomationTypeEnum.AssetAutomationType + ) = proto.Field( + proto.ENUM, + number=1, + optional=True, + enum=gage_asset_automation_type.AssetAutomationTypeEnum.AssetAutomationType, + ) + asset_automation_status: ( + gage_asset_automation_status.AssetAutomationStatusEnum.AssetAutomationStatus + ) = proto.Field( + proto.ENUM, + number=2, + optional=True, + enum=gage_asset_automation_status.AssetAutomationStatusEnum.AssetAutomationStatus, + ) + + class BrandGuidelines(proto.Message): + r"""Settings that control the visual appearance of your brand in + a campaign's automatically generated assets and formats. Only + applicable to Performance Max campaigns. + + Attributes: + main_color (str): + The main brand color, entered as a hex code (e.g., #00ff00). + You must provide the main_color if you provide an + accent_color. + accent_color (str): + The accent brand color, entered as a hex code (e.g., + #00ff00). You must provide the accent_color if you provide a + main_color. + predefined_font_family (str): + The brand's font family. Must be one of the + following Google Fonts (case sensitive): Open + Sans, Roboto, Montserrat, Poppins, Lato, Oswald, + Playfair Display, Roboto Slab. + """ + + main_color: str = proto.Field( + proto.STRING, + number=1, + ) + accent_color: str = proto.Field( + proto.STRING, + number=2, + ) + predefined_font_family: str = proto.Field( + proto.STRING, + number=3, + ) + + class AiMaxSetting(proto.Message): + r"""Settings for AI Max in search campaigns. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + enable_ai_max (bool): + Controls whether or not AI Max features are served for this + campaign. + + Individual AI Max features are enabled or disabled by their + respective settings. But if enable_ai_max is set to false or + cleared, then no AI Max features will serve for this + campaign, regardless of the other settings. + + Search Term Matching is enabled by default when AI Max is + enabled, and can be disabled at the ad group level. + + This field is a member of `oneof`_ ``_enable_ai_max``. + bundling_required (google.ads.googleads.v23.resources.types.Campaign.AiMaxSetting.AiMaxBundlingRequired): + Output only. Indicates whether a search + campaign has adopted AI Max before, and is + required to have AI Max enabled to adopt + campaign-level text asset automation and brand + list targeting in all API versions. + + This field is a member of `oneof`_ ``_bundling_required``. + """ + + class AiMaxBundlingRequired(proto.Enum): + r"""Enum describing whether AI Max must be enabled to serve and + update text asset automation and brand list features newly + bundled with AI Max. + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Used for return value only. Represents value + unknown in this version. + NOT_REQUIRED (2): + Search campaign is using text asset + automation or brand list targeting, and AI Max + is not required to be enabled to serve these + features. + REQUIRED (3): + AI Max is required to be enabled for this + search campaign to serve existing text asset + automation and brand list targeting, or to add + new text asset automation and brand list + targeting settings. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + NOT_REQUIRED = 2 + REQUIRED = 3 + + enable_ai_max: bool = proto.Field( + proto.BOOL, + number=1, + optional=True, + ) + bundling_required: "Campaign.AiMaxSetting.AiMaxBundlingRequired" = ( + proto.Field( + proto.ENUM, + number=2, + optional=True, + enum="Campaign.AiMaxSetting.AiMaxBundlingRequired", + ) + ) + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + id: int = proto.Field( + proto.INT64, + number=59, + optional=True, + ) + name: str = proto.Field( + proto.STRING, + number=58, + optional=True, + ) + primary_status: ( + campaign_primary_status.CampaignPrimaryStatusEnum.CampaignPrimaryStatus + ) = proto.Field( + proto.ENUM, + number=81, + enum=campaign_primary_status.CampaignPrimaryStatusEnum.CampaignPrimaryStatus, + ) + primary_status_reasons: MutableSequence[ + campaign_primary_status_reason.CampaignPrimaryStatusReasonEnum.CampaignPrimaryStatusReason + ] = proto.RepeatedField( + proto.ENUM, + number=82, + enum=campaign_primary_status_reason.CampaignPrimaryStatusReasonEnum.CampaignPrimaryStatusReason, + ) + status: campaign_status.CampaignStatusEnum.CampaignStatus = proto.Field( + proto.ENUM, + number=5, + enum=campaign_status.CampaignStatusEnum.CampaignStatus, + ) + serving_status: ( + campaign_serving_status.CampaignServingStatusEnum.CampaignServingStatus + ) = proto.Field( + proto.ENUM, + number=21, + enum=campaign_serving_status.CampaignServingStatusEnum.CampaignServingStatus, + ) + bidding_strategy_system_status: ( + gage_bidding_strategy_system_status.BiddingStrategySystemStatusEnum.BiddingStrategySystemStatus + ) = proto.Field( + proto.ENUM, + number=78, + enum=gage_bidding_strategy_system_status.BiddingStrategySystemStatusEnum.BiddingStrategySystemStatus, + ) + ad_serving_optimization_status: ( + gage_ad_serving_optimization_status.AdServingOptimizationStatusEnum.AdServingOptimizationStatus + ) = proto.Field( + proto.ENUM, + number=8, + enum=gage_ad_serving_optimization_status.AdServingOptimizationStatusEnum.AdServingOptimizationStatus, + ) + advertising_channel_type: ( + gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType + ) = proto.Field( + proto.ENUM, + number=9, + enum=gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType, + ) + advertising_channel_sub_type: ( + gage_advertising_channel_sub_type.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType + ) = proto.Field( + proto.ENUM, + number=10, + enum=gage_advertising_channel_sub_type.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType, + ) + tracking_url_template: str = proto.Field( + proto.STRING, + number=60, + optional=True, + ) + url_custom_parameters: MutableSequence[custom_parameter.CustomParameter] = ( + proto.RepeatedField( + proto.MESSAGE, + number=12, + message=custom_parameter.CustomParameter, + ) + ) + local_services_campaign_settings: LocalServicesCampaignSettings = ( + proto.Field( + proto.MESSAGE, + number=75, + message=LocalServicesCampaignSettings, + ) + ) + travel_campaign_settings: TravelCampaignSettings = proto.Field( + proto.MESSAGE, + number=85, + message=TravelCampaignSettings, + ) + demand_gen_campaign_settings: DemandGenCampaignSettings = proto.Field( + proto.MESSAGE, + number=91, + message=DemandGenCampaignSettings, + ) + video_campaign_settings: VideoCampaignSettings = proto.Field( + proto.MESSAGE, + number=94, + message=VideoCampaignSettings, + ) + pmax_campaign_settings: PmaxCampaignSettings = proto.Field( + proto.MESSAGE, + number=97, + message=PmaxCampaignSettings, + ) + real_time_bidding_setting: ( + gagc_real_time_bidding_setting.RealTimeBiddingSetting + ) = proto.Field( + proto.MESSAGE, + number=39, + message=gagc_real_time_bidding_setting.RealTimeBiddingSetting, + ) + network_settings: NetworkSettings = proto.Field( + proto.MESSAGE, + number=14, + message=NetworkSettings, + ) + hotel_setting: HotelSettingInfo = proto.Field( + proto.MESSAGE, + number=32, + message=HotelSettingInfo, + ) + dynamic_search_ads_setting: DynamicSearchAdsSetting = proto.Field( + proto.MESSAGE, + number=33, + message=DynamicSearchAdsSetting, + ) + shopping_setting: ShoppingSetting = proto.Field( + proto.MESSAGE, + number=36, + message=ShoppingSetting, + ) + targeting_setting: gagc_targeting_setting.TargetingSetting = proto.Field( + proto.MESSAGE, + number=43, + message=gagc_targeting_setting.TargetingSetting, + ) + audience_setting: AudienceSetting = proto.Field( + proto.MESSAGE, + number=73, + optional=True, + message=AudienceSetting, + ) + geo_target_type_setting: GeoTargetTypeSetting = proto.Field( + proto.MESSAGE, + number=47, + message=GeoTargetTypeSetting, + ) + local_campaign_setting: LocalCampaignSetting = proto.Field( + proto.MESSAGE, + number=50, + message=LocalCampaignSetting, + ) + app_campaign_setting: AppCampaignSetting = proto.Field( + proto.MESSAGE, + number=51, + message=AppCampaignSetting, + ) + labels: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=61, + ) + experiment_type: ( + campaign_experiment_type.CampaignExperimentTypeEnum.CampaignExperimentType + ) = proto.Field( + proto.ENUM, + number=17, + enum=campaign_experiment_type.CampaignExperimentTypeEnum.CampaignExperimentType, + ) + base_campaign: str = proto.Field( + proto.STRING, + number=56, + optional=True, + ) + campaign_budget: str = proto.Field( + proto.STRING, + number=62, + optional=True, + ) + bidding_strategy_type: ( + gage_bidding_strategy_type.BiddingStrategyTypeEnum.BiddingStrategyType + ) = proto.Field( + proto.ENUM, + number=22, + enum=gage_bidding_strategy_type.BiddingStrategyTypeEnum.BiddingStrategyType, + ) + accessible_bidding_strategy: str = proto.Field( + proto.STRING, + number=71, + ) + campaign_group: str = proto.Field( + proto.STRING, + number=76, + optional=True, + ) + start_date_time: str = proto.Field( + proto.STRING, + number=104, + optional=True, + ) + end_date_time: str = proto.Field( + proto.STRING, + number=105, + optional=True, + ) + final_url_suffix: str = proto.Field( + proto.STRING, + number=65, + optional=True, + ) + frequency_caps: MutableSequence[frequency_cap.FrequencyCapEntry] = ( + proto.RepeatedField( + proto.MESSAGE, + number=40, + message=frequency_cap.FrequencyCapEntry, + ) + ) + video_brand_safety_suitability: ( + brand_safety_suitability.BrandSafetySuitabilityEnum.BrandSafetySuitability + ) = proto.Field( + proto.ENUM, + number=42, + enum=brand_safety_suitability.BrandSafetySuitabilityEnum.BrandSafetySuitability, + ) + vanity_pharma: VanityPharma = proto.Field( + proto.MESSAGE, + number=44, + message=VanityPharma, + ) + selective_optimization: SelectiveOptimization = proto.Field( + proto.MESSAGE, + number=45, + message=SelectiveOptimization, + ) + optimization_goal_setting: OptimizationGoalSetting = proto.Field( + proto.MESSAGE, + number=54, + message=OptimizationGoalSetting, + ) + tracking_setting: TrackingSetting = proto.Field( + proto.MESSAGE, + number=46, + message=TrackingSetting, + ) + payment_mode: gage_payment_mode.PaymentModeEnum.PaymentMode = proto.Field( + proto.ENUM, + number=52, + enum=gage_payment_mode.PaymentModeEnum.PaymentMode, + ) + optimization_score: float = proto.Field( + proto.DOUBLE, + number=66, + optional=True, + ) + excluded_parent_asset_field_types: MutableSequence[ + asset_field_type.AssetFieldTypeEnum.AssetFieldType + ] = proto.RepeatedField( + proto.ENUM, + number=69, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + excluded_parent_asset_set_types: MutableSequence[ + asset_set_type.AssetSetTypeEnum.AssetSetType + ] = proto.RepeatedField( + proto.ENUM, + number=80, + enum=asset_set_type.AssetSetTypeEnum.AssetSetType, + ) + performance_max_upgrade: PerformanceMaxUpgrade = proto.Field( + proto.MESSAGE, + number=77, + message=PerformanceMaxUpgrade, + ) + hotel_property_asset_set: str = proto.Field( + proto.STRING, + number=83, + optional=True, + ) + listing_type: gage_listing_type.ListingTypeEnum.ListingType = proto.Field( + proto.ENUM, + number=86, + optional=True, + enum=gage_listing_type.ListingTypeEnum.ListingType, + ) + asset_automation_settings: MutableSequence[AssetAutomationSetting] = ( + proto.RepeatedField( + proto.MESSAGE, + number=88, + message=AssetAutomationSetting, + ) + ) + keyword_match_type: ( + campaign_keyword_match_type.CampaignKeywordMatchTypeEnum.CampaignKeywordMatchType + ) = proto.Field( + proto.ENUM, + number=90, + enum=campaign_keyword_match_type.CampaignKeywordMatchTypeEnum.CampaignKeywordMatchType, + ) + brand_guidelines_enabled: bool = proto.Field( + proto.BOOL, + number=96, + optional=True, + ) + brand_guidelines: BrandGuidelines = proto.Field( + proto.MESSAGE, + number=98, + message=BrandGuidelines, + ) + third_party_integration_partners: ( + gagc_third_party_integration_partners.CampaignThirdPartyIntegrationPartners + ) = proto.Field( + proto.MESSAGE, + number=100, + message=gagc_third_party_integration_partners.CampaignThirdPartyIntegrationPartners, + ) + ai_max_setting: AiMaxSetting = proto.Field( + proto.MESSAGE, + number=101, + message=AiMaxSetting, + ) + contains_eu_political_advertising: ( + eu_political_advertising_status.EuPoliticalAdvertisingStatusEnum.EuPoliticalAdvertisingStatus + ) = proto.Field( + proto.ENUM, + number=102, + enum=eu_political_advertising_status.EuPoliticalAdvertisingStatusEnum.EuPoliticalAdvertisingStatus, + ) + feed_types: MutableSequence[ + asset_set_type.AssetSetTypeEnum.AssetSetType + ] = proto.RepeatedField( + proto.ENUM, + number=103, + enum=asset_set_type.AssetSetTypeEnum.AssetSetType, + ) + bidding_strategy: str = proto.Field( + proto.STRING, + number=67, + oneof="campaign_bidding_strategy", + ) + commission: bidding.Commission = proto.Field( + proto.MESSAGE, + number=49, + oneof="campaign_bidding_strategy", + message=bidding.Commission, + ) + manual_cpa: bidding.ManualCpa = proto.Field( + proto.MESSAGE, + number=74, + oneof="campaign_bidding_strategy", + message=bidding.ManualCpa, + ) + manual_cpc: bidding.ManualCpc = proto.Field( + proto.MESSAGE, + number=24, + oneof="campaign_bidding_strategy", + message=bidding.ManualCpc, + ) + manual_cpm: bidding.ManualCpm = proto.Field( + proto.MESSAGE, + number=25, + oneof="campaign_bidding_strategy", + message=bidding.ManualCpm, + ) + manual_cpv: bidding.ManualCpv = proto.Field( + proto.MESSAGE, + number=37, + oneof="campaign_bidding_strategy", + message=bidding.ManualCpv, + ) + maximize_conversions: bidding.MaximizeConversions = proto.Field( + proto.MESSAGE, + number=30, + oneof="campaign_bidding_strategy", + message=bidding.MaximizeConversions, + ) + maximize_conversion_value: bidding.MaximizeConversionValue = proto.Field( + proto.MESSAGE, + number=31, + oneof="campaign_bidding_strategy", + message=bidding.MaximizeConversionValue, + ) + target_cpa: bidding.TargetCpa = proto.Field( + proto.MESSAGE, + number=26, + oneof="campaign_bidding_strategy", + message=bidding.TargetCpa, + ) + target_impression_share: bidding.TargetImpressionShare = proto.Field( + proto.MESSAGE, + number=48, + oneof="campaign_bidding_strategy", + message=bidding.TargetImpressionShare, + ) + target_roas: bidding.TargetRoas = proto.Field( + proto.MESSAGE, + number=29, + oneof="campaign_bidding_strategy", + message=bidding.TargetRoas, + ) + target_spend: bidding.TargetSpend = proto.Field( + proto.MESSAGE, + number=27, + oneof="campaign_bidding_strategy", + message=bidding.TargetSpend, + ) + percent_cpc: bidding.PercentCpc = proto.Field( + proto.MESSAGE, + number=34, + oneof="campaign_bidding_strategy", + message=bidding.PercentCpc, + ) + target_cpm: bidding.TargetCpm = proto.Field( + proto.MESSAGE, + number=41, + oneof="campaign_bidding_strategy", + message=bidding.TargetCpm, + ) + fixed_cpm: bidding.FixedCpm = proto.Field( + proto.MESSAGE, + number=92, + oneof="campaign_bidding_strategy", + message=bidding.FixedCpm, + ) + target_cpv: bidding.TargetCpv = proto.Field( + proto.MESSAGE, + number=93, + oneof="campaign_bidding_strategy", + message=bidding.TargetCpv, + ) + target_cpc: bidding.TargetCpc = proto.Field( + proto.MESSAGE, + number=99, + oneof="campaign_bidding_strategy", + message=bidding.TargetCpc, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/campaign_aggregate_asset_view.py b/google/ads/googleads/v23/resources/types/campaign_aggregate_asset_view.py similarity index 89% rename from google/ads/googleads/v19/resources/types/campaign_aggregate_asset_view.py rename to google/ads/googleads/v23/resources/types/campaign_aggregate_asset_view.py index 6a9b726df..62ad1b66f 100644 --- a/google/ads/googleads/v19/resources/types/campaign_aggregate_asset_view.py +++ b/google/ads/googleads/v23/resources/types/campaign_aggregate_asset_view.py @@ -18,15 +18,15 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import asset_field_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import asset_field_type +from google.ads.googleads.v23.enums.types import ( asset_source as gage_asset_source, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignAggregateAssetView", }, @@ -56,11 +56,11 @@ class CampaignAggregateAssetView(proto.Message): Output only. The ID of the asset. This field is a member of `oneof`_ ``_asset``. - asset_source (google.ads.googleads.v19.enums.types.AssetSourceEnum.AssetSource): + asset_source (google.ads.googleads.v23.enums.types.AssetSourceEnum.AssetSource): Output only. Source of the asset link. This field is a member of `oneof`_ ``_asset_source``. - field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): Output only. FieldType of the asset. This field is a member of `oneof`_ ``_field_type``. diff --git a/google/ads/googleads/v19/resources/types/campaign_asset.py b/google/ads/googleads/v23/resources/types/campaign_asset.py similarity index 84% rename from google/ads/googleads/v19/resources/types/campaign_asset.py rename to google/ads/googleads/v23/resources/types/campaign_asset.py index fe9212110..0ed4b6474 100644 --- a/google/ads/googleads/v19/resources/types/campaign_asset.py +++ b/google/ads/googleads/v23/resources/types/campaign_asset.py @@ -19,19 +19,19 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import asset_policy -from google.ads.googleads.v19.enums.types import asset_field_type -from google.ads.googleads.v19.enums.types import asset_link_primary_status -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import asset_policy +from google.ads.googleads.v23.enums.types import asset_field_type +from google.ads.googleads.v23.enums.types import asset_link_primary_status +from google.ads.googleads.v23.enums.types import ( asset_link_primary_status_reason, ) -from google.ads.googleads.v19.enums.types import asset_link_status -from google.ads.googleads.v19.enums.types import asset_source +from google.ads.googleads.v23.enums.types import asset_link_status +from google.ads.googleads.v23.enums.types import asset_source __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignAsset", }, @@ -59,15 +59,15 @@ class CampaignAsset(proto.Message): campaign. This field is a member of `oneof`_ ``_asset``. - field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): Immutable. Role that the asset takes under the linked campaign. Required. - source (google.ads.googleads.v19.enums.types.AssetSourceEnum.AssetSource): + source (google.ads.googleads.v23.enums.types.AssetSourceEnum.AssetSource): Output only. Source of the campaign asset link. - status (google.ads.googleads.v19.enums.types.AssetLinkStatusEnum.AssetLinkStatus): + status (google.ads.googleads.v23.enums.types.AssetLinkStatusEnum.AssetLinkStatus): Status of the campaign asset. - primary_status (google.ads.googleads.v19.enums.types.AssetLinkPrimaryStatusEnum.AssetLinkPrimaryStatus): + primary_status (google.ads.googleads.v23.enums.types.AssetLinkPrimaryStatusEnum.AssetLinkPrimaryStatus): Output only. Provides the PrimaryStatus of this asset link. Primary status is meant essentially to differentiate between the plain @@ -77,10 +77,10 @@ class CampaignAsset(proto.Message): assets its mainly policy and quality approvals) to come up with a more comprehensive status to indicate its serving state. - primary_status_details (MutableSequence[google.ads.googleads.v19.common.types.AssetLinkPrimaryStatusDetails]): + primary_status_details (MutableSequence[google.ads.googleads.v23.common.types.AssetLinkPrimaryStatusDetails]): Output only. Provides the details of the primary status and its associated reasons. - primary_status_reasons (MutableSequence[google.ads.googleads.v19.enums.types.AssetLinkPrimaryStatusReasonEnum.AssetLinkPrimaryStatusReason]): + primary_status_reasons (MutableSequence[google.ads.googleads.v23.enums.types.AssetLinkPrimaryStatusReasonEnum.AssetLinkPrimaryStatusReason]): Output only. Provides a list of reasons for why an asset is not serving or not serving at full capacity. diff --git a/google/ads/googleads/v19/resources/types/campaign_asset_set.py b/google/ads/googleads/v23/resources/types/campaign_asset_set.py similarity index 90% rename from google/ads/googleads/v19/resources/types/campaign_asset_set.py rename to google/ads/googleads/v23/resources/types/campaign_asset_set.py index 26169cdee..7a75b7c78 100644 --- a/google/ads/googleads/v19/resources/types/campaign_asset_set.py +++ b/google/ads/googleads/v23/resources/types/campaign_asset_set.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import asset_set_link_status +from google.ads.googleads.v23.enums.types import asset_set_link_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignAssetSet", }, @@ -47,7 +47,7 @@ class CampaignAssetSet(proto.Message): asset_set (str): Immutable. The asset set which is linked to the campaign. - status (google.ads.googleads.v19.enums.types.AssetSetLinkStatusEnum.AssetSetLinkStatus): + status (google.ads.googleads.v23.enums.types.AssetSetLinkStatusEnum.AssetSetLinkStatus): Output only. The status of the campaign asset set asset. Read-only. """ diff --git a/google/ads/googleads/v19/resources/types/campaign_audience_view.py b/google/ads/googleads/v23/resources/types/campaign_audience_view.py similarity index 94% rename from google/ads/googleads/v19/resources/types/campaign_audience_view.py rename to google/ads/googleads/v23/resources/types/campaign_audience_view.py index ff6a55792..d38e199ae 100644 --- a/google/ads/googleads/v19/resources/types/campaign_audience_view.py +++ b/google/ads/googleads/v23/resources/types/campaign_audience_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignAudienceView", }, diff --git a/google/ads/googleads/v19/resources/types/campaign_bid_modifier.py b/google/ads/googleads/v23/resources/types/campaign_bid_modifier.py similarity index 92% rename from google/ads/googleads/v19/resources/types/campaign_bid_modifier.py rename to google/ads/googleads/v23/resources/types/campaign_bid_modifier.py index bbeea628f..25bde00e1 100644 --- a/google/ads/googleads/v19/resources/types/campaign_bid_modifier.py +++ b/google/ads/googleads/v23/resources/types/campaign_bid_modifier.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import criteria +from google.ads.googleads.v23.common.types import criteria __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignBidModifier", }, @@ -59,7 +59,7 @@ class CampaignBidModifier(proto.Message): matches. This field is a member of `oneof`_ ``_bid_modifier``. - interaction_type (google.ads.googleads.v19.common.types.InteractionTypeInfo): + interaction_type (google.ads.googleads.v23.common.types.InteractionTypeInfo): Immutable. Criterion for interaction type. Only supported for search campaigns. diff --git a/google/ads/googleads/v19/resources/types/campaign_budget.py b/google/ads/googleads/v23/resources/types/campaign_budget.py similarity index 94% rename from google/ads/googleads/v19/resources/types/campaign_budget.py rename to google/ads/googleads/v23/resources/types/campaign_budget.py index aad48c54e..e38dd5aa5 100644 --- a/google/ads/googleads/v19/resources/types/campaign_budget.py +++ b/google/ads/googleads/v23/resources/types/campaign_budget.py @@ -18,15 +18,15 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import budget_delivery_method -from google.ads.googleads.v19.enums.types import budget_period -from google.ads.googleads.v19.enums.types import budget_status -from google.ads.googleads.v19.enums.types import budget_type +from google.ads.googleads.v23.enums.types import budget_delivery_method +from google.ads.googleads.v23.enums.types import budget_period +from google.ads.googleads.v23.enums.types import budget_status +from google.ads.googleads.v23.enums.types import budget_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignBudget", }, @@ -84,10 +84,10 @@ class CampaignBudget(proto.Message): equivalent to one currency unit. This field is a member of `oneof`_ ``_total_amount_micros``. - status (google.ads.googleads.v19.enums.types.BudgetStatusEnum.BudgetStatus): + status (google.ads.googleads.v23.enums.types.BudgetStatusEnum.BudgetStatus): Output only. The status of this campaign budget. This field is read-only. - delivery_method (google.ads.googleads.v19.enums.types.BudgetDeliveryMethodEnum.BudgetDeliveryMethod): + delivery_method (google.ads.googleads.v23.enums.types.BudgetDeliveryMethodEnum.BudgetDeliveryMethod): The delivery method that determines the rate at which the campaign budget is spent. @@ -139,7 +139,7 @@ class CampaignBudget(proto.Message): This field is read-only. This field is a member of `oneof`_ ``_recommended_budget_amount_micros``. - period (google.ads.googleads.v19.enums.types.BudgetPeriodEnum.BudgetPeriod): + period (google.ads.googleads.v23.enums.types.BudgetPeriodEnum.BudgetPeriod): Immutable. Period over which to spend the budget. Defaults to DAILY if not specified. recommended_budget_estimated_change_weekly_clicks (int): @@ -173,7 +173,7 @@ class CampaignBudget(proto.Message): This field is read-only. This field is a member of `oneof`_ ``_recommended_budget_estimated_change_weekly_views``. - type_ (google.ads.googleads.v19.enums.types.BudgetTypeEnum.BudgetType): + type_ (google.ads.googleads.v23.enums.types.BudgetTypeEnum.BudgetType): Immutable. The type of the campaign budget. aligned_bidding_strategy_id (int): ID of the portfolio bidding strategy that diff --git a/google/ads/googleads/v19/resources/types/campaign_conversion_goal.py b/google/ads/googleads/v23/resources/types/campaign_conversion_goal.py similarity index 87% rename from google/ads/googleads/v19/resources/types/campaign_conversion_goal.py rename to google/ads/googleads/v23/resources/types/campaign_conversion_goal.py index ba9ce1f3a..0d176111d 100644 --- a/google/ads/googleads/v19/resources/types/campaign_conversion_goal.py +++ b/google/ads/googleads/v23/resources/types/campaign_conversion_goal.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import conversion_action_category -from google.ads.googleads.v19.enums.types import conversion_origin +from google.ads.googleads.v23.enums.types import conversion_action_category +from google.ads.googleads.v23.enums.types import conversion_origin __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignConversionGoal", }, @@ -44,10 +44,10 @@ class CampaignConversionGoal(proto.Message): campaign (str): Immutable. The campaign with which this campaign conversion goal is associated. - category (google.ads.googleads.v19.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): + category (google.ads.googleads.v23.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): The conversion category of this campaign conversion goal. - origin (google.ads.googleads.v19.enums.types.ConversionOriginEnum.ConversionOrigin): + origin (google.ads.googleads.v23.enums.types.ConversionOriginEnum.ConversionOrigin): The conversion origin of this campaign conversion goal. biddable (bool): diff --git a/google/ads/googleads/v19/resources/types/campaign_criterion.py b/google/ads/googleads/v23/resources/types/campaign_criterion.py similarity index 76% rename from google/ads/googleads/v19/resources/types/campaign_criterion.py rename to google/ads/googleads/v23/resources/types/campaign_criterion.py index 955831293..24c6d0b2b 100644 --- a/google/ads/googleads/v19/resources/types/campaign_criterion.py +++ b/google/ads/googleads/v23/resources/types/campaign_criterion.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.enums.types import campaign_criterion_status -from google.ads.googleads.v19.enums.types import criterion_type +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import campaign_criterion_status +from google.ads.googleads.v23.enums.types import criterion_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignCriterion", }, @@ -75,137 +75,157 @@ class CampaignCriterion(proto.Message): (``true``) the criterion. This field is a member of `oneof`_ ``_negative``. - type_ (google.ads.googleads.v19.enums.types.CriterionTypeEnum.CriterionType): + type_ (google.ads.googleads.v23.enums.types.CriterionTypeEnum.CriterionType): Output only. The type of the criterion. - status (google.ads.googleads.v19.enums.types.CampaignCriterionStatusEnum.CampaignCriterionStatus): + status (google.ads.googleads.v23.enums.types.CampaignCriterionStatusEnum.CampaignCriterionStatus): The status of the criterion. - keyword (google.ads.googleads.v19.common.types.KeywordInfo): + keyword (google.ads.googleads.v23.common.types.KeywordInfo): Immutable. Keyword. This field is a member of `oneof`_ ``criterion``. - placement (google.ads.googleads.v19.common.types.PlacementInfo): + placement (google.ads.googleads.v23.common.types.PlacementInfo): Immutable. Placement. This field is a member of `oneof`_ ``criterion``. - mobile_app_category (google.ads.googleads.v19.common.types.MobileAppCategoryInfo): + mobile_app_category (google.ads.googleads.v23.common.types.MobileAppCategoryInfo): Immutable. Mobile app category. This field is a member of `oneof`_ ``criterion``. - mobile_application (google.ads.googleads.v19.common.types.MobileApplicationInfo): + mobile_application (google.ads.googleads.v23.common.types.MobileApplicationInfo): Immutable. Mobile application. This field is a member of `oneof`_ ``criterion``. - location (google.ads.googleads.v19.common.types.LocationInfo): + location (google.ads.googleads.v23.common.types.LocationInfo): Immutable. Location. This field is a member of `oneof`_ ``criterion``. - device (google.ads.googleads.v19.common.types.DeviceInfo): + device (google.ads.googleads.v23.common.types.DeviceInfo): Immutable. Device. This field is a member of `oneof`_ ``criterion``. - ad_schedule (google.ads.googleads.v19.common.types.AdScheduleInfo): + ad_schedule (google.ads.googleads.v23.common.types.AdScheduleInfo): Immutable. Ad Schedule. This field is a member of `oneof`_ ``criterion``. - age_range (google.ads.googleads.v19.common.types.AgeRangeInfo): + age_range (google.ads.googleads.v23.common.types.AgeRangeInfo): Immutable. Age range. This field is a member of `oneof`_ ``criterion``. - gender (google.ads.googleads.v19.common.types.GenderInfo): + gender (google.ads.googleads.v23.common.types.GenderInfo): Immutable. Gender. This field is a member of `oneof`_ ``criterion``. - income_range (google.ads.googleads.v19.common.types.IncomeRangeInfo): + income_range (google.ads.googleads.v23.common.types.IncomeRangeInfo): Immutable. Income range. This field is a member of `oneof`_ ``criterion``. - parental_status (google.ads.googleads.v19.common.types.ParentalStatusInfo): + parental_status (google.ads.googleads.v23.common.types.ParentalStatusInfo): Immutable. Parental status. This field is a member of `oneof`_ ``criterion``. - user_list (google.ads.googleads.v19.common.types.UserListInfo): + user_list (google.ads.googleads.v23.common.types.UserListInfo): Immutable. User List. This field is a member of `oneof`_ ``criterion``. - youtube_video (google.ads.googleads.v19.common.types.YouTubeVideoInfo): + youtube_video (google.ads.googleads.v23.common.types.YouTubeVideoInfo): Immutable. YouTube Video. This field is a member of `oneof`_ ``criterion``. - youtube_channel (google.ads.googleads.v19.common.types.YouTubeChannelInfo): + youtube_channel (google.ads.googleads.v23.common.types.YouTubeChannelInfo): Immutable. YouTube Channel. This field is a member of `oneof`_ ``criterion``. - proximity (google.ads.googleads.v19.common.types.ProximityInfo): + proximity (google.ads.googleads.v23.common.types.ProximityInfo): Immutable. Proximity. This field is a member of `oneof`_ ``criterion``. - topic (google.ads.googleads.v19.common.types.TopicInfo): + topic (google.ads.googleads.v23.common.types.TopicInfo): Immutable. Topic. This field is a member of `oneof`_ ``criterion``. - listing_scope (google.ads.googleads.v19.common.types.ListingScopeInfo): + listing_scope (google.ads.googleads.v23.common.types.ListingScopeInfo): Immutable. Listing scope. This field is a member of `oneof`_ ``criterion``. - language (google.ads.googleads.v19.common.types.LanguageInfo): + language (google.ads.googleads.v23.common.types.LanguageInfo): Immutable. Language. This field is a member of `oneof`_ ``criterion``. - ip_block (google.ads.googleads.v19.common.types.IpBlockInfo): + ip_block (google.ads.googleads.v23.common.types.IpBlockInfo): Immutable. IpBlock. + You can exclude up to 500 IP addresses per + campaign. + This field is a member of `oneof`_ ``criterion``. - content_label (google.ads.googleads.v19.common.types.ContentLabelInfo): + content_label (google.ads.googleads.v23.common.types.ContentLabelInfo): Immutable. ContentLabel. This field is a member of `oneof`_ ``criterion``. - carrier (google.ads.googleads.v19.common.types.CarrierInfo): + carrier (google.ads.googleads.v23.common.types.CarrierInfo): Immutable. Carrier. This field is a member of `oneof`_ ``criterion``. - user_interest (google.ads.googleads.v19.common.types.UserInterestInfo): + user_interest (google.ads.googleads.v23.common.types.UserInterestInfo): Immutable. User Interest. This field is a member of `oneof`_ ``criterion``. - webpage (google.ads.googleads.v19.common.types.WebpageInfo): + webpage (google.ads.googleads.v23.common.types.WebpageInfo): Immutable. Webpage. This field is a member of `oneof`_ ``criterion``. - operating_system_version (google.ads.googleads.v19.common.types.OperatingSystemVersionInfo): + operating_system_version (google.ads.googleads.v23.common.types.OperatingSystemVersionInfo): Immutable. Operating system version. This field is a member of `oneof`_ ``criterion``. - mobile_device (google.ads.googleads.v19.common.types.MobileDeviceInfo): + mobile_device (google.ads.googleads.v23.common.types.MobileDeviceInfo): Immutable. Mobile Device. This field is a member of `oneof`_ ``criterion``. - location_group (google.ads.googleads.v19.common.types.LocationGroupInfo): + location_group (google.ads.googleads.v23.common.types.LocationGroupInfo): Immutable. Location Group This field is a member of `oneof`_ ``criterion``. - custom_affinity (google.ads.googleads.v19.common.types.CustomAffinityInfo): + custom_affinity (google.ads.googleads.v23.common.types.CustomAffinityInfo): Immutable. Custom Affinity. This field is a member of `oneof`_ ``criterion``. - custom_audience (google.ads.googleads.v19.common.types.CustomAudienceInfo): + custom_audience (google.ads.googleads.v23.common.types.CustomAudienceInfo): Immutable. Custom Audience This field is a member of `oneof`_ ``criterion``. - combined_audience (google.ads.googleads.v19.common.types.CombinedAudienceInfo): + combined_audience (google.ads.googleads.v23.common.types.CombinedAudienceInfo): Immutable. Combined Audience. This field is a member of `oneof`_ ``criterion``. - keyword_theme (google.ads.googleads.v19.common.types.KeywordThemeInfo): + keyword_theme (google.ads.googleads.v23.common.types.KeywordThemeInfo): Immutable. Smart Campaign Keyword Theme. This field is a member of `oneof`_ ``criterion``. - local_service_id (google.ads.googleads.v19.common.types.LocalServiceIdInfo): + local_service_id (google.ads.googleads.v23.common.types.LocalServiceIdInfo): Immutable. GLS service campaign criterion. This field is a member of `oneof`_ ``criterion``. - brand_list (google.ads.googleads.v19.common.types.BrandListInfo): + brand_list (google.ads.googleads.v23.common.types.BrandListInfo): Immutable. Brand list campaign criterion. + This field is a member of `oneof`_ ``criterion``. + life_event (google.ads.googleads.v23.common.types.LifeEventInfo): + Immutable. Life event campaign criterion. + + This field is a member of `oneof`_ ``criterion``. + webpage_list (google.ads.googleads.v23.common.types.WebpageListInfo): + Immutable. Webpage list. + This criterion is not publicly available. + + This field is a member of `oneof`_ ``criterion``. + video_lineup (google.ads.googleads.v23.common.types.VideoLineupInfo): + Immutable. Video lineup criterion. + + This field is a member of `oneof`_ ``criterion``. + extended_demographic (google.ads.googleads.v23.common.types.ExtendedDemographicInfo): + Immutable. Extended demographic criterion. + This field is a member of `oneof`_ ``criterion``. """ @@ -441,6 +461,30 @@ class CampaignCriterion(proto.Message): oneof="criterion", message=criteria.BrandListInfo, ) + life_event: criteria.LifeEventInfo = proto.Field( + proto.MESSAGE, + number=48, + oneof="criterion", + message=criteria.LifeEventInfo, + ) + webpage_list: criteria.WebpageListInfo = proto.Field( + proto.MESSAGE, + number=49, + oneof="criterion", + message=criteria.WebpageListInfo, + ) + video_lineup: criteria.VideoLineupInfo = proto.Field( + proto.MESSAGE, + number=50, + oneof="criterion", + message=criteria.VideoLineupInfo, + ) + extended_demographic: criteria.ExtendedDemographicInfo = proto.Field( + proto.MESSAGE, + number=52, + oneof="criterion", + message=criteria.ExtendedDemographicInfo, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/campaign_customizer.py b/google/ads/googleads/v23/resources/types/campaign_customizer.py similarity index 87% rename from google/ads/googleads/v19/resources/types/campaign_customizer.py rename to google/ads/googleads/v23/resources/types/campaign_customizer.py index 1225f9ea1..9637903d8 100644 --- a/google/ads/googleads/v19/resources/types/campaign_customizer.py +++ b/google/ads/googleads/v23/resources/types/campaign_customizer.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import customizer_value -from google.ads.googleads.v19.enums.types import customizer_value_status +from google.ads.googleads.v23.common.types import customizer_value +from google.ads.googleads.v23.enums.types import customizer_value_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignCustomizer", }, @@ -47,10 +47,10 @@ class CampaignCustomizer(proto.Message): customizer_attribute (str): Required. Immutable. The customizer attribute which is linked to the campaign. - status (google.ads.googleads.v19.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): + status (google.ads.googleads.v23.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): Output only. The status of the campaign customizer. - value (google.ads.googleads.v19.common.types.CustomizerValue): + value (google.ads.googleads.v23.common.types.CustomizerValue): Required. The value to associate with the customizer attribute at this level. The value must be of the type specified for the diff --git a/google/ads/googleads/v19/resources/types/campaign_draft.py b/google/ads/googleads/v23/resources/types/campaign_draft.py similarity index 94% rename from google/ads/googleads/v19/resources/types/campaign_draft.py rename to google/ads/googleads/v23/resources/types/campaign_draft.py index 8681740ad..7b35bfe52 100644 --- a/google/ads/googleads/v19/resources/types/campaign_draft.py +++ b/google/ads/googleads/v23/resources/types/campaign_draft.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import campaign_draft_status +from google.ads.googleads.v23.enums.types import campaign_draft_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignDraft", }, @@ -71,7 +71,7 @@ class CampaignDraft(proto.Message): This field is read-only. This field is a member of `oneof`_ ``_draft_campaign``. - status (google.ads.googleads.v19.enums.types.CampaignDraftStatusEnum.CampaignDraftStatus): + status (google.ads.googleads.v23.enums.types.CampaignDraftStatusEnum.CampaignDraftStatus): Output only. The status of the campaign draft. This field is read-only. When a new campaign draft is added, the status diff --git a/google/ads/googleads/v23/resources/types/campaign_goal_config.py b/google/ads/googleads/v23/resources/types/campaign_goal_config.py new file mode 100644 index 000000000..dae5231f8 --- /dev/null +++ b/google/ads/googleads/v23/resources/types/campaign_goal_config.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import campaign_goal_settings +from google.ads.googleads.v23.enums.types import goal_type as gage_goal_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "CampaignGoalConfig", + }, +) + + +class CampaignGoalConfig(proto.Message): + r"""A link between a campaign and a goal enabling + campaign-specific optimization. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the campaign goal config. + campaign goal config resource names have the form: + ``customers/{customer_id}/campaignGoalConfigs/{campaign_id}~{goal_id}`` + campaign (str): + Immutable. The resource name of the campaign + for this link. + goal (str): + Immutable. The resource name of the goal this + link is attached to. + goal_type (google.ads.googleads.v23.enums.types.GoalTypeEnum.GoalType): + Output only. The goal type this link is + attached to. + campaign_retention_settings (google.ads.googleads.v23.common.types.CampaignGoalSettings.CampaignRetentionGoalSettings): + Retention goal campaign settings. + + This field is a member of `oneof`_ ``campaign_goal_config_settings``. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + campaign: str = proto.Field( + proto.STRING, + number=2, + ) + goal: str = proto.Field( + proto.STRING, + number=3, + ) + goal_type: gage_goal_type.GoalTypeEnum.GoalType = proto.Field( + proto.ENUM, + number=4, + enum=gage_goal_type.GoalTypeEnum.GoalType, + ) + campaign_retention_settings: ( + campaign_goal_settings.CampaignGoalSettings.CampaignRetentionGoalSettings + ) = proto.Field( + proto.MESSAGE, + number=5, + oneof="campaign_goal_config_settings", + message=campaign_goal_settings.CampaignGoalSettings.CampaignRetentionGoalSettings, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/campaign_group.py b/google/ads/googleads/v23/resources/types/campaign_group.py similarity index 90% rename from google/ads/googleads/v19/resources/types/campaign_group.py rename to google/ads/googleads/v23/resources/types/campaign_group.py index 76676e9ec..96f9f566f 100644 --- a/google/ads/googleads/v19/resources/types/campaign_group.py +++ b/google/ads/googleads/v23/resources/types/campaign_group.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import campaign_group_status +from google.ads.googleads.v23.enums.types import campaign_group_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignGroup", }, @@ -50,7 +50,7 @@ class CampaignGroup(proto.Message): It must not contain any null (code point 0x0), NL line feed (code point 0xA) or carriage return (code point 0xD) characters. - status (google.ads.googleads.v19.enums.types.CampaignGroupStatusEnum.CampaignGroupStatus): + status (google.ads.googleads.v23.enums.types.CampaignGroupStatusEnum.CampaignGroupStatus): The status of the campaign group. When a new campaign group is added, the status diff --git a/google/ads/googleads/v19/resources/types/campaign_label.py b/google/ads/googleads/v23/resources/types/campaign_label.py similarity index 95% rename from google/ads/googleads/v19/resources/types/campaign_label.py rename to google/ads/googleads/v23/resources/types/campaign_label.py index ec95ae9a9..e77056be7 100644 --- a/google/ads/googleads/v19/resources/types/campaign_label.py +++ b/google/ads/googleads/v23/resources/types/campaign_label.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignLabel", }, diff --git a/google/ads/googleads/v19/resources/types/campaign_lifecycle_goal.py b/google/ads/googleads/v23/resources/types/campaign_lifecycle_goal.py similarity index 88% rename from google/ads/googleads/v19/resources/types/campaign_lifecycle_goal.py rename to google/ads/googleads/v23/resources/types/campaign_lifecycle_goal.py index a14b247a7..c421a3216 100644 --- a/google/ads/googleads/v19/resources/types/campaign_lifecycle_goal.py +++ b/google/ads/googleads/v23/resources/types/campaign_lifecycle_goal.py @@ -18,15 +18,15 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import lifecycle_goals -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import lifecycle_goals +from google.ads.googleads.v23.enums.types import ( customer_acquisition_optimization_mode, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignLifecycleGoal", "CustomerAcquisitionGoalSettings", @@ -46,7 +46,7 @@ class CampaignLifecycleGoal(proto.Message): campaign (str): Output only. The campaign where the goal is attached. - customer_acquisition_goal_settings (google.ads.googleads.v19.resources.types.CustomerAcquisitionGoalSettings): + customer_acquisition_goal_settings (google.ads.googleads.v23.resources.types.CustomerAcquisitionGoalSettings): Output only. The customer acquisition goal settings for the campaign. The customer acquisition goal is described in this article: @@ -75,10 +75,10 @@ class CustomerAcquisitionGoalSettings(proto.Message): r"""The customer acquisition goal settings for the campaign. Attributes: - optimization_mode (google.ads.googleads.v19.enums.types.CustomerAcquisitionOptimizationModeEnum.CustomerAcquisitionOptimizationMode): + optimization_mode (google.ads.googleads.v23.enums.types.CustomerAcquisitionOptimizationModeEnum.CustomerAcquisitionOptimizationMode): Output only. Customer acquisition optimization mode of this campaign. - value_settings (google.ads.googleads.v19.common.types.LifecycleGoalValueSettings): + value_settings (google.ads.googleads.v23.common.types.LifecycleGoalValueSettings): Output only. Campaign specific values for the customer acquisition goal. """ diff --git a/google/ads/googleads/v19/resources/types/campaign_search_term_insight.py b/google/ads/googleads/v23/resources/types/campaign_search_term_insight.py similarity index 96% rename from google/ads/googleads/v19/resources/types/campaign_search_term_insight.py rename to google/ads/googleads/v23/resources/types/campaign_search_term_insight.py index ca061233e..acde352b4 100644 --- a/google/ads/googleads/v19/resources/types/campaign_search_term_insight.py +++ b/google/ads/googleads/v23/resources/types/campaign_search_term_insight.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignSearchTermInsight", }, diff --git a/google/ads/googleads/v23/resources/types/campaign_search_term_view.py b/google/ads/googleads/v23/resources/types/campaign_search_term_view.py new file mode 100644 index 000000000..150f5eef4 --- /dev/null +++ b/google/ads/googleads/v23/resources/types/campaign_search_term_view.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "CampaignSearchTermView", + }, +) + + +class CampaignSearchTermView(proto.Message): + r"""This report provides granular performance data, including + cost metrics, for each individual search term that triggered + your ads. If keyword-related segments are used, Performance Max + data will be excluded from the results. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Output only. The resource name of the campaign search term + view. Campaign search term view resource names have the + form: + + ``customers/{customer_id}/campaignSearchTermViews/{campaign_id}~{URL-base64_search_term}`` + search_term (str): + Output only. The search term. + + This field is a member of `oneof`_ ``_search_term``. + campaign (str): + Output only. The campaign the search term + served in. + + This field is a member of `oneof`_ ``_campaign``. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + search_term: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + campaign: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/campaign_shared_set.py b/google/ads/googleads/v23/resources/types/campaign_shared_set.py similarity index 92% rename from google/ads/googleads/v19/resources/types/campaign_shared_set.py rename to google/ads/googleads/v23/resources/types/campaign_shared_set.py index a4060efaf..adbe3c523 100644 --- a/google/ads/googleads/v19/resources/types/campaign_shared_set.py +++ b/google/ads/googleads/v23/resources/types/campaign_shared_set.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import campaign_shared_set_status +from google.ads.googleads.v23.enums.types import campaign_shared_set_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignSharedSet", }, @@ -60,7 +60,7 @@ class CampaignSharedSet(proto.Message): associated with Display mobile app campaigns. This field is a member of `oneof`_ ``_shared_set``. - status (google.ads.googleads.v19.enums.types.CampaignSharedSetStatusEnum.CampaignSharedSetStatus): + status (google.ads.googleads.v23.enums.types.CampaignSharedSetStatusEnum.CampaignSharedSetStatus): Output only. The status of this campaign shared set. Read only. """ diff --git a/google/ads/googleads/v19/resources/types/campaign_simulation.py b/google/ads/googleads/v23/resources/types/campaign_simulation.py similarity index 79% rename from google/ads/googleads/v19/resources/types/campaign_simulation.py rename to google/ads/googleads/v23/resources/types/campaign_simulation.py index ca84883a0..0fef716f0 100644 --- a/google/ads/googleads/v19/resources/types/campaign_simulation.py +++ b/google/ads/googleads/v23/resources/types/campaign_simulation.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import simulation -from google.ads.googleads.v19.enums.types import simulation_modification_method -from google.ads.googleads.v19.enums.types import simulation_type +from google.ads.googleads.v23.common.types import simulation +from google.ads.googleads.v23.enums.types import simulation_modification_method +from google.ads.googleads.v23.enums.types import simulation_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CampaignSimulation", }, @@ -37,22 +37,22 @@ class CampaignSimulation(proto.Message): type, simulation type and simulation modification method is detailed below respectively. - - SEARCH - CPC_BID - UNIFORM - - SEARCH - CPC_BID - SCALING - - SEARCH - TARGET_CPA - UNIFORM - - SEARCH - TARGET_CPA - SCALING - - SEARCH - TARGET_ROAS - UNIFORM - - SEARCH - TARGET_IMPRESSION_SHARE - UNIFORM - - SEARCH - BUDGET - UNIFORM - - SHOPPING - BUDGET - UNIFORM - - SHOPPING - TARGET_ROAS - UNIFORM - - MULTI_CHANNEL - TARGET_CPA - UNIFORM - - MULTI_CHANNEL - TARGET_ROAS - UNIFORM - - DEMAND_GEN - TARGET_CPA - DEFAULT - - DISPLAY - TARGET_CPA - UNIFORM - - PERFORMANCE_MAX - TARGET_CPA - UNIFORM - - PERFORMANCE_MAX - TARGET_ROAS - UNIFORM - - PERFORMANCE_MAX - BUDGET - UNIFORM + - SEARCH - CPC_BID - UNIFORM + - SEARCH - CPC_BID - SCALING + - SEARCH - TARGET_CPA - UNIFORM + - SEARCH - TARGET_CPA - SCALING + - SEARCH - TARGET_ROAS - UNIFORM + - SEARCH - TARGET_IMPRESSION_SHARE - UNIFORM + - SEARCH - BUDGET - UNIFORM + - SHOPPING - BUDGET - UNIFORM + - SHOPPING - TARGET_ROAS - UNIFORM + - MULTI_CHANNEL - TARGET_CPA - UNIFORM + - MULTI_CHANNEL - TARGET_ROAS - UNIFORM + - DEMAND_GEN - TARGET_CPA - DEFAULT + - DISPLAY - TARGET_CPA - UNIFORM + - PERFORMANCE_MAX - TARGET_CPA - UNIFORM + - PERFORMANCE_MAX - TARGET_ROAS - UNIFORM + - PERFORMANCE_MAX - BUDGET - UNIFORM This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -69,10 +69,10 @@ class CampaignSimulation(proto.Message): ``customers/{customer_id}/campaignSimulations/{campaign_id}~{type}~{modification_method}~{start_date}~{end_date}`` campaign_id (int): Output only. Campaign id of the simulation. - type_ (google.ads.googleads.v19.enums.types.SimulationTypeEnum.SimulationType): + type_ (google.ads.googleads.v23.enums.types.SimulationTypeEnum.SimulationType): Output only. The field that the simulation modifies. - modification_method (google.ads.googleads.v19.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): + modification_method (google.ads.googleads.v23.enums.types.SimulationModificationMethodEnum.SimulationModificationMethod): Output only. How the simulation modifies the field. start_date (str): @@ -81,27 +81,27 @@ class CampaignSimulation(proto.Message): end_date (str): Output only. Last day on which the simulation is based, in YYYY-MM-DD format - cpc_bid_point_list (google.ads.googleads.v19.common.types.CpcBidSimulationPointList): + cpc_bid_point_list (google.ads.googleads.v23.common.types.CpcBidSimulationPointList): Output only. Simulation points if the simulation type is CPC_BID. This field is a member of `oneof`_ ``point_list``. - target_cpa_point_list (google.ads.googleads.v19.common.types.TargetCpaSimulationPointList): + target_cpa_point_list (google.ads.googleads.v23.common.types.TargetCpaSimulationPointList): Output only. Simulation points if the simulation type is TARGET_CPA. This field is a member of `oneof`_ ``point_list``. - target_roas_point_list (google.ads.googleads.v19.common.types.TargetRoasSimulationPointList): + target_roas_point_list (google.ads.googleads.v23.common.types.TargetRoasSimulationPointList): Output only. Simulation points if the simulation type is TARGET_ROAS. This field is a member of `oneof`_ ``point_list``. - target_impression_share_point_list (google.ads.googleads.v19.common.types.TargetImpressionShareSimulationPointList): + target_impression_share_point_list (google.ads.googleads.v23.common.types.TargetImpressionShareSimulationPointList): Output only. Simulation points if the simulation type is TARGET_IMPRESSION_SHARE. This field is a member of `oneof`_ ``point_list``. - budget_point_list (google.ads.googleads.v19.common.types.BudgetSimulationPointList): + budget_point_list (google.ads.googleads.v23.common.types.BudgetSimulationPointList): Output only. Simulation points if the simulation type is BUDGET. diff --git a/google/ads/googleads/v19/resources/types/carrier_constant.py b/google/ads/googleads/v23/resources/types/carrier_constant.py similarity index 95% rename from google/ads/googleads/v19/resources/types/carrier_constant.py rename to google/ads/googleads/v23/resources/types/carrier_constant.py index fc9d42925..e7930b819 100644 --- a/google/ads/googleads/v19/resources/types/carrier_constant.py +++ b/google/ads/googleads/v23/resources/types/carrier_constant.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CarrierConstant", }, diff --git a/google/ads/googleads/v19/resources/types/change_event.py b/google/ads/googleads/v23/resources/types/change_event.py similarity index 80% rename from google/ads/googleads/v19/resources/types/change_event.py rename to google/ads/googleads/v23/resources/types/change_event.py index a96ce8339..ae68fe683 100644 --- a/google/ads/googleads/v19/resources/types/change_event.py +++ b/google/ads/googleads/v23/resources/types/change_event.py @@ -18,52 +18,52 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import change_client_type -from google.ads.googleads.v19.enums.types import change_event_resource_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import change_client_type +from google.ads.googleads.v23.enums.types import change_event_resource_type +from google.ads.googleads.v23.enums.types import ( resource_change_operation as gage_resource_change_operation, ) -from google.ads.googleads.v19.resources.types import ad as gagr_ad -from google.ads.googleads.v19.resources.types import ad_group as gagr_ad_group -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ad as gagr_ad +from google.ads.googleads.v23.resources.types import ad_group as gagr_ad_group +from google.ads.googleads.v23.resources.types import ( ad_group_ad as gagr_ad_group_ad, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_asset as gagr_ad_group_asset, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_bid_modifier as gagr_ad_group_bid_modifier, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_criterion as gagr_ad_group_criterion, ) -from google.ads.googleads.v19.resources.types import asset as gagr_asset -from google.ads.googleads.v19.resources.types import asset_set as gagr_asset_set -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import asset as gagr_asset +from google.ads.googleads.v23.resources.types import asset_set as gagr_asset_set +from google.ads.googleads.v23.resources.types import ( asset_set_asset as gagr_asset_set_asset, ) -from google.ads.googleads.v19.resources.types import campaign as gagr_campaign -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import campaign as gagr_campaign +from google.ads.googleads.v23.resources.types import ( campaign_asset as gagr_campaign_asset, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_asset_set as gagr_campaign_asset_set, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_budget as gagr_campaign_budget, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_criterion as gagr_campaign_criterion, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_asset as gagr_customer_asset, ) from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ChangeEvent", }, @@ -86,25 +86,25 @@ class ChangeEvent(proto.Message): change_date_time (str): Output only. Time at which the change was committed on this resource. - change_resource_type (google.ads.googleads.v19.enums.types.ChangeEventResourceTypeEnum.ChangeEventResourceType): + change_resource_type (google.ads.googleads.v23.enums.types.ChangeEventResourceTypeEnum.ChangeEventResourceType): Output only. The type of the changed resource. This dictates what resource will be set in old_resource and new_resource. change_resource_name (str): Output only. The Simply resource this change occurred on. - client_type (google.ads.googleads.v19.enums.types.ChangeClientTypeEnum.ChangeClientType): + client_type (google.ads.googleads.v23.enums.types.ChangeClientTypeEnum.ChangeClientType): Output only. Where the change was made through. user_email (str): Output only. The email of the user who made this change. - old_resource (google.ads.googleads.v19.resources.types.ChangeEvent.ChangedResource): + old_resource (google.ads.googleads.v23.resources.types.ChangeEvent.ChangedResource): Output only. The old resource before the change. Only changed fields will be populated. - new_resource (google.ads.googleads.v19.resources.types.ChangeEvent.ChangedResource): + new_resource (google.ads.googleads.v23.resources.types.ChangeEvent.ChangedResource): Output only. The new resource after the change. Only changed fields will be populated. - resource_change_operation (google.ads.googleads.v19.enums.types.ResourceChangeOperationEnum.ResourceChangeOperation): + resource_change_operation (google.ads.googleads.v23.enums.types.ResourceChangeOperationEnum.ResourceChangeOperation): Output only. The operation on the changed resource. changed_fields (google.protobuf.field_mask_pb2.FieldMask): @@ -126,38 +126,38 @@ class ChangedResource(proto.Message): resource of the change_resource_type will be set. Attributes: - ad (google.ads.googleads.v19.resources.types.Ad): + ad (google.ads.googleads.v23.resources.types.Ad): Output only. Set if change_resource_type == AD. - ad_group (google.ads.googleads.v19.resources.types.AdGroup): + ad_group (google.ads.googleads.v23.resources.types.AdGroup): Output only. Set if change_resource_type == AD_GROUP. - ad_group_criterion (google.ads.googleads.v19.resources.types.AdGroupCriterion): + ad_group_criterion (google.ads.googleads.v23.resources.types.AdGroupCriterion): Output only. Set if change_resource_type == AD_GROUP_CRITERION. - campaign (google.ads.googleads.v19.resources.types.Campaign): + campaign (google.ads.googleads.v23.resources.types.Campaign): Output only. Set if change_resource_type == CAMPAIGN. - campaign_budget (google.ads.googleads.v19.resources.types.CampaignBudget): + campaign_budget (google.ads.googleads.v23.resources.types.CampaignBudget): Output only. Set if change_resource_type == CAMPAIGN_BUDGET. - ad_group_bid_modifier (google.ads.googleads.v19.resources.types.AdGroupBidModifier): + ad_group_bid_modifier (google.ads.googleads.v23.resources.types.AdGroupBidModifier): Output only. Set if change_resource_type == AD_GROUP_BID_MODIFIER. - campaign_criterion (google.ads.googleads.v19.resources.types.CampaignCriterion): + campaign_criterion (google.ads.googleads.v23.resources.types.CampaignCriterion): Output only. Set if change_resource_type == CAMPAIGN_CRITERION. - ad_group_ad (google.ads.googleads.v19.resources.types.AdGroupAd): + ad_group_ad (google.ads.googleads.v23.resources.types.AdGroupAd): Output only. Set if change_resource_type == AD_GROUP_AD. - asset (google.ads.googleads.v19.resources.types.Asset): + asset (google.ads.googleads.v23.resources.types.Asset): Output only. Set if change_resource_type == ASSET. - customer_asset (google.ads.googleads.v19.resources.types.CustomerAsset): + customer_asset (google.ads.googleads.v23.resources.types.CustomerAsset): Output only. Set if change_resource_type == CUSTOMER_ASSET. - campaign_asset (google.ads.googleads.v19.resources.types.CampaignAsset): + campaign_asset (google.ads.googleads.v23.resources.types.CampaignAsset): Output only. Set if change_resource_type == CAMPAIGN_ASSET. - ad_group_asset (google.ads.googleads.v19.resources.types.AdGroupAsset): + ad_group_asset (google.ads.googleads.v23.resources.types.AdGroupAsset): Output only. Set if change_resource_type == AD_GROUP_ASSET. - asset_set (google.ads.googleads.v19.resources.types.AssetSet): + asset_set (google.ads.googleads.v23.resources.types.AssetSet): Output only. Set if change_resource_type == ASSET_SET. - asset_set_asset (google.ads.googleads.v19.resources.types.AssetSetAsset): + asset_set_asset (google.ads.googleads.v23.resources.types.AssetSetAsset): Output only. Set if change_resource_type == ASSET_SET_ASSET. - campaign_asset_set (google.ads.googleads.v19.resources.types.CampaignAssetSet): + campaign_asset_set (google.ads.googleads.v23.resources.types.CampaignAssetSet): Output only. Set if change_resource_type == CAMPAIGN_ASSET_SET. """ diff --git a/google/ads/googleads/v19/resources/types/change_status.py b/google/ads/googleads/v23/resources/types/change_status.py similarity index 89% rename from google/ads/googleads/v19/resources/types/change_status.py rename to google/ads/googleads/v23/resources/types/change_status.py index 7ea48051a..100bca62d 100644 --- a/google/ads/googleads/v19/resources/types/change_status.py +++ b/google/ads/googleads/v23/resources/types/change_status.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import change_status_operation -from google.ads.googleads.v19.enums.types import change_status_resource_type +from google.ads.googleads.v23.enums.types import change_status_operation +from google.ads.googleads.v23.enums.types import change_status_resource_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ChangeStatus", }, @@ -49,7 +49,7 @@ class ChangeStatus(proto.Message): change has occurred on this resource. This field is a member of `oneof`_ ``_last_change_date_time``. - resource_type (google.ads.googleads.v19.enums.types.ChangeStatusResourceTypeEnum.ChangeStatusResourceType): + resource_type (google.ads.googleads.v23.enums.types.ChangeStatusResourceTypeEnum.ChangeStatusResourceType): Output only. Represents the type of the changed resource. This dictates what fields will be set. For example, for AD_GROUP, campaign and ad_group fields will be set. @@ -63,7 +63,7 @@ class ChangeStatus(proto.Message): change. This field is a member of `oneof`_ ``_ad_group``. - resource_status (google.ads.googleads.v19.enums.types.ChangeStatusOperationEnum.ChangeStatusOperation): + resource_status (google.ads.googleads.v23.enums.types.ChangeStatusOperationEnum.ChangeStatusOperation): Output only. Represents the status of the changed resource. ad_group_ad (str): @@ -110,9 +110,15 @@ class ChangeStatus(proto.Message): asset_group (str): Output only. The AssetGroup affected by this change. + asset_set (str): + Output only. The AssetSet affected by this + change. campaign_budget (str): Output only. The CampaignBudget affected by this change. + campaign_asset_set (str): + Output only. The CampaignAssetSet affected by + this change. """ resource_name: str = proto.Field( @@ -200,10 +206,18 @@ class ChangeStatus(proto.Message): proto.STRING, number=41, ) + asset_set: str = proto.Field( + proto.STRING, + number=43, + ) campaign_budget: str = proto.Field( proto.STRING, number=42, ) + campaign_asset_set: str = proto.Field( + proto.STRING, + number=44, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/channel_aggregate_asset_view.py b/google/ads/googleads/v23/resources/types/channel_aggregate_asset_view.py similarity index 87% rename from google/ads/googleads/v19/resources/types/channel_aggregate_asset_view.py rename to google/ads/googleads/v23/resources/types/channel_aggregate_asset_view.py index bf5b2608e..a15d7f369 100644 --- a/google/ads/googleads/v19/resources/types/channel_aggregate_asset_view.py +++ b/google/ads/googleads/v23/resources/types/channel_aggregate_asset_view.py @@ -18,18 +18,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( advertising_channel_type as gage_advertising_channel_type, ) -from google.ads.googleads.v19.enums.types import asset_field_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import asset_field_type +from google.ads.googleads.v23.enums.types import ( asset_source as gage_asset_source, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ChannelAggregateAssetView", }, @@ -50,7 +50,7 @@ class ChannelAggregateAssetView(proto.Message): the form: ``customers/{customer_id}/channelAggregateAssetViews/{ChannelAssetV2.advertising_channel_type}~{ChannelAssetV2.asset_id}~{ChannelAssetV2.asset_source}~{ChannelAssetV2.field_type}"`` - advertising_channel_type (google.ads.googleads.v19.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): + advertising_channel_type (google.ads.googleads.v23.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): Output only. Channel in which the asset served. @@ -59,11 +59,11 @@ class ChannelAggregateAssetView(proto.Message): Output only. The ID of the asset. This field is a member of `oneof`_ ``_asset``. - asset_source (google.ads.googleads.v19.enums.types.AssetSourceEnum.AssetSource): + asset_source (google.ads.googleads.v23.enums.types.AssetSourceEnum.AssetSource): Output only. Source of the asset link. This field is a member of `oneof`_ ``_asset_source``. - field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): Output only. FieldType of the asset. This field is a member of `oneof`_ ``_field_type``. diff --git a/google/ads/googleads/v19/resources/types/click_view.py b/google/ads/googleads/v23/resources/types/click_view.py similarity index 88% rename from google/ads/googleads/v19/resources/types/click_view.py rename to google/ads/googleads/v23/resources/types/click_view.py index b61821999..72afb5333 100644 --- a/google/ads/googleads/v19/resources/types/click_view.py +++ b/google/ads/googleads/v23/resources/types/click_view.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import click_location -from google.ads.googleads.v19.common.types import criteria +from google.ads.googleads.v23.common.types import click_location +from google.ads.googleads.v23.common.types import criteria __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ClickView", }, @@ -39,6 +39,9 @@ class ClickView(proto.Message): filter limiting the results to one day and can be requested for dates back to 90 days before the time of the request. + GCLIDs are not available in this report for App Campaigns for + Installs (ACi) and App Campaigns for Pre-registration (ACpre). + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -52,11 +55,11 @@ class ClickView(proto.Message): Output only. The Google Click ID. This field is a member of `oneof`_ ``_gclid``. - area_of_interest (google.ads.googleads.v19.common.types.ClickLocation): + area_of_interest (google.ads.googleads.v23.common.types.ClickLocation): Output only. The location criteria matching the area of interest associated with the impression. - location_of_presence (google.ads.googleads.v19.common.types.ClickLocation): + location_of_presence (google.ads.googleads.v23.common.types.ClickLocation): Output only. The location criteria matching the location of presence associated with the impression. @@ -83,7 +86,7 @@ class ClickView(proto.Message): Output only. The associated keyword, if one exists and the click corresponds to the SEARCH channel. - keyword_info (google.ads.googleads.v19.common.types.KeywordInfo): + keyword_info (google.ads.googleads.v23.common.types.KeywordInfo): Output only. Basic information about the associated keyword, if it exists. """ diff --git a/google/ads/googleads/v19/resources/types/combined_audience.py b/google/ads/googleads/v23/resources/types/combined_audience.py similarity index 91% rename from google/ads/googleads/v19/resources/types/combined_audience.py rename to google/ads/googleads/v23/resources/types/combined_audience.py index e890a73de..800080747 100644 --- a/google/ads/googleads/v19/resources/types/combined_audience.py +++ b/google/ads/googleads/v23/resources/types/combined_audience.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import combined_audience_status +from google.ads.googleads.v23.enums.types import combined_audience_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CombinedAudience", }, @@ -42,7 +42,7 @@ class CombinedAudience(proto.Message): ``customers/{customer_id}/combinedAudience/{combined_audience_id}`` id (int): Output only. ID of the combined audience. - status (google.ads.googleads.v19.enums.types.CombinedAudienceStatusEnum.CombinedAudienceStatus): + status (google.ads.googleads.v23.enums.types.CombinedAudienceStatusEnum.CombinedAudienceStatus): Output only. Status of this combined audience. Indicates whether the combined audience is enabled or removed. diff --git a/google/ads/googleads/v19/resources/types/content_criterion_view.py b/google/ads/googleads/v23/resources/types/content_criterion_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/content_criterion_view.py rename to google/ads/googleads/v23/resources/types/content_criterion_view.py index 5c8957182..8a3e919d3 100644 --- a/google/ads/googleads/v19/resources/types/content_criterion_view.py +++ b/google/ads/googleads/v23/resources/types/content_criterion_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ContentCriterionView", }, diff --git a/google/ads/googleads/v19/resources/types/conversion_action.py b/google/ads/googleads/v23/resources/types/conversion_action.py similarity index 90% rename from google/ads/googleads/v19/resources/types/conversion_action.py rename to google/ads/googleads/v23/resources/types/conversion_action.py index d8acbc290..791a7857f 100644 --- a/google/ads/googleads/v19/resources/types/conversion_action.py +++ b/google/ads/googleads/v23/resources/types/conversion_action.py @@ -19,26 +19,26 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import tag_snippet -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import tag_snippet +from google.ads.googleads.v23.enums.types import ( attribution_model as gage_attribution_model, ) -from google.ads.googleads.v19.enums.types import conversion_action_category -from google.ads.googleads.v19.enums.types import conversion_action_counting_type -from google.ads.googleads.v19.enums.types import conversion_action_status -from google.ads.googleads.v19.enums.types import conversion_action_type -from google.ads.googleads.v19.enums.types import conversion_origin -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import conversion_action_category +from google.ads.googleads.v23.enums.types import conversion_action_counting_type +from google.ads.googleads.v23.enums.types import conversion_action_status +from google.ads.googleads.v23.enums.types import conversion_action_type +from google.ads.googleads.v23.enums.types import conversion_origin +from google.ads.googleads.v23.enums.types import ( data_driven_model_status as gage_data_driven_model_status, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( mobile_app_vendor as gage_mobile_app_vendor, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ConversionAction", }, @@ -67,13 +67,13 @@ class ConversionAction(proto.Message): when creating new conversion actions. This field is a member of `oneof`_ ``_name``. - status (google.ads.googleads.v19.enums.types.ConversionActionStatusEnum.ConversionActionStatus): + status (google.ads.googleads.v23.enums.types.ConversionActionStatusEnum.ConversionActionStatus): The status of this conversion action for conversion event accrual. - type_ (google.ads.googleads.v19.enums.types.ConversionActionTypeEnum.ConversionActionType): + type_ (google.ads.googleads.v23.enums.types.ConversionActionTypeEnum.ConversionActionType): Immutable. The type of this conversion action. - origin (google.ads.googleads.v19.enums.types.ConversionOriginEnum.ConversionOrigin): + origin (google.ads.googleads.v23.enums.types.ConversionOriginEnum.ConversionOrigin): Output only. The conversion origin of this conversion action. primary_for_goal (bool): @@ -90,7 +90,7 @@ class ConversionAction(proto.Message): optional. This field is a member of `oneof`_ ``_primary_for_goal``. - category (google.ads.googleads.v19.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): + category (google.ads.googleads.v23.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): The category of conversions reported for this conversion action. owner_customer (str): @@ -116,16 +116,16 @@ class ConversionAction(proto.Message): an interaction. This field is a member of `oneof`_ ``_view_through_lookback_window_days``. - value_settings (google.ads.googleads.v19.resources.types.ConversionAction.ValueSettings): + value_settings (google.ads.googleads.v23.resources.types.ConversionAction.ValueSettings): Settings related to the value for conversion events associated with this conversion action. - counting_type (google.ads.googleads.v19.enums.types.ConversionActionCountingTypeEnum.ConversionActionCountingType): + counting_type (google.ads.googleads.v23.enums.types.ConversionActionCountingTypeEnum.ConversionActionCountingType): How to count conversion events for the conversion action. - attribution_model_settings (google.ads.googleads.v19.resources.types.ConversionAction.AttributionModelSettings): + attribution_model_settings (google.ads.googleads.v23.resources.types.ConversionAction.AttributionModelSettings): Settings related to this conversion action's attribution model. - tag_snippets (MutableSequence[google.ads.googleads.v19.common.types.TagSnippet]): + tag_snippets (MutableSequence[google.ads.googleads.v23.common.types.TagSnippet]): Output only. The snippets used for tracking conversions. phone_call_duration_seconds (int): @@ -141,16 +141,16 @@ class ConversionAction(proto.Message): App ID for an app conversion action. This field is a member of `oneof`_ ``_app_id``. - mobile_app_vendor (google.ads.googleads.v19.enums.types.MobileAppVendorEnum.MobileAppVendor): + mobile_app_vendor (google.ads.googleads.v23.enums.types.MobileAppVendorEnum.MobileAppVendor): Output only. Mobile app vendor for an app conversion action. - firebase_settings (google.ads.googleads.v19.resources.types.ConversionAction.FirebaseSettings): + firebase_settings (google.ads.googleads.v23.resources.types.ConversionAction.FirebaseSettings): Output only. Firebase settings for Firebase conversion types. - third_party_app_analytics_settings (google.ads.googleads.v19.resources.types.ConversionAction.ThirdPartyAppAnalyticsSettings): + third_party_app_analytics_settings (google.ads.googleads.v23.resources.types.ConversionAction.ThirdPartyAppAnalyticsSettings): Output only. Third Party App Analytics settings for third party conversion types. - google_analytics_4_settings (google.ads.googleads.v19.resources.types.ConversionAction.GoogleAnalytics4Settings): + google_analytics_4_settings (google.ads.googleads.v23.resources.types.ConversionAction.GoogleAnalytics4Settings): Output only. Google Analytics 4 settings for Google Analytics 4 conversion types. """ @@ -160,10 +160,10 @@ class AttributionModelSettings(proto.Message): model. Attributes: - attribution_model (google.ads.googleads.v19.enums.types.AttributionModelEnum.AttributionModel): + attribution_model (google.ads.googleads.v23.enums.types.AttributionModelEnum.AttributionModel): The attribution model type of this conversion action. - data_driven_model_status (google.ads.googleads.v19.enums.types.DataDrivenModelStatusEnum.DataDrivenModelStatus): + data_driven_model_status (google.ads.googleads.v23.enums.types.DataDrivenModelStatusEnum.DataDrivenModelStatus): Output only. The status of the data-driven attribution model for the conversion action. """ diff --git a/google/ads/googleads/v19/resources/types/conversion_custom_variable.py b/google/ads/googleads/v23/resources/types/conversion_custom_variable.py similarity index 94% rename from google/ads/googleads/v19/resources/types/conversion_custom_variable.py rename to google/ads/googleads/v23/resources/types/conversion_custom_variable.py index fe14da524..83ce2c89f 100644 --- a/google/ads/googleads/v19/resources/types/conversion_custom_variable.py +++ b/google/ads/googleads/v23/resources/types/conversion_custom_variable.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( conversion_custom_variable_status, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ConversionCustomVariable", }, @@ -63,7 +63,7 @@ class ConversionCustomVariable(proto.Message): There should not be any extra spaces before and after. Currently only lowercase letters, numbers and underscores are allowed in the tag. - status (google.ads.googleads.v19.enums.types.ConversionCustomVariableStatusEnum.ConversionCustomVariableStatus): + status (google.ads.googleads.v23.enums.types.ConversionCustomVariableStatusEnum.ConversionCustomVariableStatus): The status of the conversion custom variable for conversion event accrual. owner_customer (str): diff --git a/google/ads/googleads/v19/resources/types/conversion_goal_campaign_config.py b/google/ads/googleads/v23/resources/types/conversion_goal_campaign_config.py similarity index 91% rename from google/ads/googleads/v19/resources/types/conversion_goal_campaign_config.py rename to google/ads/googleads/v23/resources/types/conversion_goal_campaign_config.py index e5eb57ab3..bf48764a8 100644 --- a/google/ads/googleads/v19/resources/types/conversion_goal_campaign_config.py +++ b/google/ads/googleads/v23/resources/types/conversion_goal_campaign_config.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( goal_config_level as gage_goal_config_level, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ConversionGoalCampaignConfig", }, @@ -45,7 +45,7 @@ class ConversionGoalCampaignConfig(proto.Message): campaign (str): Immutable. The campaign with which this conversion goal campaign config is associated. - goal_config_level (google.ads.googleads.v19.enums.types.GoalConfigLevelEnum.GoalConfigLevel): + goal_config_level (google.ads.googleads.v23.enums.types.GoalConfigLevelEnum.GoalConfigLevel): The level of goal config the campaign is using. custom_conversion_goal (str): diff --git a/google/ads/googleads/v19/resources/types/conversion_value_rule.py b/google/ads/googleads/v23/resources/types/conversion_value_rule.py similarity index 90% rename from google/ads/googleads/v19/resources/types/conversion_value_rule.py rename to google/ads/googleads/v23/resources/types/conversion_value_rule.py index fd99469a7..63aa55997 100644 --- a/google/ads/googleads/v19/resources/types/conversion_value_rule.py +++ b/google/ads/googleads/v23/resources/types/conversion_value_rule.py @@ -19,17 +19,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import conversion_value_rule_status -from google.ads.googleads.v19.enums.types import value_rule_device_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import conversion_value_rule_status +from google.ads.googleads.v23.enums.types import value_rule_device_type +from google.ads.googleads.v23.enums.types import ( value_rule_geo_location_match_type, ) -from google.ads.googleads.v19.enums.types import value_rule_operation +from google.ads.googleads.v23.enums.types import value_rule_operation __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ConversionValueRule", }, @@ -48,18 +48,18 @@ class ConversionValueRule(proto.Message): id (int): Output only. The ID of the conversion value rule. - action (google.ads.googleads.v19.resources.types.ConversionValueRule.ValueRuleAction): + action (google.ads.googleads.v23.resources.types.ConversionValueRule.ValueRuleAction): Action applied when the rule is triggered. - geo_location_condition (google.ads.googleads.v19.resources.types.ConversionValueRule.ValueRuleGeoLocationCondition): + geo_location_condition (google.ads.googleads.v23.resources.types.ConversionValueRule.ValueRuleGeoLocationCondition): Condition for Geo location that must be satisfied for the value rule to apply. - device_condition (google.ads.googleads.v19.resources.types.ConversionValueRule.ValueRuleDeviceCondition): + device_condition (google.ads.googleads.v23.resources.types.ConversionValueRule.ValueRuleDeviceCondition): Condition for device type that must be satisfied for the value rule to apply. - audience_condition (google.ads.googleads.v19.resources.types.ConversionValueRule.ValueRuleAudienceCondition): + audience_condition (google.ads.googleads.v23.resources.types.ConversionValueRule.ValueRuleAudienceCondition): Condition for audience that must be satisfied for the value rule to apply. - itinerary_condition (google.ads.googleads.v19.resources.types.ConversionValueRule.ValueRuleItineraryCondition): + itinerary_condition (google.ads.googleads.v23.resources.types.ConversionValueRule.ValueRuleItineraryCondition): Condition for itinerary that must be satisfied for the value rule to apply. owner_customer (str): @@ -69,7 +69,7 @@ class ConversionValueRule(proto.Message): of the manager whereas the customer in the resource_name will be of the requesting serving customer. \*\* Read-only \*\* - status (google.ads.googleads.v19.enums.types.ConversionValueRuleStatusEnum.ConversionValueRuleStatus): + status (google.ads.googleads.v23.enums.types.ConversionValueRuleStatusEnum.ConversionValueRuleStatus): The status of the conversion value rule. """ @@ -77,7 +77,7 @@ class ValueRuleAction(proto.Message): r"""Action applied when rule is applied. Attributes: - operation (google.ads.googleads.v19.enums.types.ValueRuleOperationEnum.ValueRuleOperation): + operation (google.ads.googleads.v23.enums.types.ValueRuleOperationEnum.ValueRuleOperation): Specifies applied operation. value (float): Specifies applied value. @@ -102,12 +102,12 @@ class ValueRuleGeoLocationCondition(proto.Message): excluded_geo_target_constants (MutableSequence[str]): Geo locations that advertisers want to exclude. - excluded_geo_match_type (google.ads.googleads.v19.enums.types.ValueRuleGeoLocationMatchTypeEnum.ValueRuleGeoLocationMatchType): + excluded_geo_match_type (google.ads.googleads.v23.enums.types.ValueRuleGeoLocationMatchTypeEnum.ValueRuleGeoLocationMatchType): Excluded Geo location match type. geo_target_constants (MutableSequence[str]): Geo locations that advertisers want to include. - geo_match_type (google.ads.googleads.v19.enums.types.ValueRuleGeoLocationMatchTypeEnum.ValueRuleGeoLocationMatchType): + geo_match_type (google.ads.googleads.v23.enums.types.ValueRuleGeoLocationMatchTypeEnum.ValueRuleGeoLocationMatchType): Included Geo location match type. """ @@ -140,7 +140,7 @@ class ValueRuleDeviceCondition(proto.Message): r"""Condition on Device dimension. Attributes: - device_types (MutableSequence[google.ads.googleads.v19.enums.types.ValueRuleDeviceTypeEnum.ValueRuleDeviceType]): + device_types (MutableSequence[google.ads.googleads.v23.enums.types.ValueRuleDeviceTypeEnum.ValueRuleDeviceType]): Value for device type condition. """ @@ -175,13 +175,13 @@ class ValueRuleItineraryCondition(proto.Message): r"""Condition on Itinerary dimension. Attributes: - advance_booking_window (google.ads.googleads.v19.resources.types.ConversionValueRule.ValueRuleItineraryAdvanceBookingWindow): + advance_booking_window (google.ads.googleads.v23.resources.types.ConversionValueRule.ValueRuleItineraryAdvanceBookingWindow): Range for the number of days between the date of the booking and the start of the itinerary. - travel_length (google.ads.googleads.v19.resources.types.ConversionValueRule.ValueRuleItineraryTravelLength): + travel_length (google.ads.googleads.v23.resources.types.ConversionValueRule.ValueRuleItineraryTravelLength): Range for the itinerary length in number of nights. - travel_start_day (google.ads.googleads.v19.resources.types.ConversionValueRule.ValueRuleItineraryTravelStartDay): + travel_start_day (google.ads.googleads.v23.resources.types.ConversionValueRule.ValueRuleItineraryTravelStartDay): The days of the week on which this itinerary's travel can start. """ diff --git a/google/ads/googleads/v19/resources/types/conversion_value_rule_set.py b/google/ads/googleads/v23/resources/types/conversion_value_rule_set.py similarity index 85% rename from google/ads/googleads/v19/resources/types/conversion_value_rule_set.py rename to google/ads/googleads/v23/resources/types/conversion_value_rule_set.py index 6a4f4969f..3d9aa86c8 100644 --- a/google/ads/googleads/v19/resources/types/conversion_value_rule_set.py +++ b/google/ads/googleads/v23/resources/types/conversion_value_rule_set.py @@ -19,17 +19,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import conversion_action_category -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import conversion_action_category +from google.ads.googleads.v23.enums.types import ( conversion_value_rule_set_status, ) -from google.ads.googleads.v19.enums.types import value_rule_set_attachment_type -from google.ads.googleads.v19.enums.types import value_rule_set_dimension +from google.ads.googleads.v23.enums.types import value_rule_set_attachment_type +from google.ads.googleads.v23.enums.types import value_rule_set_dimension __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ConversionValueRuleSet", }, @@ -37,7 +37,9 @@ class ConversionValueRuleSet(proto.Message): - r"""A conversion value rule set + r"""A conversion value rule set is a collection of conversion value + rules that lets you adjust conversion values based on the dimensions + specified in the ``dimensions`` field. Attributes: resource_name (str): @@ -50,7 +52,7 @@ class ConversionValueRuleSet(proto.Message): rule set. conversion_value_rules (MutableSequence[str]): Resource names of rules within the rule set. - dimensions (MutableSequence[google.ads.googleads.v19.enums.types.ValueRuleSetDimensionEnum.ValueRuleSetDimension]): + dimensions (MutableSequence[google.ads.googleads.v23.enums.types.ValueRuleSetDimensionEnum.ValueRuleSetDimension]): Defines dimensions for Value Rule conditions. The condition types of value rules within this value rule set must be of these dimensions. The @@ -67,17 +69,17 @@ class ConversionValueRuleSet(proto.Message): name of the manager whereas the customer in the resource_name will be of the requesting serving customer. \*\* Read-only \*\* - attachment_type (google.ads.googleads.v19.enums.types.ValueRuleSetAttachmentTypeEnum.ValueRuleSetAttachmentType): + attachment_type (google.ads.googleads.v23.enums.types.ValueRuleSetAttachmentTypeEnum.ValueRuleSetAttachmentType): Immutable. Defines the scope where the conversion value rule set is attached. campaign (str): The resource name of the campaign when the conversion value rule set is attached to a campaign. - status (google.ads.googleads.v19.enums.types.ConversionValueRuleSetStatusEnum.ConversionValueRuleSetStatus): + status (google.ads.googleads.v23.enums.types.ConversionValueRuleSetStatusEnum.ConversionValueRuleSetStatus): Output only. The status of the conversion value rule set. \*\* Read-only \*\* - conversion_action_categories (MutableSequence[google.ads.googleads.v19.enums.types.ConversionActionCategoryEnum.ConversionActionCategory]): + conversion_action_categories (MutableSequence[google.ads.googleads.v23.enums.types.ConversionActionCategoryEnum.ConversionActionCategory]): Immutable. The conversion action categories of the conversion value rule set. """ diff --git a/google/ads/googleads/v19/resources/types/currency_constant.py b/google/ads/googleads/v23/resources/types/currency_constant.py similarity index 96% rename from google/ads/googleads/v19/resources/types/currency_constant.py rename to google/ads/googleads/v23/resources/types/currency_constant.py index 9535806a9..62bbc469a 100644 --- a/google/ads/googleads/v19/resources/types/currency_constant.py +++ b/google/ads/googleads/v23/resources/types/currency_constant.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CurrencyConstant", }, diff --git a/google/ads/googleads/v19/resources/types/custom_audience.py b/google/ads/googleads/v23/resources/types/custom_audience.py similarity index 91% rename from google/ads/googleads/v19/resources/types/custom_audience.py rename to google/ads/googleads/v23/resources/types/custom_audience.py index d23700b9e..e02c2ad44 100644 --- a/google/ads/googleads/v19/resources/types/custom_audience.py +++ b/google/ads/googleads/v23/resources/types/custom_audience.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import custom_audience_member_type -from google.ads.googleads.v19.enums.types import custom_audience_status -from google.ads.googleads.v19.enums.types import custom_audience_type +from google.ads.googleads.v23.enums.types import custom_audience_member_type +from google.ads.googleads.v23.enums.types import custom_audience_status +from google.ads.googleads.v23.enums.types import custom_audience_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomAudience", "CustomAudienceMember", @@ -48,7 +48,7 @@ class CustomAudience(proto.Message): ``customers/{customer_id}/customAudiences/{custom_audience_id}`` id (int): Output only. ID of the custom audience. - status (google.ads.googleads.v19.enums.types.CustomAudienceStatusEnum.CustomAudienceStatus): + status (google.ads.googleads.v23.enums.types.CustomAudienceStatusEnum.CustomAudienceStatus): Output only. Status of this custom audience. Indicates whether the custom audience is enabled or removed. @@ -57,13 +57,13 @@ class CustomAudience(proto.Message): unique for all custom audiences created by a customer. This field is required for creating operations. - type_ (google.ads.googleads.v19.enums.types.CustomAudienceTypeEnum.CustomAudienceType): + type_ (google.ads.googleads.v23.enums.types.CustomAudienceTypeEnum.CustomAudienceType): Type of the custom audience. ("INTEREST" OR "PURCHASE_INTENT" is not allowed for newly created custom audience but kept for existing audiences) description (str): Description of this custom audience. - members (MutableSequence[google.ads.googleads.v19.resources.types.CustomAudienceMember]): + members (MutableSequence[google.ads.googleads.v23.resources.types.CustomAudienceMember]): List of custom audience members that this custom audience is composed of. Members can be added during CustomAudience creation. If members @@ -121,7 +121,7 @@ class CustomAudienceMember(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - member_type (google.ads.googleads.v19.enums.types.CustomAudienceMemberTypeEnum.CustomAudienceMemberType): + member_type (google.ads.googleads.v23.enums.types.CustomAudienceMemberTypeEnum.CustomAudienceMemberType): The type of custom audience member, KEYWORD, URL, PLACE_CATEGORY or APP. keyword (str): diff --git a/google/ads/googleads/v19/resources/types/custom_conversion_goal.py b/google/ads/googleads/v23/resources/types/custom_conversion_goal.py similarity index 91% rename from google/ads/googleads/v19/resources/types/custom_conversion_goal.py rename to google/ads/googleads/v23/resources/types/custom_conversion_goal.py index 4248088f5..34c27bab7 100644 --- a/google/ads/googleads/v19/resources/types/custom_conversion_goal.py +++ b/google/ads/googleads/v23/resources/types/custom_conversion_goal.py @@ -19,12 +19,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import custom_conversion_goal_status +from google.ads.googleads.v23.enums.types import custom_conversion_goal_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomConversionGoal", }, @@ -49,7 +49,7 @@ class CustomConversionGoal(proto.Message): conversion_actions (MutableSequence[str]): Conversion actions that the custom conversion goal makes biddable. - status (google.ads.googleads.v19.enums.types.CustomConversionGoalStatusEnum.CustomConversionGoalStatus): + status (google.ads.googleads.v23.enums.types.CustomConversionGoalStatusEnum.CustomConversionGoalStatus): The status of the custom conversion goal. """ diff --git a/google/ads/googleads/v19/resources/types/custom_interest.py b/google/ads/googleads/v23/resources/types/custom_interest.py similarity index 89% rename from google/ads/googleads/v19/resources/types/custom_interest.py rename to google/ads/googleads/v23/resources/types/custom_interest.py index a1f9a615a..5892d476d 100644 --- a/google/ads/googleads/v19/resources/types/custom_interest.py +++ b/google/ads/googleads/v23/resources/types/custom_interest.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import custom_interest_member_type -from google.ads.googleads.v19.enums.types import custom_interest_status -from google.ads.googleads.v19.enums.types import custom_interest_type +from google.ads.googleads.v23.enums.types import custom_interest_member_type +from google.ads.googleads.v23.enums.types import custom_interest_status +from google.ads.googleads.v23.enums.types import custom_interest_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomInterest", "CustomInterestMember", @@ -49,7 +49,7 @@ class CustomInterest(proto.Message): Output only. Id of the custom interest. This field is a member of `oneof`_ ``_id``. - status (google.ads.googleads.v19.enums.types.CustomInterestStatusEnum.CustomInterestStatus): + status (google.ads.googleads.v23.enums.types.CustomInterestStatusEnum.CustomInterestStatus): Status of this custom interest. Indicates whether the custom interest is enabled or removed. @@ -59,7 +59,7 @@ class CustomInterest(proto.Message): This field is required for create operations. This field is a member of `oneof`_ ``_name``. - type_ (google.ads.googleads.v19.enums.types.CustomInterestTypeEnum.CustomInterestType): + type_ (google.ads.googleads.v23.enums.types.CustomInterestTypeEnum.CustomInterestType): Type of the custom interest, CUSTOM_AFFINITY or CUSTOM_INTENT. By default the type is set to CUSTOM_AFFINITY. @@ -67,7 +67,7 @@ class CustomInterest(proto.Message): Description of this custom interest audience. This field is a member of `oneof`_ ``_description``. - members (MutableSequence[google.ads.googleads.v19.resources.types.CustomInterestMember]): + members (MutableSequence[google.ads.googleads.v23.resources.types.CustomInterestMember]): List of custom interest members that this custom interest is composed of. Members can be added during CustomInterest creation. If members @@ -124,7 +124,7 @@ class CustomInterestMember(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - member_type (google.ads.googleads.v19.enums.types.CustomInterestMemberTypeEnum.CustomInterestMemberType): + member_type (google.ads.googleads.v23.enums.types.CustomInterestMemberTypeEnum.CustomInterestMemberType): The type of custom interest member, KEYWORD or URL. parameter (str): diff --git a/google/ads/googleads/v19/resources/types/customer.py b/google/ads/googleads/v23/resources/types/customer.py similarity index 88% rename from google/ads/googleads/v19/resources/types/customer.py rename to google/ads/googleads/v23/resources/types/customer.py index c31990bcf..c24f53558 100644 --- a/google/ads/googleads/v19/resources/types/customer.py +++ b/google/ads/googleads/v23/resources/types/customer.py @@ -19,20 +19,23 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import brand_safety_suitability -from google.ads.googleads.v19.enums.types import conversion_tracking_status_enum -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import ( + third_party_integration_partners as gagc_third_party_integration_partners, +) +from google.ads.googleads.v23.enums.types import brand_safety_suitability +from google.ads.googleads.v23.enums.types import conversion_tracking_status_enum +from google.ads.googleads.v23.enums.types import ( customer_pay_per_conversion_eligibility_failure_reason, ) -from google.ads.googleads.v19.enums.types import customer_status -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import customer_status +from google.ads.googleads.v23.enums.types import ( local_services_verification_status, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "Customer", "CallReportingSetting", @@ -42,6 +45,7 @@ "LocalServicesSettings", "GranularLicenseStatus", "GranularInsuranceStatus", + "VideoCustomer", }, ) @@ -110,16 +114,15 @@ class Customer(proto.Message): account. This field is a member of `oneof`_ ``_test_account``. - call_reporting_setting (google.ads.googleads.v19.resources.types.CallReportingSetting): + call_reporting_setting (google.ads.googleads.v23.resources.types.CallReportingSetting): Call reporting setting for a customer. Only mutable in an ``update`` operation. - conversion_tracking_setting (google.ads.googleads.v19.resources.types.ConversionTrackingSetting): - Immutable. Conversion tracking setting for a - customer. - remarketing_setting (google.ads.googleads.v19.resources.types.RemarketingSetting): + conversion_tracking_setting (google.ads.googleads.v23.resources.types.ConversionTrackingSetting): + Conversion tracking setting for a customer. + remarketing_setting (google.ads.googleads.v23.resources.types.RemarketingSetting): Output only. Remarketing setting for a customer. - pay_per_conversion_eligibility_failure_reasons (MutableSequence[google.ads.googleads.v19.enums.types.CustomerPayPerConversionEligibilityFailureReasonEnum.CustomerPayPerConversionEligibilityFailureReason]): + pay_per_conversion_eligibility_failure_reasons (MutableSequence[google.ads.googleads.v23.enums.types.CustomerPayPerConversionEligibilityFailureReasonEnum.CustomerPayPerConversionEligibilityFailureReason]): Output only. Reasons why the customer is not eligible to use PaymentMode.CONVERSIONS. If the list is empty, the customer is eligible. This @@ -151,7 +154,7 @@ class Customer(proto.Message): non-manager customers. This field is read-only. - status (google.ads.googleads.v19.enums.types.CustomerStatusEnum.CustomerStatus): + status (google.ads.googleads.v23.enums.types.CustomerStatusEnum.CustomerStatus): Output only. The status of the customer. location_asset_auto_migration_done (bool): Output only. True if feed based location has @@ -175,18 +178,20 @@ class Customer(proto.Message): HH:mm:ss format. This field is a member of `oneof`_ ``_image_asset_auto_migration_done_date_time``. - customer_agreement_setting (google.ads.googleads.v19.resources.types.CustomerAgreementSetting): + customer_agreement_setting (google.ads.googleads.v23.resources.types.CustomerAgreementSetting): Output only. Customer Agreement Setting for a customer. - local_services_settings (google.ads.googleads.v19.resources.types.LocalServicesSettings): + local_services_settings (google.ads.googleads.v23.resources.types.LocalServicesSettings): Output only. Settings for Local Services customer. - video_brand_safety_suitability (google.ads.googleads.v19.enums.types.BrandSafetySuitabilityEnum.BrandSafetySuitability): - Output only. Brand Safety setting at the - account level. Allows for selecting an inventory - type to show your ads on content that is the - right fit for your brand. See + video_brand_safety_suitability (google.ads.googleads.v23.enums.types.BrandSafetySuitabilityEnum.BrandSafetySuitability): + Brand Safety setting at the account level. + Allows for selecting an inventory type to show + your ads on content that is the right fit for + your brand. See https://support.google.com/google-ads/answer/7515513. + video_customer (google.ads.googleads.v23.resources.types.VideoCustomer): + Video specific information about a Customer. """ resource_name: str = proto.Field( @@ -316,6 +321,11 @@ class Customer(proto.Message): number=46, enum=brand_safety_suitability.BrandSafetySuitabilityEnum.BrandSafetySuitability, ) + video_customer: "VideoCustomer" = proto.Field( + proto.MESSAGE, + number=54, + message="VideoCustomer", + ) class CallReportingSetting(proto.Message): @@ -392,7 +402,7 @@ class ConversionTrackingSetting(proto.Message): read-only. For more information, see https://support.google.com/adspolicy/answer/7475709. - conversion_tracking_status (google.ads.googleads.v19.enums.types.ConversionTrackingStatusEnum.ConversionTrackingStatus): + conversion_tracking_status (google.ads.googleads.v23.enums.types.ConversionTrackingStatusEnum.ConversionTrackingStatus): Output only. Conversion tracking status. It indicates whether the customer is using conversion tracking, and who is the conversion tracking owner of this customer. If this @@ -406,9 +416,9 @@ class ConversionTrackingSetting(proto.Message): inherited from the manager. This field is read-only. google_ads_conversion_customer (str): - Immutable. The resource name of the customer - where conversions are created and managed. This - field is read-only. + The resource name of the customer where + conversions are created and managed. This field + is read-only. """ conversion_tracking_id: int = proto.Field( @@ -480,10 +490,10 @@ class LocalServicesSettings(proto.Message): r"""Settings for Local Services customer. Attributes: - granular_license_statuses (MutableSequence[google.ads.googleads.v19.resources.types.GranularLicenseStatus]): + granular_license_statuses (MutableSequence[google.ads.googleads.v23.resources.types.GranularLicenseStatus]): Output only. A read-only list of geo vertical level license statuses. - granular_insurance_statuses (MutableSequence[google.ads.googleads.v19.resources.types.GranularInsuranceStatus]): + granular_insurance_statuses (MutableSequence[google.ads.googleads.v23.resources.types.GranularInsuranceStatus]): Output only. A read-only list of geo vertical level insurance statuses. """ @@ -526,7 +536,7 @@ class GranularLicenseStatus(proto.Message): https://developers.google.com/google-ads/api/data/codes-formats#local_services_ids This field is a member of `oneof`_ ``_category_id``. - verification_status (google.ads.googleads.v19.enums.types.LocalServicesVerificationStatusEnum.LocalServicesVerificationStatus): + verification_status (google.ads.googleads.v23.enums.types.LocalServicesVerificationStatusEnum.LocalServicesVerificationStatus): Output only. Granular license status, per geo + vertical. @@ -575,7 +585,7 @@ class GranularInsuranceStatus(proto.Message): https://developers.google.com/google-ads/api/data/codes-formats#local_services_ids This field is a member of `oneof`_ ``_category_id``. - verification_status (google.ads.googleads.v19.enums.types.LocalServicesVerificationStatusEnum.LocalServicesVerificationStatus): + verification_status (google.ads.googleads.v23.enums.types.LocalServicesVerificationStatusEnum.LocalServicesVerificationStatus): Output only. Granular insurance status, per geo + vertical. @@ -602,4 +612,21 @@ class GranularInsuranceStatus(proto.Message): ) +class VideoCustomer(proto.Message): + r"""Video specific information about a Customer. + + Attributes: + third_party_integration_partners (google.ads.googleads.v23.common.types.CustomerThirdPartyIntegrationPartners): + Third Party integration partners. + """ + + third_party_integration_partners: ( + gagc_third_party_integration_partners.CustomerThirdPartyIntegrationPartners + ) = proto.Field( + proto.MESSAGE, + number=1, + message=gagc_third_party_integration_partners.CustomerThirdPartyIntegrationPartners, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/customer_asset.py b/google/ads/googleads/v23/resources/types/customer_asset.py similarity index 83% rename from google/ads/googleads/v19/resources/types/customer_asset.py rename to google/ads/googleads/v23/resources/types/customer_asset.py index 997d4930f..5923270aa 100644 --- a/google/ads/googleads/v19/resources/types/customer_asset.py +++ b/google/ads/googleads/v23/resources/types/customer_asset.py @@ -19,19 +19,19 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import asset_policy -from google.ads.googleads.v19.enums.types import asset_field_type -from google.ads.googleads.v19.enums.types import asset_link_primary_status -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import asset_policy +from google.ads.googleads.v23.enums.types import asset_field_type +from google.ads.googleads.v23.enums.types import asset_link_primary_status +from google.ads.googleads.v23.enums.types import ( asset_link_primary_status_reason, ) -from google.ads.googleads.v19.enums.types import asset_link_status -from google.ads.googleads.v19.enums.types import asset_source +from google.ads.googleads.v23.enums.types import asset_link_status +from google.ads.googleads.v23.enums.types import asset_source __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerAsset", }, @@ -50,15 +50,15 @@ class CustomerAsset(proto.Message): asset (str): Required. Immutable. The asset which is linked to the customer. - field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): Required. Immutable. Role that the asset takes for the customer link. - source (google.ads.googleads.v19.enums.types.AssetSourceEnum.AssetSource): + source (google.ads.googleads.v23.enums.types.AssetSourceEnum.AssetSource): Output only. Source of the customer asset link. - status (google.ads.googleads.v19.enums.types.AssetLinkStatusEnum.AssetLinkStatus): + status (google.ads.googleads.v23.enums.types.AssetLinkStatusEnum.AssetLinkStatus): Status of the customer asset. - primary_status (google.ads.googleads.v19.enums.types.AssetLinkPrimaryStatusEnum.AssetLinkPrimaryStatus): + primary_status (google.ads.googleads.v23.enums.types.AssetLinkPrimaryStatusEnum.AssetLinkPrimaryStatus): Output only. Provides the PrimaryStatus of this asset link. Primary status is meant essentially to differentiate between the plain @@ -68,10 +68,10 @@ class CustomerAsset(proto.Message): assets its mainly policy and quality approvals) to come up with a more comprehensive status to indicate its serving state. - primary_status_details (MutableSequence[google.ads.googleads.v19.common.types.AssetLinkPrimaryStatusDetails]): + primary_status_details (MutableSequence[google.ads.googleads.v23.common.types.AssetLinkPrimaryStatusDetails]): Output only. Provides the details of the primary status and its associated reasons. - primary_status_reasons (MutableSequence[google.ads.googleads.v19.enums.types.AssetLinkPrimaryStatusReasonEnum.AssetLinkPrimaryStatusReason]): + primary_status_reasons (MutableSequence[google.ads.googleads.v23.enums.types.AssetLinkPrimaryStatusReasonEnum.AssetLinkPrimaryStatusReason]): Output only. Provides a list of reasons for why an asset is not serving or not serving at full capacity. diff --git a/google/ads/googleads/v19/resources/types/customer_asset_set.py b/google/ads/googleads/v23/resources/types/customer_asset_set.py similarity index 90% rename from google/ads/googleads/v19/resources/types/customer_asset_set.py rename to google/ads/googleads/v23/resources/types/customer_asset_set.py index 1f86e7f07..da21ecd3b 100644 --- a/google/ads/googleads/v19/resources/types/customer_asset_set.py +++ b/google/ads/googleads/v23/resources/types/customer_asset_set.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import asset_set_link_status +from google.ads.googleads.v23.enums.types import asset_set_link_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerAssetSet", }, @@ -47,7 +47,7 @@ class CustomerAssetSet(proto.Message): customer (str): Immutable. The customer to which this asset set is linked. - status (google.ads.googleads.v19.enums.types.AssetSetLinkStatusEnum.AssetSetLinkStatus): + status (google.ads.googleads.v23.enums.types.AssetSetLinkStatusEnum.AssetSetLinkStatus): Output only. The status of the customer asset set asset. Read-only. """ diff --git a/google/ads/googleads/v19/resources/types/customer_client.py b/google/ads/googleads/v23/resources/types/customer_client.py similarity index 95% rename from google/ads/googleads/v19/resources/types/customer_client.py rename to google/ads/googleads/v23/resources/types/customer_client.py index 0507d2b4d..cd3661db4 100644 --- a/google/ads/googleads/v19/resources/types/customer_client.py +++ b/google/ads/googleads/v23/resources/types/customer_client.py @@ -19,12 +19,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import customer_status +from google.ads.googleads.v23.enums.types import customer_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerClient", }, @@ -100,7 +100,7 @@ class CustomerClient(proto.Message): Label resource names have the form: ``customers/{customer_id}/labels/{label_id}`` - status (google.ads.googleads.v19.enums.types.CustomerStatusEnum.CustomerStatus): + status (google.ads.googleads.v23.enums.types.CustomerStatusEnum.CustomerStatus): Output only. The status of the client customer. Read only. """ diff --git a/google/ads/googleads/v19/resources/types/customer_client_link.py b/google/ads/googleads/v23/resources/types/customer_client_link.py similarity index 92% rename from google/ads/googleads/v19/resources/types/customer_client_link.py rename to google/ads/googleads/v23/resources/types/customer_client_link.py index b8a8efa2a..c7d8f6f4f 100644 --- a/google/ads/googleads/v19/resources/types/customer_client_link.py +++ b/google/ads/googleads/v23/resources/types/customer_client_link.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import manager_link_status +from google.ads.googleads.v23.enums.types import manager_link_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerClientLink", }, @@ -50,7 +50,7 @@ class CustomerClientLink(proto.Message): customer client link. Read only. This field is a member of `oneof`_ ``_manager_link_id``. - status (google.ads.googleads.v19.enums.types.ManagerLinkStatusEnum.ManagerLinkStatus): + status (google.ads.googleads.v23.enums.types.ManagerLinkStatusEnum.ManagerLinkStatus): This is the status of the link between client and manager. hidden (bool): diff --git a/google/ads/googleads/v19/resources/types/customer_conversion_goal.py b/google/ads/googleads/v23/resources/types/customer_conversion_goal.py similarity index 87% rename from google/ads/googleads/v19/resources/types/customer_conversion_goal.py rename to google/ads/googleads/v23/resources/types/customer_conversion_goal.py index d1bda38e3..872d9c83b 100644 --- a/google/ads/googleads/v19/resources/types/customer_conversion_goal.py +++ b/google/ads/googleads/v23/resources/types/customer_conversion_goal.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import conversion_action_category -from google.ads.googleads.v19.enums.types import conversion_origin +from google.ads.googleads.v23.enums.types import conversion_action_category +from google.ads.googleads.v23.enums.types import conversion_origin __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerConversionGoal", }, @@ -41,12 +41,12 @@ class CustomerConversionGoal(proto.Message): goal. Customer conversion goal resource names have the form: ``customers/{customer_id}/customerConversionGoals/{category}~{origin}`` - category (google.ads.googleads.v19.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): + category (google.ads.googleads.v23.enums.types.ConversionActionCategoryEnum.ConversionActionCategory): The conversion category of this customer conversion goal. Only conversion actions that have this category will be included in this goal. - origin (google.ads.googleads.v19.enums.types.ConversionOriginEnum.ConversionOrigin): + origin (google.ads.googleads.v23.enums.types.ConversionOriginEnum.ConversionOrigin): The conversion origin of this customer conversion goal. Only conversion actions that have this conversion origin will be included in diff --git a/google/ads/googleads/v19/resources/types/customer_customizer.py b/google/ads/googleads/v23/resources/types/customer_customizer.py similarity index 86% rename from google/ads/googleads/v19/resources/types/customer_customizer.py rename to google/ads/googleads/v23/resources/types/customer_customizer.py index ad0c9100c..bfb3ead8c 100644 --- a/google/ads/googleads/v19/resources/types/customer_customizer.py +++ b/google/ads/googleads/v23/resources/types/customer_customizer.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import customizer_value -from google.ads.googleads.v19.enums.types import customizer_value_status +from google.ads.googleads.v23.common.types import customizer_value +from google.ads.googleads.v23.enums.types import customizer_value_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerCustomizer", }, @@ -44,10 +44,10 @@ class CustomerCustomizer(proto.Message): customizer_attribute (str): Required. Immutable. The customizer attribute which is linked to the customer. - status (google.ads.googleads.v19.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): + status (google.ads.googleads.v23.enums.types.CustomizerValueStatusEnum.CustomizerValueStatus): Output only. The status of the customer customizer attribute. - value (google.ads.googleads.v19.common.types.CustomizerValue): + value (google.ads.googleads.v23.common.types.CustomizerValue): Required. The value to associate with the customizer attribute at this level. The value must be of the type specified for the diff --git a/google/ads/googleads/v19/resources/types/customer_label.py b/google/ads/googleads/v23/resources/types/customer_label.py similarity index 96% rename from google/ads/googleads/v19/resources/types/customer_label.py rename to google/ads/googleads/v23/resources/types/customer_label.py index dd34aa3fe..05cb96c73 100644 --- a/google/ads/googleads/v19/resources/types/customer_label.py +++ b/google/ads/googleads/v23/resources/types/customer_label.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerLabel", }, diff --git a/google/ads/googleads/v19/resources/types/customer_lifecycle_goal.py b/google/ads/googleads/v23/resources/types/customer_lifecycle_goal.py similarity index 89% rename from google/ads/googleads/v19/resources/types/customer_lifecycle_goal.py rename to google/ads/googleads/v23/resources/types/customer_lifecycle_goal.py index e34c54b3a..d180796d8 100644 --- a/google/ads/googleads/v19/resources/types/customer_lifecycle_goal.py +++ b/google/ads/googleads/v23/resources/types/customer_lifecycle_goal.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import lifecycle_goals +from google.ads.googleads.v23.common.types import lifecycle_goals __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerLifecycleGoal", }, @@ -39,7 +39,7 @@ class CustomerLifecycleGoal(proto.Message): Customer lifecycle resource names have the form: ``customers/{customer_id}/customerLifecycleGoal`` - customer_acquisition_goal_value_settings (google.ads.googleads.v19.common.types.LifecycleGoalValueSettings): + customer_acquisition_goal_value_settings (google.ads.googleads.v23.common.types.LifecycleGoalValueSettings): Output only. Customer acquisition goal customer level value settings. owner_customer (str): diff --git a/google/ads/googleads/v19/resources/types/customer_manager_link.py b/google/ads/googleads/v23/resources/types/customer_manager_link.py similarity index 91% rename from google/ads/googleads/v19/resources/types/customer_manager_link.py rename to google/ads/googleads/v23/resources/types/customer_manager_link.py index 6ee9afbf6..5a35f7c8c 100644 --- a/google/ads/googleads/v19/resources/types/customer_manager_link.py +++ b/google/ads/googleads/v23/resources/types/customer_manager_link.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import manager_link_status +from google.ads.googleads.v23.enums.types import manager_link_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerManagerLink", }, @@ -50,7 +50,7 @@ class CustomerManagerLink(proto.Message): This field is read only. This field is a member of `oneof`_ ``_manager_link_id``. - status (google.ads.googleads.v19.enums.types.ManagerLinkStatusEnum.ManagerLinkStatus): + status (google.ads.googleads.v23.enums.types.ManagerLinkStatusEnum.ManagerLinkStatus): Status of the link between the customer and the manager. """ diff --git a/google/ads/googleads/v19/resources/types/customer_negative_criterion.py b/google/ads/googleads/v23/resources/types/customer_negative_criterion.py similarity index 78% rename from google/ads/googleads/v19/resources/types/customer_negative_criterion.py rename to google/ads/googleads/v23/resources/types/customer_negative_criterion.py index edcb85c92..efe0fb5e5 100644 --- a/google/ads/googleads/v19/resources/types/customer_negative_criterion.py +++ b/google/ads/googleads/v23/resources/types/customer_negative_criterion.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.enums.types import criterion_type +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import criterion_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerNegativeCriterion", }, @@ -52,38 +52,45 @@ class CustomerNegativeCriterion(proto.Message): Output only. The ID of the criterion. This field is a member of `oneof`_ ``_id``. - type_ (google.ads.googleads.v19.enums.types.CriterionTypeEnum.CriterionType): + type_ (google.ads.googleads.v23.enums.types.CriterionTypeEnum.CriterionType): Output only. The type of the criterion. - content_label (google.ads.googleads.v19.common.types.ContentLabelInfo): + content_label (google.ads.googleads.v23.common.types.ContentLabelInfo): Immutable. ContentLabel. This field is a member of `oneof`_ ``criterion``. - mobile_application (google.ads.googleads.v19.common.types.MobileApplicationInfo): + mobile_application (google.ads.googleads.v23.common.types.MobileApplicationInfo): Immutable. MobileApplication. This field is a member of `oneof`_ ``criterion``. - mobile_app_category (google.ads.googleads.v19.common.types.MobileAppCategoryInfo): + mobile_app_category (google.ads.googleads.v23.common.types.MobileAppCategoryInfo): Immutable. MobileAppCategory. This field is a member of `oneof`_ ``criterion``. - placement (google.ads.googleads.v19.common.types.PlacementInfo): + placement (google.ads.googleads.v23.common.types.PlacementInfo): Immutable. Placement. This field is a member of `oneof`_ ``criterion``. - youtube_video (google.ads.googleads.v19.common.types.YouTubeVideoInfo): + youtube_video (google.ads.googleads.v23.common.types.YouTubeVideoInfo): Immutable. YouTube Video. This field is a member of `oneof`_ ``criterion``. - youtube_channel (google.ads.googleads.v19.common.types.YouTubeChannelInfo): + youtube_channel (google.ads.googleads.v23.common.types.YouTubeChannelInfo): Immutable. YouTube Channel. This field is a member of `oneof`_ ``criterion``. - negative_keyword_list (google.ads.googleads.v19.common.types.NegativeKeywordListInfo): + negative_keyword_list (google.ads.googleads.v23.common.types.NegativeKeywordListInfo): Immutable. NegativeKeywordList. This field is a member of `oneof`_ ``criterion``. - ip_block (google.ads.googleads.v19.common.types.IpBlockInfo): - Immutable. IPBLock + ip_block (google.ads.googleads.v23.common.types.IpBlockInfo): + Immutable. IpBlock. + + You can exclude up to 500 IP addresses per + account. + + This field is a member of `oneof`_ ``criterion``. + placement_list (google.ads.googleads.v23.common.types.PlacementListInfo): + Immutable. PlacementList. This field is a member of `oneof`_ ``criterion``. """ @@ -150,6 +157,12 @@ class CustomerNegativeCriterion(proto.Message): oneof="criterion", message=criteria.IpBlockInfo, ) + placement_list: criteria.PlacementListInfo = proto.Field( + proto.MESSAGE, + number=13, + oneof="criterion", + message=criteria.PlacementListInfo, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/customer_search_term_insight.py b/google/ads/googleads/v23/resources/types/customer_search_term_insight.py similarity index 96% rename from google/ads/googleads/v19/resources/types/customer_search_term_insight.py rename to google/ads/googleads/v23/resources/types/customer_search_term_insight.py index 981a49dda..de44c645f 100644 --- a/google/ads/googleads/v19/resources/types/customer_search_term_insight.py +++ b/google/ads/googleads/v23/resources/types/customer_search_term_insight.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerSearchTermInsight", }, diff --git a/google/ads/googleads/v19/resources/types/customer_sk_ad_network_conversion_value_schema.py b/google/ads/googleads/v23/resources/types/customer_sk_ad_network_conversion_value_schema.py similarity index 94% rename from google/ads/googleads/v19/resources/types/customer_sk_ad_network_conversion_value_schema.py rename to google/ads/googleads/v23/resources/types/customer_sk_ad_network_conversion_value_schema.py index 38abdb3c3..57fdf3a09 100644 --- a/google/ads/googleads/v19/resources/types/customer_sk_ad_network_conversion_value_schema.py +++ b/google/ads/googleads/v23/resources/types/customer_sk_ad_network_conversion_value_schema.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( sk_ad_network_coarse_conversion_value, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerSkAdNetworkConversionValueSchema", }, @@ -42,7 +42,7 @@ class CustomerSkAdNetworkConversionValueSchema(proto.Message): CustomerSkAdNetworkConversionValueSchema resource names have the form: customers/{customer_id}/customerSkAdNetworkConversionValueSchemas/{account_link_id} - schema (google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema): + schema (google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema): Output only. The schema for the specified resource. """ @@ -59,13 +59,13 @@ class SkAdNetworkConversionValueSchema(proto.Message): after which the App Attribution Partner or advertiser stops calling [updateConversionValue] (https://developer.apple.com/documentation/storekit/skadnetwork/3566697-updateconversionvalue). - fine_grained_conversion_value_mappings (MutableSequence[google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.FineGrainedConversionValueMappings]): + fine_grained_conversion_value_mappings (MutableSequence[google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.FineGrainedConversionValueMappings]): Output only. Fine grained conversion value mappings. For SkAdNetwork versions >= 4.0 that support multiple conversion windows, fine grained conversion value mappings are only applicable to the first postback. - postback_mappings (MutableSequence[google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.PostbackMapping]): + postback_mappings (MutableSequence[google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.PostbackMapping]): Output only. Per-postback conversion value mappings for postbacks in multiple conversion windows. Only applicable for SkAdNetwork @@ -79,7 +79,7 @@ class FineGrainedConversionValueMappings(proto.Message): fine_grained_conversion_value (int): Output only. Fine grained conversion value. Valid values are in the inclusive range [0,63]. - conversion_value_mapping (google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.ConversionValueMapping): + conversion_value_mapping (google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.ConversionValueMapping): Output only. Conversion events the fine grained conversion value maps to. """ @@ -108,10 +108,10 @@ class PostbackMapping(proto.Message): postback_sequence_index (int): Output only. 0-based index that indicates the order of postback. Valid values are in the inclusive range [0,2]. - coarse_grained_conversion_value_mappings (google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.CoarseGrainedConversionValueMappings): + coarse_grained_conversion_value_mappings (google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.CoarseGrainedConversionValueMappings): Output only. Conversion value mappings for all coarse grained conversion values. - lock_window_coarse_conversion_value (google.ads.googleads.v19.enums.types.SkAdNetworkCoarseConversionValueEnum.SkAdNetworkCoarseConversionValue): + lock_window_coarse_conversion_value (google.ads.googleads.v23.enums.types.SkAdNetworkCoarseConversionValueEnum.SkAdNetworkCoarseConversionValue): Output only. Coarse grained conversion value that triggers conversion window lock. @@ -160,13 +160,13 @@ class CoarseGrainedConversionValueMappings(proto.Message): r"""Mappings for coarse grained conversion values. Attributes: - low_conversion_value_mapping (google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.ConversionValueMapping): + low_conversion_value_mapping (google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.ConversionValueMapping): Output only. Mapping for "low" coarse conversion value. - medium_conversion_value_mapping (google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.ConversionValueMapping): + medium_conversion_value_mapping (google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.ConversionValueMapping): Output only. Mapping for "medium" coarse conversion value. - high_conversion_value_mapping (google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.ConversionValueMapping): + high_conversion_value_mapping (google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.ConversionValueMapping): Output only. Mapping for "high" coarse conversion value. """ @@ -200,7 +200,7 @@ class ConversionValueMapping(proto.Message): Output only. The maximum of the time range in which a user was last active during the measurement window. - mapped_events (MutableSequence[google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.Event]): + mapped_events (MutableSequence[google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.Event]): Output only. The conversion value may be mapped to multiple events with various attributes. @@ -240,7 +240,7 @@ class Event(proto.Message): currency_code (str): Output only. The reported currency for the event_revenue. ISO 4217 three-letter currency code, for example, "USD". - event_revenue_range (google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.Event.RevenueRange): + event_revenue_range (google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.Event.RevenueRange): Output only. The event revenue range. This field is a member of `oneof`_ ``revenue_rate``. @@ -249,7 +249,7 @@ class Event(proto.Message): value. This field is a member of `oneof`_ ``revenue_rate``. - event_occurrence_range (google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.Event.EventOccurrenceRange): + event_occurrence_range (google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema.SkAdNetworkConversionValueSchema.Event.EventOccurrenceRange): Output only. The event counter range. This field is a member of `oneof`_ ``event_rate``. diff --git a/google/ads/googleads/v19/resources/types/customer_user_access.py b/google/ads/googleads/v23/resources/types/customer_user_access.py similarity index 92% rename from google/ads/googleads/v19/resources/types/customer_user_access.py rename to google/ads/googleads/v23/resources/types/customer_user_access.py index ee10a7899..9942b2294 100644 --- a/google/ads/googleads/v19/resources/types/customer_user_access.py +++ b/google/ads/googleads/v23/resources/types/customer_user_access.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import access_role as gage_access_role +from google.ads.googleads.v23.enums.types import access_role as gage_access_role __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerUserAccess", }, @@ -50,7 +50,7 @@ class CustomerUserAccess(proto.Message): Read only field This field is a member of `oneof`_ ``_email_address``. - access_role (google.ads.googleads.v19.enums.types.AccessRoleEnum.AccessRole): + access_role (google.ads.googleads.v23.enums.types.AccessRoleEnum.AccessRole): Access role of the user. access_creation_date_time (str): Output only. The customer user access diff --git a/google/ads/googleads/v19/resources/types/customer_user_access_invitation.py b/google/ads/googleads/v23/resources/types/customer_user_access_invitation.py similarity index 88% rename from google/ads/googleads/v19/resources/types/customer_user_access_invitation.py rename to google/ads/googleads/v23/resources/types/customer_user_access_invitation.py index e8df7a591..189b7d48c 100644 --- a/google/ads/googleads/v19/resources/types/customer_user_access_invitation.py +++ b/google/ads/googleads/v23/resources/types/customer_user_access_invitation.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import access_invitation_status -from google.ads.googleads.v19.enums.types import access_role as gage_access_role +from google.ads.googleads.v23.enums.types import access_invitation_status +from google.ads.googleads.v23.enums.types import access_role as gage_access_role __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomerUserAccessInvitation", }, @@ -43,7 +43,7 @@ class CustomerUserAccessInvitation(proto.Message): invitation_id (int): Output only. The ID of the invitation. This field is read-only. - access_role (google.ads.googleads.v19.enums.types.AccessRoleEnum.AccessRole): + access_role (google.ads.googleads.v23.enums.types.AccessRoleEnum.AccessRole): Immutable. Access role of the user. email_address (str): Immutable. Email address the invitation was @@ -55,7 +55,7 @@ class CustomerUserAccessInvitation(proto.Message): The format is "YYYY-MM-DD HH:MM:SS". Examples: "2018-03-05 09:15:00" or "2018-02-01 14:34:30". - invitation_status (google.ads.googleads.v19.enums.types.AccessInvitationStatusEnum.AccessInvitationStatus): + invitation_status (google.ads.googleads.v23.enums.types.AccessInvitationStatusEnum.AccessInvitationStatus): Output only. Invitation status of the user. """ diff --git a/google/ads/googleads/v19/resources/types/customizer_attribute.py b/google/ads/googleads/v23/resources/types/customizer_attribute.py similarity index 88% rename from google/ads/googleads/v19/resources/types/customizer_attribute.py rename to google/ads/googleads/v23/resources/types/customizer_attribute.py index 53967526f..dd3ecadba 100644 --- a/google/ads/googleads/v19/resources/types/customizer_attribute.py +++ b/google/ads/googleads/v23/resources/types/customizer_attribute.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import customizer_attribute_status -from google.ads.googleads.v19.enums.types import customizer_attribute_type +from google.ads.googleads.v23.enums.types import customizer_attribute_status +from google.ads.googleads.v23.enums.types import customizer_attribute_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "CustomizerAttribute", }, @@ -53,10 +53,10 @@ class CustomizerAttribute(proto.Message): length of 1 and maximum length of 40. Name of an enabled customizer attribute must be unique (case insensitive). - type_ (google.ads.googleads.v19.enums.types.CustomizerAttributeTypeEnum.CustomizerAttributeType): + type_ (google.ads.googleads.v23.enums.types.CustomizerAttributeTypeEnum.CustomizerAttributeType): Immutable. The type of the customizer attribute. - status (google.ads.googleads.v19.enums.types.CustomizerAttributeStatusEnum.CustomizerAttributeStatus): + status (google.ads.googleads.v23.enums.types.CustomizerAttributeStatusEnum.CustomizerAttributeStatus): Output only. The status of the customizer attribute. """ diff --git a/google/ads/googleads/v19/resources/types/data_link.py b/google/ads/googleads/v23/resources/types/data_link.py similarity index 90% rename from google/ads/googleads/v19/resources/types/data_link.py rename to google/ads/googleads/v23/resources/types/data_link.py index e96d54f81..79e476e1e 100644 --- a/google/ads/googleads/v19/resources/types/data_link.py +++ b/google/ads/googleads/v23/resources/types/data_link.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import data_link_status -from google.ads.googleads.v19.enums.types import data_link_type +from google.ads.googleads.v23.enums.types import data_link_status +from google.ads.googleads.v23.enums.types import data_link_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "DataLink", "YoutubeVideoIdentifier", @@ -55,11 +55,11 @@ class DataLink(proto.Message): This field is read only. This field is a member of `oneof`_ ``_data_link_id``. - type_ (google.ads.googleads.v19.enums.types.DataLinkTypeEnum.DataLinkType): + type_ (google.ads.googleads.v23.enums.types.DataLinkTypeEnum.DataLinkType): Output only. The type of the data. - status (google.ads.googleads.v19.enums.types.DataLinkStatusEnum.DataLinkStatus): + status (google.ads.googleads.v23.enums.types.DataLinkStatusEnum.DataLinkStatus): Output only. The status of the data link. - youtube_video (google.ads.googleads.v19.resources.types.YoutubeVideoIdentifier): + youtube_video (google.ads.googleads.v23.resources.types.YoutubeVideoIdentifier): Immutable. A data link to YouTube video. This field is a member of `oneof`_ ``data_link_entity``. diff --git a/google/ads/googleads/v23/resources/types/detail_content_suitability_placement_view.py b/google/ads/googleads/v23/resources/types/detail_content_suitability_placement_view.py new file mode 100644 index 000000000..1387c15aa --- /dev/null +++ b/google/ads/googleads/v23/resources/types/detail_content_suitability_placement_view.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.ads.googleads.v23.enums.types import ( + placement_type as gage_placement_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "DetailContentSuitabilityPlacementView", + }, +) + + +class DetailContentSuitabilityPlacementView(proto.Message): + r"""A detail content suitability placement view. + + Attributes: + resource_name (str): + Output only. The resource name of the detail content + suitability placement view. Detail content suitability + placement view resource names have the form: + + ``customers/{customer_id}/detailContentSuitabilityPlacementViews/{placement_fingerprint}`` + display_name (str): + Output only. The display name is URL for + websites, YouTube video name for YouTube videos, + and translated mobile app name for mobile apps. + placement (str): + Output only. The automatic placement string + at detail level, for example. website url, + mobile application id, or a YouTube video id. + placement_type (google.ads.googleads.v23.enums.types.PlacementTypeEnum.PlacementType): + Output only. Represents the type of the + placement, for example, Website, YouTubeVideo + and MobileApplication. + target_url (str): + Output only. URL of the placement, for + example, website, link to the mobile application + in app store, or a YouTube video URL. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + placement: str = proto.Field( + proto.STRING, + number=3, + ) + placement_type: gage_placement_type.PlacementTypeEnum.PlacementType = ( + proto.Field( + proto.ENUM, + number=4, + enum=gage_placement_type.PlacementTypeEnum.PlacementType, + ) + ) + target_url: str = proto.Field( + proto.STRING, + number=5, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/detail_placement_view.py b/google/ads/googleads/v23/resources/types/detail_placement_view.py similarity index 85% rename from google/ads/googleads/v19/resources/types/detail_placement_view.py rename to google/ads/googleads/v23/resources/types/detail_placement_view.py index af639a7ad..a569d5cf5 100644 --- a/google/ads/googleads/v19/resources/types/detail_placement_view.py +++ b/google/ads/googleads/v23/resources/types/detail_placement_view.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( placement_type as gage_placement_type, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "DetailPlacementView", }, @@ -33,8 +33,14 @@ class DetailPlacementView(proto.Message): - r"""A view with metrics aggregated by ad group and URL or YouTube - video. + r"""A view with metrics aggregated by ad group and URL or YouTube video. + + This view primarily surfaces placement data from the Google Display + Network. While you can select segments like + ``segments.ad_network_type``, this view generally does not include + placement data from other networks, such as the Search Partners + network. To understand performance on Search Partners, consider + other reports and segmentations. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -69,7 +75,7 @@ class DetailPlacementView(proto.Message): in app store, or a YouTube video URL. This field is a member of `oneof`_ ``_target_url``. - placement_type (google.ads.googleads.v19.enums.types.PlacementTypeEnum.PlacementType): + placement_type (google.ads.googleads.v23.enums.types.PlacementTypeEnum.PlacementType): Output only. Type of the placement, for example, Website, YouTube Video, and Mobile Application. diff --git a/google/ads/googleads/v19/resources/types/detailed_demographic.py b/google/ads/googleads/v23/resources/types/detailed_demographic.py similarity index 92% rename from google/ads/googleads/v19/resources/types/detailed_demographic.py rename to google/ads/googleads/v23/resources/types/detailed_demographic.py index 1b84878b8..0347e71ec 100644 --- a/google/ads/googleads/v19/resources/types/detailed_demographic.py +++ b/google/ads/googleads/v23/resources/types/detailed_demographic.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import ( +from google.ads.googleads.v23.common.types import ( criterion_category_availability, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "DetailedDemographic", }, @@ -55,7 +55,7 @@ class DetailedDemographic(proto.Message): launched_to_all (bool): Output only. True if the detailed demographic is launched to all channels and locales. - availabilities (MutableSequence[google.ads.googleads.v19.common.types.CriterionCategoryAvailability]): + availabilities (MutableSequence[google.ads.googleads.v23.common.types.CriterionCategoryAvailability]): Output only. Availability information of the detailed demographic. """ diff --git a/google/ads/googleads/v23/resources/types/display_keyword_view.py b/google/ads/googleads/v23/resources/types/display_keyword_view.py new file mode 100644 index 000000000..fc0a52037 --- /dev/null +++ b/google/ads/googleads/v23/resources/types/display_keyword_view.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "DisplayKeywordView", + }, +) + + +class DisplayKeywordView(proto.Message): + r"""A display keyword view. + + Provides performance data for keywords used in Display Network + campaigns. This view lets you analyze how your display keywords are + performing across various segments. + + This view is primarily used to track the effectiveness of keyword + targeting within your Display campaigns. To understand which network + the metrics apply to, you can select the + ``segments.ad_network_type`` field in your query. This field will + segment the data by networks such as the Google Display Network, + YouTube, Gmail, and so on. + + You can select fields from this resource along with metrics like + impressions, clicks, and conversions to gauge performance. + Attributed resources like ``ad_group`` and ``campaign`` can also be + selected without segmenting metrics. + + Attributes: + resource_name (str): + Output only. The resource name of the display keyword view. + Display Keyword view resource names have the form: + + ``customers/{customer_id}/displayKeywordViews/{ad_group_id}~{criterion_id}`` + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/distance_view.py b/google/ads/googleads/v23/resources/types/distance_view.py similarity index 91% rename from google/ads/googleads/v19/resources/types/distance_view.py rename to google/ads/googleads/v23/resources/types/distance_view.py index 2ab8a7dce..fae00b5c8 100644 --- a/google/ads/googleads/v19/resources/types/distance_view.py +++ b/google/ads/googleads/v23/resources/types/distance_view.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( distance_bucket as gage_distance_bucket, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "DistanceView", }, @@ -48,7 +48,7 @@ class DistanceView(proto.Message): Distance view resource names have the form: ``customers/{customer_id}/distanceViews/1~{distance_bucket}`` - distance_bucket (google.ads.googleads.v19.enums.types.DistanceBucketEnum.DistanceBucket): + distance_bucket (google.ads.googleads.v23.enums.types.DistanceBucketEnum.DistanceBucket): Output only. Grouping of user distance from location extensions. metric_system (bool): diff --git a/google/ads/googleads/v19/resources/types/domain_category.py b/google/ads/googleads/v23/resources/types/domain_category.py similarity index 98% rename from google/ads/googleads/v19/resources/types/domain_category.py rename to google/ads/googleads/v23/resources/types/domain_category.py index 2f93a91af..42201eb38 100644 --- a/google/ads/googleads/v19/resources/types/domain_category.py +++ b/google/ads/googleads/v23/resources/types/domain_category.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "DomainCategory", }, diff --git a/google/ads/googleads/v19/resources/types/dynamic_search_ads_search_term_view.py b/google/ads/googleads/v23/resources/types/dynamic_search_ads_search_term_view.py similarity index 97% rename from google/ads/googleads/v19/resources/types/dynamic_search_ads_search_term_view.py rename to google/ads/googleads/v23/resources/types/dynamic_search_ads_search_term_view.py index ff111d096..603efbc20 100644 --- a/google/ads/googleads/v19/resources/types/dynamic_search_ads_search_term_view.py +++ b/google/ads/googleads/v23/resources/types/dynamic_search_ads_search_term_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "DynamicSearchAdsSearchTermView", }, diff --git a/google/ads/googleads/v19/resources/types/expanded_landing_page_view.py b/google/ads/googleads/v23/resources/types/expanded_landing_page_view.py similarity index 95% rename from google/ads/googleads/v19/resources/types/expanded_landing_page_view.py rename to google/ads/googleads/v23/resources/types/expanded_landing_page_view.py index 5d7678898..3117f1882 100644 --- a/google/ads/googleads/v19/resources/types/expanded_landing_page_view.py +++ b/google/ads/googleads/v23/resources/types/expanded_landing_page_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ExpandedLandingPageView", }, diff --git a/google/ads/googleads/v19/resources/types/experiment.py b/google/ads/googleads/v23/resources/types/experiment.py similarity index 90% rename from google/ads/googleads/v19/resources/types/experiment.py rename to google/ads/googleads/v23/resources/types/experiment.py index 21d25ad8c..078f09bae 100644 --- a/google/ads/googleads/v19/resources/types/experiment.py +++ b/google/ads/googleads/v23/resources/types/experiment.py @@ -19,15 +19,15 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import metric_goal -from google.ads.googleads.v19.enums.types import async_action_status -from google.ads.googleads.v19.enums.types import experiment_status -from google.ads.googleads.v19.enums.types import experiment_type +from google.ads.googleads.v23.common.types import metric_goal +from google.ads.googleads.v23.enums.types import async_action_status +from google.ads.googleads.v23.enums.types import experiment_status +from google.ads.googleads.v23.enums.types import experiment_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "Experiment", }, @@ -68,10 +68,10 @@ class Experiment(proto.Message): to initiated. The suffix will be appended to the in-design and experiment campaign names so that the name is base campaign name + suffix. - type_ (google.ads.googleads.v19.enums.types.ExperimentTypeEnum.ExperimentType): + type_ (google.ads.googleads.v23.enums.types.ExperimentTypeEnum.ExperimentType): Required. The product/feature that uses this experiment. - status (google.ads.googleads.v19.enums.types.ExperimentStatusEnum.ExperimentStatus): + status (google.ads.googleads.v23.enums.types.ExperimentStatusEnum.ExperimentStatus): The Advertiser-chosen status of this experiment. start_date (str): @@ -97,7 +97,7 @@ class Experiment(proto.Message): Example: 2019-04-18 This field is a member of `oneof`_ ``_end_date``. - goals (MutableSequence[google.ads.googleads.v19.common.types.MetricGoal]): + goals (MutableSequence[google.ads.googleads.v23.common.types.MetricGoal]): The goals of this experiment. long_running_operation (str): Output only. The resource name of the @@ -107,7 +107,7 @@ class Experiment(proto.Message): is returned. This field is a member of `oneof`_ ``_long_running_operation``. - promote_status (google.ads.googleads.v19.enums.types.AsyncActionStatusEnum.AsyncActionStatus): + promote_status (google.ads.googleads.v23.enums.types.AsyncActionStatusEnum.AsyncActionStatus): Output only. The status of the experiment promotion process. sync_enabled (bool): diff --git a/google/ads/googleads/v19/resources/types/experiment_arm.py b/google/ads/googleads/v23/resources/types/experiment_arm.py similarity index 96% rename from google/ads/googleads/v19/resources/types/experiment_arm.py rename to google/ads/googleads/v23/resources/types/experiment_arm.py index eec60bcb8..2cb3290c7 100644 --- a/google/ads/googleads/v19/resources/types/experiment_arm.py +++ b/google/ads/googleads/v23/resources/types/experiment_arm.py @@ -21,8 +21,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ExperimentArm", }, diff --git a/google/ads/googleads/v23/resources/types/final_url_expansion_asset_view.py b/google/ads/googleads/v23/resources/types/final_url_expansion_asset_view.py new file mode 100644 index 000000000..05524f370 --- /dev/null +++ b/google/ads/googleads/v23/resources/types/final_url_expansion_asset_view.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.ads.googleads.v23.enums.types import asset_field_type +from google.ads.googleads.v23.enums.types import asset_link_status + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "FinalUrlExpansionAssetView", + }, +) + + +class FinalUrlExpansionAssetView(proto.Message): + r"""FinalUrlExpansionAssetView Resource. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Output only. The resource name of the + FinalUrlExpansionAsset. + campaign (str): + Output only. Campaign in which the asset + served. + + This field is a member of `oneof`_ ``_campaign``. + asset (str): + Output only. The ID of the asset. + + This field is a member of `oneof`_ ``_asset``. + field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): + Output only. The field type of the asset. + status (google.ads.googleads.v23.enums.types.AssetLinkStatusEnum.AssetLinkStatus): + Output only. Status of the + FinalUrlExpansionAsset. + + This field is a member of `oneof`_ ``_status``. + final_url (str): + Output only. Final URL of the + FinalUrlExpansionAsset. + ad_group (str): + Output only. Ad Group in which + FinalUrlExpansionAsset served. + + This field is a member of `oneof`_ ``level``. + asset_group (str): + Output only. Asset Group in which + FinalUrlExpansionAsset served. + + This field is a member of `oneof`_ ``level``. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + campaign: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + asset: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + field_type: asset_field_type.AssetFieldTypeEnum.AssetFieldType = ( + proto.Field( + proto.ENUM, + number=4, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + ) + status: asset_link_status.AssetLinkStatusEnum.AssetLinkStatus = proto.Field( + proto.ENUM, + number=5, + optional=True, + enum=asset_link_status.AssetLinkStatusEnum.AssetLinkStatus, + ) + final_url: str = proto.Field( + proto.STRING, + number=6, + ) + ad_group: str = proto.Field( + proto.STRING, + number=7, + oneof="level", + ) + asset_group: str = proto.Field( + proto.STRING, + number=8, + oneof="level", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/gender_view.py b/google/ads/googleads/v23/resources/types/gender_view.py similarity index 94% rename from google/ads/googleads/v19/resources/types/gender_view.py rename to google/ads/googleads/v23/resources/types/gender_view.py index 6e11a75c0..3de5b0c31 100644 --- a/google/ads/googleads/v19/resources/types/gender_view.py +++ b/google/ads/googleads/v23/resources/types/gender_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "GenderView", }, diff --git a/google/ads/googleads/v19/resources/types/geo_target_constant.py b/google/ads/googleads/v23/resources/types/geo_target_constant.py similarity index 94% rename from google/ads/googleads/v19/resources/types/geo_target_constant.py rename to google/ads/googleads/v23/resources/types/geo_target_constant.py index faef4f873..e9fa8c5e1 100644 --- a/google/ads/googleads/v19/resources/types/geo_target_constant.py +++ b/google/ads/googleads/v23/resources/types/geo_target_constant.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import geo_target_constant_status +from google.ads.googleads.v23.enums.types import geo_target_constant_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "GeoTargetConstant", }, @@ -60,7 +60,7 @@ class GeoTargetConstant(proto.Message): Output only. Geo target constant target type. This field is a member of `oneof`_ ``_target_type``. - status (google.ads.googleads.v19.enums.types.GeoTargetConstantStatusEnum.GeoTargetConstantStatus): + status (google.ads.googleads.v23.enums.types.GeoTargetConstantStatusEnum.GeoTargetConstantStatus): Output only. Geo target constant status. canonical_name (str): Output only. The fully qualified English diff --git a/google/ads/googleads/v19/resources/types/geographic_view.py b/google/ads/googleads/v23/resources/types/geographic_view.py similarity index 91% rename from google/ads/googleads/v19/resources/types/geographic_view.py rename to google/ads/googleads/v23/resources/types/geographic_view.py index 34d0aae24..27ac82d68 100644 --- a/google/ads/googleads/v19/resources/types/geographic_view.py +++ b/google/ads/googleads/v23/resources/types/geographic_view.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import geo_targeting_type +from google.ads.googleads.v23.enums.types import geo_targeting_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "GeographicView", }, @@ -48,7 +48,7 @@ class GeographicView(proto.Message): Geographic view resource names have the form: ``customers/{customer_id}/geographicViews/{country_criterion_id}~{location_type}`` - location_type (google.ads.googleads.v19.enums.types.GeoTargetingTypeEnum.GeoTargetingType): + location_type (google.ads.googleads.v23.enums.types.GeoTargetingTypeEnum.GeoTargetingType): Output only. Type of the geo targeting of the campaign. country_criterion_id (int): diff --git a/google/ads/googleads/v23/resources/types/goal.py b/google/ads/googleads/v23/resources/types/goal.py new file mode 100644 index 000000000..3854568f7 --- /dev/null +++ b/google/ads/googleads/v23/resources/types/goal.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import goal_setting +from google.ads.googleads.v23.enums.types import goal_optimization_eligibility +from google.ads.googleads.v23.enums.types import goal_type as gage_goal_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "Goal", + }, +) + + +class Goal(proto.Message): + r"""Representation of goals. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the goal. Goal resource + names have the form: + ``customers/{customer_id}/goals/{goal_id}`` + goal_id (int): + Output only. The ID of this goal. + + This field is a member of `oneof`_ ``_goal_id``. + goal_type (google.ads.googleads.v23.enums.types.GoalTypeEnum.GoalType): + Output only. The type of this goal. + owner_customer (str): + Output only. The resource name of the goal + owner customer. + + This field is a member of `oneof`_ ``_owner_customer``. + optimization_eligibility (google.ads.googleads.v23.enums.types.GoalOptimizationEligibilityEnum.GoalOptimizationEligibility): + Output only. Indicates if this goal is + eligible for campaign optimization. + retention_goal_settings (google.ads.googleads.v23.common.types.GoalSetting.RetentionGoal): + Retention goal settings. + + This field is a member of `oneof`_ ``goal_settings``. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + goal_id: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + goal_type: gage_goal_type.GoalTypeEnum.GoalType = proto.Field( + proto.ENUM, + number=3, + enum=gage_goal_type.GoalTypeEnum.GoalType, + ) + owner_customer: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + optimization_eligibility: ( + goal_optimization_eligibility.GoalOptimizationEligibilityEnum.GoalOptimizationEligibility + ) = proto.Field( + proto.ENUM, + number=6, + enum=goal_optimization_eligibility.GoalOptimizationEligibilityEnum.GoalOptimizationEligibility, + ) + retention_goal_settings: goal_setting.GoalSetting.RetentionGoal = ( + proto.Field( + proto.MESSAGE, + number=7, + oneof="goal_settings", + message=goal_setting.GoalSetting.RetentionGoal, + ) + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/google_ads_field.py b/google/ads/googleads/v23/resources/types/google_ads_field.py similarity index 94% rename from google/ads/googleads/v19/resources/types/google_ads_field.py rename to google/ads/googleads/v23/resources/types/google_ads_field.py index 2c10ca8de..8919256a3 100644 --- a/google/ads/googleads/v19/resources/types/google_ads_field.py +++ b/google/ads/googleads/v23/resources/types/google_ads_field.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import google_ads_field_category -from google.ads.googleads.v19.enums.types import google_ads_field_data_type +from google.ads.googleads.v23.enums.types import google_ads_field_category +from google.ads.googleads.v23.enums.types import google_ads_field_data_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "GoogleAdsField", }, @@ -47,7 +47,7 @@ class GoogleAdsField(proto.Message): Output only. The name of the artifact. This field is a member of `oneof`_ ``_name``. - category (google.ads.googleads.v19.enums.types.GoogleAdsFieldCategoryEnum.GoogleAdsFieldCategory): + category (google.ads.googleads.v23.enums.types.GoogleAdsFieldCategoryEnum.GoogleAdsFieldCategory): Output only. The category of the artifact. selectable (bool): Output only. Whether the artifact can be used @@ -94,7 +94,7 @@ class GoogleAdsField(proto.Message): if it is a field of type ENUM. This field is only set for artifacts of category SEGMENT or ATTRIBUTE. - data_type (google.ads.googleads.v19.enums.types.GoogleAdsFieldDataTypeEnum.GoogleAdsFieldDataType): + data_type (google.ads.googleads.v23.enums.types.GoogleAdsFieldDataTypeEnum.GoogleAdsFieldDataType): Output only. This field determines the operators that can be used with the artifact in WHERE clauses. diff --git a/google/ads/googleads/v23/resources/types/group_content_suitability_placement_view.py b/google/ads/googleads/v23/resources/types/group_content_suitability_placement_view.py new file mode 100644 index 000000000..adca60236 --- /dev/null +++ b/google/ads/googleads/v23/resources/types/group_content_suitability_placement_view.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.ads.googleads.v23.enums.types import ( + placement_type as gage_placement_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "GroupContentSuitabilityPlacementView", + }, +) + + +class GroupContentSuitabilityPlacementView(proto.Message): + r"""A group content suitability placement view. + + Attributes: + resource_name (str): + Output only. The resource name of the group content + suitability placement view. Group content suitability + placement view resource names have the form: + + ``customers/{customer_id}/groupContentSuitabilityPlacementViews/{placement_fingerprint}`` + display_name (str): + Output only. The display name is URL for + websites, YouTube video name for YouTube videos, + and translated mobile app name for mobile apps. + placement (str): + Output only. The automatic placement string + at group level, for example. website url, mobile + application id, or a YouTube video id. + placement_type (google.ads.googleads.v23.enums.types.PlacementTypeEnum.PlacementType): + Output only. Represents the type of the + placement, for example, Website, YouTubeVideo + and MobileApplication. + target_url (str): + Output only. URL of the placement, for + example, website, link to the mobile application + in app store, or a YouTube video URL. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + placement: str = proto.Field( + proto.STRING, + number=3, + ) + placement_type: gage_placement_type.PlacementTypeEnum.PlacementType = ( + proto.Field( + proto.ENUM, + number=4, + enum=gage_placement_type.PlacementTypeEnum.PlacementType, + ) + ) + target_url: str = proto.Field( + proto.STRING, + number=5, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/group_placement_view.py b/google/ads/googleads/v23/resources/types/group_placement_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/group_placement_view.py rename to google/ads/googleads/v23/resources/types/group_placement_view.py index 3d43a409e..eb940bcd4 100644 --- a/google/ads/googleads/v19/resources/types/group_placement_view.py +++ b/google/ads/googleads/v23/resources/types/group_placement_view.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( placement_type as gage_placement_type, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "GroupPlacementView", }, @@ -60,7 +60,7 @@ class GroupPlacementView(proto.Message): in app store, or a YouTube channel URL. This field is a member of `oneof`_ ``_target_url``. - placement_type (google.ads.googleads.v19.enums.types.PlacementTypeEnum.PlacementType): + placement_type (google.ads.googleads.v23.enums.types.PlacementTypeEnum.PlacementType): Output only. Type of the placement, for example, Website, YouTube Channel, Mobile Application. diff --git a/google/ads/googleads/v19/resources/types/hotel_group_view.py b/google/ads/googleads/v23/resources/types/hotel_group_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/hotel_group_view.py rename to google/ads/googleads/v23/resources/types/hotel_group_view.py index e02890592..027601545 100644 --- a/google/ads/googleads/v19/resources/types/hotel_group_view.py +++ b/google/ads/googleads/v23/resources/types/hotel_group_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "HotelGroupView", }, diff --git a/google/ads/googleads/v19/resources/types/hotel_performance_view.py b/google/ads/googleads/v23/resources/types/hotel_performance_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/hotel_performance_view.py rename to google/ads/googleads/v23/resources/types/hotel_performance_view.py index 3a4187c92..92dd2330a 100644 --- a/google/ads/googleads/v19/resources/types/hotel_performance_view.py +++ b/google/ads/googleads/v23/resources/types/hotel_performance_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "HotelPerformanceView", }, diff --git a/google/ads/googleads/v19/resources/types/hotel_reconciliation.py b/google/ads/googleads/v23/resources/types/hotel_reconciliation.py similarity index 96% rename from google/ads/googleads/v19/resources/types/hotel_reconciliation.py rename to google/ads/googleads/v23/resources/types/hotel_reconciliation.py index 6a80d6ca1..7058377f4 100644 --- a/google/ads/googleads/v19/resources/types/hotel_reconciliation.py +++ b/google/ads/googleads/v23/resources/types/hotel_reconciliation.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import hotel_reconciliation_status +from google.ads.googleads.v23.enums.types import hotel_reconciliation_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "HotelReconciliation", }, @@ -93,7 +93,7 @@ class HotelReconciliation(proto.Message): Output only. Whether a given booking has been billed. Once billed, a booking can't be modified. - status (google.ads.googleads.v19.enums.types.HotelReconciliationStatusEnum.HotelReconciliationStatus): + status (google.ads.googleads.v23.enums.types.HotelReconciliationStatusEnum.HotelReconciliationStatus): Required. Output only. Current status of a booking with regards to reconciliation and billing. Bookings should be reconciled within 45 diff --git a/google/ads/googleads/v19/resources/types/income_range_view.py b/google/ads/googleads/v23/resources/types/income_range_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/income_range_view.py rename to google/ads/googleads/v23/resources/types/income_range_view.py index e3bb6c633..dddb5df80 100644 --- a/google/ads/googleads/v19/resources/types/income_range_view.py +++ b/google/ads/googleads/v23/resources/types/income_range_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "IncomeRangeView", }, diff --git a/google/ads/googleads/v19/resources/types/invoice.py b/google/ads/googleads/v23/resources/types/invoice.py similarity index 80% rename from google/ads/googleads/v19/resources/types/invoice.py rename to google/ads/googleads/v23/resources/types/invoice.py index ec11d4b2b..0038eb91d 100644 --- a/google/ads/googleads/v19/resources/types/invoice.py +++ b/google/ads/googleads/v23/resources/types/invoice.py @@ -19,14 +19,20 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import dates -from google.ads.googleads.v19.enums.types import invoice_type -from google.ads.googleads.v19.enums.types import month_of_year +from google.ads.googleads.v23.common.types import dates +from google.ads.googleads.v23.enums.types import invoice_type +from google.ads.googleads.v23.enums.types import month_of_year +from google.ads.googleads.v23.enums.types import ( + regulatory_fee_type as gage_regulatory_fee_type, +) +from google.ads.googleads.v23.enums.types import ( + unit_of_measure as gage_unit_of_measure, +) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "Invoice", }, @@ -55,7 +61,7 @@ class Invoice(proto.Message): appears on the invoice PDF as "Invoice number". This field is a member of `oneof`_ ``_id``. - type_ (google.ads.googleads.v19.enums.types.InvoiceTypeEnum.InvoiceType): + type_ (google.ads.googleads.v23.enums.types.InvoiceTypeEnum.InvoiceType): Output only. The type of invoice. billing_setup (str): Output only. The resource name of this invoice's billing @@ -90,7 +96,7 @@ class Invoice(proto.Message): format. This field is a member of `oneof`_ ``_due_date``. - service_date_range (google.ads.googleads.v19.common.types.DateRange): + service_date_range (google.ads.googleads.v23.common.types.DateRange): Output only. The service period date range of this invoice. The end date is inclusive. currency_code (str): @@ -181,10 +187,10 @@ class Invoice(proto.Message): to request the PDF with this URL. This field is a member of `oneof`_ ``_pdf_url``. - account_budget_summaries (MutableSequence[google.ads.googleads.v19.resources.types.Invoice.AccountBudgetSummary]): + account_budget_summaries (MutableSequence[google.ads.googleads.v23.resources.types.Invoice.AccountBudgetSummary]): Output only. The list of summarized account budget information associated with this invoice. - account_summaries (MutableSequence[google.ads.googleads.v19.resources.types.Invoice.AccountSummary]): + account_summaries (MutableSequence[google.ads.googleads.v23.resources.types.Invoice.AccountSummary]): Output only. The list of summarized account information associated with this invoice. """ @@ -292,6 +298,12 @@ class AccountSummary(proto.Message): subtotal_amount_micros and tax_amount_micros. This field is a member of `oneof`_ ``_total_amount_micros``. + regulatory_cost_summaries (MutableSequence[google.ads.googleads.v23.resources.types.Invoice.RegulatoryCostSummary]): + Output only. The list of regulatory cost + information associated with this account. + adjustment_summaries (MutableSequence[google.ads.googleads.v23.resources.types.Invoice.AdjustmentSummary]): + Output only. The list of adjustment + information associated with this account. """ customer: str = proto.Field( @@ -389,6 +401,20 @@ class AccountSummary(proto.Message): number=16, optional=True, ) + regulatory_cost_summaries: MutableSequence[ + "Invoice.RegulatoryCostSummary" + ] = proto.RepeatedField( + proto.MESSAGE, + number=20, + message="Invoice.RegulatoryCostSummary", + ) + adjustment_summaries: MutableSequence["Invoice.AdjustmentSummary"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=21, + message="Invoice.AdjustmentSummary", + ) + ) class AccountBudgetSummary(proto.Message): r"""Represents a summarized account budget billable cost. @@ -451,7 +477,7 @@ class AccountBudgetSummary(proto.Message): tax amount. This field is a member of `oneof`_ ``_total_amount_micros``. - billable_activity_date_range (google.ads.googleads.v19.common.types.DateRange): + billable_activity_date_range (google.ads.googleads.v23.common.types.DateRange): Output only. The billable activity date range of the account budget, within the service date range of this invoice. The end date is @@ -483,9 +509,13 @@ class AccountBudgetSummary(proto.Message): months, in micros (negative value). This field is a member of `oneof`_ ``_invalid_activity_amount_micros``. - invalid_activity_summaries (MutableSequence[google.ads.googleads.v19.resources.types.Invoice.InvalidActivitySummary]): + invalid_activity_summaries (MutableSequence[google.ads.googleads.v23.resources.types.Invoice.InvalidActivitySummary]): Output only. The list of summarized invalid activity credits with original linkages. + campaign_summaries (MutableSequence[google.ads.googleads.v23.resources.types.Invoice.CampaignSummary]): + Output only. The list of summarized campaign + level information associated with this account + budget. """ customer: str = proto.Field( @@ -560,6 +590,13 @@ class AccountBudgetSummary(proto.Message): number=22, message="Invoice.InvalidActivitySummary", ) + campaign_summaries: MutableSequence["Invoice.CampaignSummary"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=23, + message="Invoice.CampaignSummary", + ) + ) class InvalidActivitySummary(proto.Message): r"""Details about the invalid activity for the invoice that @@ -570,7 +607,7 @@ class InvalidActivitySummary(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - original_month_of_service (google.ads.googleads.v19.enums.types.MonthOfYearEnum.MonthOfYear): + original_month_of_service (google.ads.googleads.v23.enums.types.MonthOfYearEnum.MonthOfYear): Output only. Original month of service related to this invalid activity credit. @@ -636,6 +673,128 @@ class InvalidActivitySummary(proto.Message): optional=True, ) + class CampaignSummary(proto.Message): + r"""Represents campaign level billable cost information + associated with an account budget. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + campaign_description (str): + Output only. The description of the campaign. + This is generally the same as the campaign name, + but may differ. + + This field is a member of `oneof`_ ``_campaign_description``. + quantity (int): + Output only. The quantity served for the + given unit of measure. + + This field is a member of `oneof`_ ``_quantity``. + unit_of_measure (google.ads.googleads.v23.enums.types.UnitOfMeasureEnum.UnitOfMeasure): + Output only. The unit of measure for the + quantity served. + + This field is a member of `oneof`_ ``_unit_of_measure``. + amount_micros (int): + Output only. The amount attributable to this campaign for + the given unit of measure during the service period, in + micros. The currency code for this amount is the same as the + Invoice.currency_code. + + This field is a member of `oneof`_ ``_amount_micros``. + """ + + campaign_description: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + quantity: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + unit_of_measure: ( + gage_unit_of_measure.UnitOfMeasureEnum.UnitOfMeasure + ) = proto.Field( + proto.ENUM, + number=3, + optional=True, + enum=gage_unit_of_measure.UnitOfMeasureEnum.UnitOfMeasure, + ) + amount_micros: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + + class RegulatoryCostSummary(proto.Message): + r"""Represents regulatory cost information associated with an + account. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + regulatory_fee_type (google.ads.googleads.v23.enums.types.RegulatoryFeeTypeEnum.RegulatoryFeeType): + Output only. The type of regulatory fee. + + This field is a member of `oneof`_ ``_regulatory_fee_type``. + amount_micros (int): + Output only. The amount of the regulatory fee, in micros. + The currency code for this amount is the same as the + Invoice.currency_code. + + This field is a member of `oneof`_ ``_amount_micros``. + """ + + regulatory_fee_type: ( + gage_regulatory_fee_type.RegulatoryFeeTypeEnum.RegulatoryFeeType + ) = proto.Field( + proto.ENUM, + number=1, + optional=True, + enum=gage_regulatory_fee_type.RegulatoryFeeTypeEnum.RegulatoryFeeType, + ) + amount_micros: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + + class AdjustmentSummary(proto.Message): + r"""Represents adjustment information associated with an account. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + adjustment_description (str): + Output only. The description of the + adjustment. Example: Incentive Adjustment, + discount. + + This field is a member of `oneof`_ ``_adjustment_description``. + amount_micros (int): + Output only. The amount of the adjustment, in micros. The + currency code for this amount is the same as the + Invoice.currency_code. + + This field is a member of `oneof`_ ``_amount_micros``. + """ + + adjustment_description: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + amount_micros: int = proto.Field( + proto.INT64, + number=2, + optional=True, + ) + resource_name: str = proto.Field( proto.STRING, number=1, diff --git a/google/ads/googleads/v19/resources/types/keyword_plan.py b/google/ads/googleads/v23/resources/types/keyword_plan.py similarity index 90% rename from google/ads/googleads/v19/resources/types/keyword_plan.py rename to google/ads/googleads/v23/resources/types/keyword_plan.py index 3026eea07..8263588c2 100644 --- a/google/ads/googleads/v19/resources/types/keyword_plan.py +++ b/google/ads/googleads/v23/resources/types/keyword_plan.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import dates -from google.ads.googleads.v19.enums.types import keyword_plan_forecast_interval +from google.ads.googleads.v23.common.types import dates +from google.ads.googleads.v23.enums.types import keyword_plan_forecast_interval __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlan", "KeywordPlanForecastPeriod", @@ -57,7 +57,7 @@ class KeywordPlan(proto.Message): when creating new keyword plans. This field is a member of `oneof`_ ``_name``. - forecast_period (google.ads.googleads.v19.resources.types.KeywordPlanForecastPeriod): + forecast_period (google.ads.googleads.v23.resources.types.KeywordPlanForecastPeriod): The date period used for forecasting the plan. """ @@ -94,12 +94,12 @@ class KeywordPlanForecastPeriod(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - date_interval (google.ads.googleads.v19.enums.types.KeywordPlanForecastIntervalEnum.KeywordPlanForecastInterval): + date_interval (google.ads.googleads.v23.enums.types.KeywordPlanForecastIntervalEnum.KeywordPlanForecastInterval): A future date range relative to the current date used for forecasting. This field is a member of `oneof`_ ``interval``. - date_range (google.ads.googleads.v19.common.types.DateRange): + date_range (google.ads.googleads.v23.common.types.DateRange): The custom date range used for forecasting. It cannot be greater than a year. The start and end dates must be in the future. diff --git a/google/ads/googleads/v19/resources/types/keyword_plan_ad_group.py b/google/ads/googleads/v23/resources/types/keyword_plan_ad_group.py similarity index 96% rename from google/ads/googleads/v19/resources/types/keyword_plan_ad_group.py rename to google/ads/googleads/v23/resources/types/keyword_plan_ad_group.py index 2348b3e62..ea92eb47c 100644 --- a/google/ads/googleads/v19/resources/types/keyword_plan_ad_group.py +++ b/google/ads/googleads/v23/resources/types/keyword_plan_ad_group.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanAdGroup", }, diff --git a/google/ads/googleads/v19/resources/types/keyword_plan_ad_group_keyword.py b/google/ads/googleads/v23/resources/types/keyword_plan_ad_group_keyword.py similarity index 93% rename from google/ads/googleads/v19/resources/types/keyword_plan_ad_group_keyword.py rename to google/ads/googleads/v23/resources/types/keyword_plan_ad_group_keyword.py index f3a8084be..acac65aa2 100644 --- a/google/ads/googleads/v19/resources/types/keyword_plan_ad_group_keyword.py +++ b/google/ads/googleads/v23/resources/types/keyword_plan_ad_group_keyword.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import keyword_match_type +from google.ads.googleads.v23.enums.types import keyword_match_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanAdGroupKeyword", }, @@ -58,7 +58,7 @@ class KeywordPlanAdGroupKeyword(proto.Message): The keyword text. This field is a member of `oneof`_ ``_text``. - match_type (google.ads.googleads.v19.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + match_type (google.ads.googleads.v23.enums.types.KeywordMatchTypeEnum.KeywordMatchType): The keyword match type. cpc_bid_micros (int): A keyword level max cpc bid in micros (for diff --git a/google/ads/googleads/v19/resources/types/keyword_plan_campaign.py b/google/ads/googleads/v23/resources/types/keyword_plan_campaign.py similarity index 94% rename from google/ads/googleads/v19/resources/types/keyword_plan_campaign.py rename to google/ads/googleads/v23/resources/types/keyword_plan_campaign.py index 8a26be5a8..36707c730 100644 --- a/google/ads/googleads/v19/resources/types/keyword_plan_campaign.py +++ b/google/ads/googleads/v23/resources/types/keyword_plan_campaign.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( keyword_plan_network as gage_keyword_plan_network, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanCampaign", "KeywordPlanGeoTarget", @@ -66,7 +66,7 @@ class KeywordPlanCampaign(proto.Message): language_constants (MutableSequence[str]): The languages targeted for the Keyword Plan campaign. Max allowed: 1. - keyword_plan_network (google.ads.googleads.v19.enums.types.KeywordPlanNetworkEnum.KeywordPlanNetwork): + keyword_plan_network (google.ads.googleads.v23.enums.types.KeywordPlanNetworkEnum.KeywordPlanNetwork): Targeting network. This field is required and should not be empty @@ -80,7 +80,7 @@ class KeywordPlanCampaign(proto.Message): when creating Keyword Plan campaigns. This field is a member of `oneof`_ ``_cpc_bid_micros``. - geo_targets (MutableSequence[google.ads.googleads.v19.resources.types.KeywordPlanGeoTarget]): + geo_targets (MutableSequence[google.ads.googleads.v23.resources.types.KeywordPlanGeoTarget]): The geo targets. Max number allowed: 20. """ diff --git a/google/ads/googleads/v19/resources/types/keyword_plan_campaign_keyword.py b/google/ads/googleads/v23/resources/types/keyword_plan_campaign_keyword.py similarity index 92% rename from google/ads/googleads/v19/resources/types/keyword_plan_campaign_keyword.py rename to google/ads/googleads/v23/resources/types/keyword_plan_campaign_keyword.py index 0691bb9cf..fe7fe628c 100644 --- a/google/ads/googleads/v19/resources/types/keyword_plan_campaign_keyword.py +++ b/google/ads/googleads/v23/resources/types/keyword_plan_campaign_keyword.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import keyword_match_type +from google.ads.googleads.v23.enums.types import keyword_match_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "KeywordPlanCampaignKeyword", }, @@ -58,7 +58,7 @@ class KeywordPlanCampaignKeyword(proto.Message): The keyword text. This field is a member of `oneof`_ ``_text``. - match_type (google.ads.googleads.v19.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + match_type (google.ads.googleads.v23.enums.types.KeywordMatchTypeEnum.KeywordMatchType): The keyword match type. negative (bool): Immutable. If true, the keyword is negative. diff --git a/google/ads/googleads/v19/resources/types/keyword_theme_constant.py b/google/ads/googleads/v23/resources/types/keyword_theme_constant.py similarity index 96% rename from google/ads/googleads/v19/resources/types/keyword_theme_constant.py rename to google/ads/googleads/v23/resources/types/keyword_theme_constant.py index c8149912b..2977315fb 100644 --- a/google/ads/googleads/v19/resources/types/keyword_theme_constant.py +++ b/google/ads/googleads/v23/resources/types/keyword_theme_constant.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "KeywordThemeConstant", }, diff --git a/google/ads/googleads/v19/resources/types/keyword_view.py b/google/ads/googleads/v23/resources/types/keyword_view.py similarity index 92% rename from google/ads/googleads/v19/resources/types/keyword_view.py rename to google/ads/googleads/v23/resources/types/keyword_view.py index 541f265ce..b94a51182 100644 --- a/google/ads/googleads/v19/resources/types/keyword_view.py +++ b/google/ads/googleads/v23/resources/types/keyword_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "KeywordView", }, diff --git a/google/ads/googleads/v19/resources/types/label.py b/google/ads/googleads/v23/resources/types/label.py similarity index 87% rename from google/ads/googleads/v19/resources/types/label.py rename to google/ads/googleads/v23/resources/types/label.py index e87bdc454..62e6f7f1a 100644 --- a/google/ads/googleads/v19/resources/types/label.py +++ b/google/ads/googleads/v23/resources/types/label.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import text_label as gagc_text_label -from google.ads.googleads.v19.enums.types import label_status +from google.ads.googleads.v23.common.types import text_label as gagc_text_label +from google.ads.googleads.v23.enums.types import label_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "Label", }, @@ -54,9 +54,9 @@ class Label(proto.Message): and 80, inclusive. This field is a member of `oneof`_ ``_name``. - status (google.ads.googleads.v19.enums.types.LabelStatusEnum.LabelStatus): + status (google.ads.googleads.v23.enums.types.LabelStatusEnum.LabelStatus): Output only. Status of the label. Read only. - text_label (google.ads.googleads.v19.common.types.TextLabel): + text_label (google.ads.googleads.v23.common.types.TextLabel): A type of label displaying text on a colored background. """ diff --git a/google/ads/googleads/v19/resources/types/landing_page_view.py b/google/ads/googleads/v23/resources/types/landing_page_view.py similarity index 94% rename from google/ads/googleads/v19/resources/types/landing_page_view.py rename to google/ads/googleads/v23/resources/types/landing_page_view.py index d94bccae5..56a35e498 100644 --- a/google/ads/googleads/v19/resources/types/landing_page_view.py +++ b/google/ads/googleads/v23/resources/types/landing_page_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "LandingPageView", }, diff --git a/google/ads/googleads/v19/resources/types/language_constant.py b/google/ads/googleads/v23/resources/types/language_constant.py similarity index 96% rename from google/ads/googleads/v19/resources/types/language_constant.py rename to google/ads/googleads/v23/resources/types/language_constant.py index 316129481..28eedbf3e 100644 --- a/google/ads/googleads/v19/resources/types/language_constant.py +++ b/google/ads/googleads/v23/resources/types/language_constant.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "LanguageConstant", }, diff --git a/google/ads/googleads/v19/resources/types/lead_form_submission_data.py b/google/ads/googleads/v23/resources/types/lead_form_submission_data.py similarity index 92% rename from google/ads/googleads/v19/resources/types/lead_form_submission_data.py rename to google/ads/googleads/v23/resources/types/lead_form_submission_data.py index a462b70dc..c067eaccd 100644 --- a/google/ads/googleads/v19/resources/types/lead_form_submission_data.py +++ b/google/ads/googleads/v23/resources/types/lead_form_submission_data.py @@ -19,12 +19,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import lead_form_field_user_input_type +from google.ads.googleads.v23.enums.types import lead_form_field_user_input_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "LeadFormSubmissionData", "LeadFormSubmissionField", @@ -51,10 +51,10 @@ class LeadFormSubmissionData(proto.Message): campaign (str): Output only. Campaign associated with the submitted lead form. - lead_form_submission_fields (MutableSequence[google.ads.googleads.v19.resources.types.LeadFormSubmissionField]): + lead_form_submission_fields (MutableSequence[google.ads.googleads.v23.resources.types.LeadFormSubmissionField]): Output only. Submission data associated with a lead form. - custom_lead_form_submission_fields (MutableSequence[google.ads.googleads.v19.resources.types.CustomLeadFormSubmissionField]): + custom_lead_form_submission_fields (MutableSequence[google.ads.googleads.v23.resources.types.CustomLeadFormSubmissionField]): Output only. Submission data associated with a custom lead form. ad_group (str): @@ -68,7 +68,7 @@ class LeadFormSubmissionData(proto.Message): the submissed lead form. submission_date_time (str): Output only. The date and time at which the lead form was - submitted. The format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for + submitted. The format is "yyyy-mm-dd hh:mm:ss+\|-hh:mm", for example, "2019-01-01 12:32:45-08:00". """ @@ -124,7 +124,7 @@ class LeadFormSubmissionField(proto.Message): r"""Fields in the submitted lead form. Attributes: - field_type (google.ads.googleads.v19.enums.types.LeadFormFieldUserInputTypeEnum.LeadFormFieldUserInputType): + field_type (google.ads.googleads.v23.enums.types.LeadFormFieldUserInputTypeEnum.LeadFormFieldUserInputType): Output only. Field type for lead form fields. field_value (str): Output only. Field value for lead form diff --git a/google/ads/googleads/v19/resources/types/life_event.py b/google/ads/googleads/v23/resources/types/life_event.py similarity index 92% rename from google/ads/googleads/v19/resources/types/life_event.py rename to google/ads/googleads/v23/resources/types/life_event.py index b43e9db78..3cde81517 100644 --- a/google/ads/googleads/v19/resources/types/life_event.py +++ b/google/ads/googleads/v23/resources/types/life_event.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import ( +from google.ads.googleads.v23.common.types import ( criterion_category_availability, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "LifeEvent", }, @@ -54,7 +54,7 @@ class LifeEvent(proto.Message): launched_to_all (bool): Output only. True if the life event is launched to all channels and locales. - availabilities (MutableSequence[google.ads.googleads.v19.common.types.CriterionCategoryAvailability]): + availabilities (MutableSequence[google.ads.googleads.v23.common.types.CriterionCategoryAvailability]): Output only. Availability information of the life event. """ diff --git a/google/ads/googleads/v19/resources/types/local_services_employee.py b/google/ads/googleads/v23/resources/types/local_services_employee.py similarity index 94% rename from google/ads/googleads/v19/resources/types/local_services_employee.py rename to google/ads/googleads/v23/resources/types/local_services_employee.py index b92cf1e47..19372ed1b 100644 --- a/google/ads/googleads/v19/resources/types/local_services_employee.py +++ b/google/ads/googleads/v23/resources/types/local_services_employee.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import local_services_employee_status -from google.ads.googleads.v19.enums.types import local_services_employee_type +from google.ads.googleads.v23.enums.types import local_services_employee_status +from google.ads.googleads.v23.enums.types import local_services_employee_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesEmployee", "UniversityDegree", @@ -56,18 +56,18 @@ class LocalServicesEmployee(proto.Message): The format is "YYYY-MM-DD HH:MM:SS" in the Google Ads account's timezone. Examples: "2018-03-05 09:15:00" or "2018-02-01 14:34:30". - status (google.ads.googleads.v19.enums.types.LocalServicesEmployeeStatusEnum.LocalServicesEmployeeStatus): + status (google.ads.googleads.v23.enums.types.LocalServicesEmployeeStatusEnum.LocalServicesEmployeeStatus): Output only. Employee status, such as DELETED or ENABLED. - type_ (google.ads.googleads.v19.enums.types.LocalServicesEmployeeTypeEnum.LocalServicesEmployeeType): + type_ (google.ads.googleads.v23.enums.types.LocalServicesEmployeeTypeEnum.LocalServicesEmployeeType): Output only. Employee type. - university_degrees (MutableSequence[google.ads.googleads.v19.resources.types.UniversityDegree]): + university_degrees (MutableSequence[google.ads.googleads.v23.resources.types.UniversityDegree]): Output only. A list of degrees this employee has obtained, and wants to feature. - residencies (MutableSequence[google.ads.googleads.v19.resources.types.Residency]): + residencies (MutableSequence[google.ads.googleads.v23.resources.types.Residency]): Output only. The institutions where the employee has completed their residency. - fellowships (MutableSequence[google.ads.googleads.v19.resources.types.Fellowship]): + fellowships (MutableSequence[google.ads.googleads.v23.resources.types.Fellowship]): Output only. The institutions where the employee has completed their fellowship. job_title (str): diff --git a/google/ads/googleads/v19/resources/types/local_services_lead.py b/google/ads/googleads/v23/resources/types/local_services_lead.py similarity index 90% rename from google/ads/googleads/v19/resources/types/local_services_lead.py rename to google/ads/googleads/v23/resources/types/local_services_lead.py index 617b97198..724ec0ded 100644 --- a/google/ads/googleads/v19/resources/types/local_services_lead.py +++ b/google/ads/googleads/v23/resources/types/local_services_lead.py @@ -18,16 +18,16 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( local_services_lead_credit_state, ) -from google.ads.googleads.v19.enums.types import local_services_lead_status -from google.ads.googleads.v19.enums.types import local_services_lead_type +from google.ads.googleads.v23.enums.types import local_services_lead_status +from google.ads.googleads.v23.enums.types import local_services_lead_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesLead", "ContactDetails", @@ -48,7 +48,7 @@ class LocalServicesLead(proto.Message): Attributes: resource_name (str): - Output only. The resource name of the local services lead + Immutable. The resource name of the local services lead data. Local Services Lead resource name have the form ``customers/{customer_id}/localServicesLead/{local_services_lead_id}`` @@ -64,12 +64,12 @@ class LocalServicesLead(proto.Message): Output only. Service for the category. For example: ``buyer_agent``, ``seller_agent`` for the category of ``xcat:service_area_business_real_estate_agent``. - contact_details (google.ads.googleads.v19.resources.types.ContactDetails): + contact_details (google.ads.googleads.v23.resources.types.ContactDetails): Output only. Lead's contact details. - lead_type (google.ads.googleads.v19.enums.types.LocalServicesLeadTypeEnum.LeadType): + lead_type (google.ads.googleads.v23.enums.types.LocalServicesLeadTypeEnum.LeadType): Output only. Type of Local Services lead: phone, message, booking, etc. - lead_status (google.ads.googleads.v19.enums.types.LocalServicesLeadStatusEnum.LeadStatus): + lead_status (google.ads.googleads.v23.enums.types.LocalServicesLeadStatusEnum.LeadStatus): Output only. Current status of lead. creation_date_time (str): Output only. The date time at which lead was @@ -81,7 +81,7 @@ class LocalServicesLead(proto.Message): Output only. Language used by the Local Services provider linked to lead. See https://developers.google.com/google-ads/api/data/codes-formats#locales - note (google.ads.googleads.v19.resources.types.Note): + note (google.ads.googleads.v23.resources.types.Note): Output only. Note added by advertiser for the lead. @@ -89,7 +89,7 @@ class LocalServicesLead(proto.Message): lead_charged (bool): Output only. True if the advertiser was charged for the lead. - credit_details (google.ads.googleads.v19.resources.types.CreditDetails): + credit_details (google.ads.googleads.v23.resources.types.CreditDetails): Output only. Credit details of the lead. This field is a member of `oneof`_ ``_credit_details``. @@ -222,7 +222,7 @@ class CreditDetails(proto.Message): r"""Represents the credit details of a lead. Attributes: - credit_state (google.ads.googleads.v19.enums.types.LocalServicesCreditStateEnum.CreditState): + credit_state (google.ads.googleads.v23.enums.types.LocalServicesCreditStateEnum.CreditState): Output only. Credit state of the lead. credit_state_last_update_date_time (str): Output only. The date time when the credit diff --git a/google/ads/googleads/v19/resources/types/local_services_lead_conversation.py b/google/ads/googleads/v23/resources/types/local_services_lead_conversation.py similarity index 92% rename from google/ads/googleads/v19/resources/types/local_services_lead_conversation.py rename to google/ads/googleads/v23/resources/types/local_services_lead_conversation.py index c46eca94a..01b9445c9 100644 --- a/google/ads/googleads/v19/resources/types/local_services_lead_conversation.py +++ b/google/ads/googleads/v23/resources/types/local_services_lead_conversation.py @@ -19,15 +19,15 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( local_services_conversation_type, ) -from google.ads.googleads.v19.enums.types import local_services_participant_type +from google.ads.googleads.v23.enums.types import local_services_participant_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesLeadConversation", "PhoneCallDetails", @@ -55,10 +55,10 @@ class LocalServicesLeadConversation(proto.Message): ``customers/{customer_id}/localServicesLeadConversation/{local_services_lead_conversation_id}`` id (int): Output only. ID of this Lead Conversation. - conversation_channel (google.ads.googleads.v19.enums.types.LocalServicesLeadConversationTypeEnum.ConversationType): + conversation_channel (google.ads.googleads.v23.enums.types.LocalServicesLeadConversationTypeEnum.ConversationType): Output only. Type of GLS lead conversation, EMAIL, MESSAGE, PHONE_CALL, SMS, etc. - participant_type (google.ads.googleads.v19.enums.types.LocalServicesParticipantTypeEnum.ParticipantType): + participant_type (google.ads.googleads.v23.enums.types.LocalServicesParticipantTypeEnum.ParticipantType): Output only. Type of participant in the lead conversation, ADVERTISER or CONSUMER. lead (str): @@ -70,12 +70,12 @@ class LocalServicesLeadConversation(proto.Message): The format is "YYYY-MM-DD HH:MM:SS" in the Google Ads account's timezone. Examples: "2018-03-05 09:15:00" or "2018-02-01 14:34:30". - phone_call_details (google.ads.googleads.v19.resources.types.PhoneCallDetails): + phone_call_details (google.ads.googleads.v23.resources.types.PhoneCallDetails): Output only. Details of phone call conversation in case of PHONE_CALL. This field is a member of `oneof`_ ``_phone_call_details``. - message_details (google.ads.googleads.v19.resources.types.MessageDetails): + message_details (google.ads.googleads.v23.resources.types.MessageDetails): Output only. Details of message conversation in case of EMAIL, MESSAGE or SMS. diff --git a/google/ads/googleads/v19/resources/types/local_services_verification_artifact.py b/google/ads/googleads/v23/resources/types/local_services_verification_artifact.py similarity index 91% rename from google/ads/googleads/v19/resources/types/local_services_verification_artifact.py rename to google/ads/googleads/v23/resources/types/local_services_verification_artifact.py index c42a24d9e..075ebdd6c 100644 --- a/google/ads/googleads/v19/resources/types/local_services_verification_artifact.py +++ b/google/ads/googleads/v23/resources/types/local_services_verification_artifact.py @@ -18,30 +18,30 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import local_services -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import local_services +from google.ads.googleads.v23.enums.types import ( local_services_business_registration_check_rejection_reason, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( local_services_business_registration_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( local_services_insurance_rejection_reason, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( local_services_license_rejection_reason, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( local_services_verification_artifact_status, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( local_services_verification_artifact_type, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "LocalServicesVerificationArtifact", "BackgroundCheckVerificationArtifact", @@ -82,27 +82,27 @@ class LocalServicesVerificationArtifact(proto.Message): "YYYY-MM-DD HH:MM:SS" in the Google Ads account's timezone. Examples: "2018-03-05 09:15:00" or "2018-02-01 14:34:30". - status (google.ads.googleads.v19.enums.types.LocalServicesVerificationArtifactStatusEnum.LocalServicesVerificationArtifactStatus): + status (google.ads.googleads.v23.enums.types.LocalServicesVerificationArtifactStatusEnum.LocalServicesVerificationArtifactStatus): Output only. The status of the verification artifact. - artifact_type (google.ads.googleads.v19.enums.types.LocalServicesVerificationArtifactTypeEnum.LocalServicesVerificationArtifactType): + artifact_type (google.ads.googleads.v23.enums.types.LocalServicesVerificationArtifactTypeEnum.LocalServicesVerificationArtifactType): Output only. The type of the verification artifact. - background_check_verification_artifact (google.ads.googleads.v19.resources.types.BackgroundCheckVerificationArtifact): + background_check_verification_artifact (google.ads.googleads.v23.resources.types.BackgroundCheckVerificationArtifact): Output only. A background check verification artifact. This field is a member of `oneof`_ ``artifact_data``. - insurance_verification_artifact (google.ads.googleads.v19.resources.types.InsuranceVerificationArtifact): + insurance_verification_artifact (google.ads.googleads.v23.resources.types.InsuranceVerificationArtifact): Output only. An insurance verification artifact. This field is a member of `oneof`_ ``artifact_data``. - license_verification_artifact (google.ads.googleads.v19.resources.types.LicenseVerificationArtifact): + license_verification_artifact (google.ads.googleads.v23.resources.types.LicenseVerificationArtifact): Output only. A license verification artifact. This field is a member of `oneof`_ ``artifact_data``. - business_registration_check_verification_artifact (google.ads.googleads.v19.resources.types.BusinessRegistrationCheckVerificationArtifact): + business_registration_check_verification_artifact (google.ads.googleads.v23.resources.types.BusinessRegistrationCheckVerificationArtifact): Output only. A business registration check verification artifact. @@ -216,12 +216,12 @@ class InsuranceVerificationArtifact(proto.Message): in the insurance document. This field is a member of `oneof`_ ``_amount_micros``. - rejection_reason (google.ads.googleads.v19.enums.types.LocalServicesInsuranceRejectionReasonEnum.LocalServicesInsuranceRejectionReason): + rejection_reason (google.ads.googleads.v23.enums.types.LocalServicesInsuranceRejectionReasonEnum.LocalServicesInsuranceRejectionReason): Output only. Insurance document's rejection reason. This field is a member of `oneof`_ ``_rejection_reason``. - insurance_document_readonly (google.ads.googleads.v19.common.types.LocalServicesDocumentReadOnly): + insurance_document_readonly (google.ads.googleads.v23.common.types.LocalServicesDocumentReadOnly): Output only. The readonly field containing the information for an uploaded insurance document. @@ -289,11 +289,11 @@ class LicenseVerificationArtifact(proto.Message): Output only. Last name of the licensee. This field is a member of `oneof`_ ``_licensee_last_name``. - rejection_reason (google.ads.googleads.v19.enums.types.LocalServicesLicenseRejectionReasonEnum.LocalServicesLicenseRejectionReason): + rejection_reason (google.ads.googleads.v23.enums.types.LocalServicesLicenseRejectionReasonEnum.LocalServicesLicenseRejectionReason): Output only. License rejection reason. This field is a member of `oneof`_ ``_rejection_reason``. - license_document_readonly (google.ads.googleads.v19.common.types.LocalServicesDocumentReadOnly): + license_document_readonly (google.ads.googleads.v23.common.types.LocalServicesDocumentReadOnly): Output only. The readonly field containing the information for an uploaded license document. @@ -363,7 +363,7 @@ class BusinessRegistrationCheckVerificationArtifact(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - registration_type (google.ads.googleads.v19.enums.types.LocalServicesBusinessRegistrationTypeEnum.LocalServicesBusinessRegistrationType): + registration_type (google.ads.googleads.v23.enums.types.LocalServicesBusinessRegistrationTypeEnum.LocalServicesBusinessRegistrationType): Output only. The type of business registration check (number, document). @@ -373,17 +373,17 @@ class BusinessRegistrationCheckVerificationArtifact(proto.Message): representing "VAT Tax ID" requirement. This field is a member of `oneof`_ ``_check_id``. - rejection_reason (google.ads.googleads.v19.enums.types.LocalServicesBusinessRegistrationCheckRejectionReasonEnum.LocalServicesBusinessRegistrationCheckRejectionReason): + rejection_reason (google.ads.googleads.v23.enums.types.LocalServicesBusinessRegistrationCheckRejectionReasonEnum.LocalServicesBusinessRegistrationCheckRejectionReason): Output only. Registration document rejection reason. This field is a member of `oneof`_ ``_rejection_reason``. - registration_number (google.ads.googleads.v19.resources.types.BusinessRegistrationNumber): + registration_number (google.ads.googleads.v23.resources.types.BusinessRegistrationNumber): Output only. Message storing government issued number for the business. This field is a member of `oneof`_ ``business_registration``. - registration_document (google.ads.googleads.v19.resources.types.BusinessRegistrationDocument): + registration_document (google.ads.googleads.v23.resources.types.BusinessRegistrationDocument): Output only. Message storing document info for the business. @@ -455,7 +455,7 @@ class BusinessRegistrationDocument(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - document_readonly (google.ads.googleads.v19.common.types.LocalServicesDocumentReadOnly): + document_readonly (google.ads.googleads.v23.common.types.LocalServicesDocumentReadOnly): Output only. The readonly field containing the information for an uploaded business registration document. diff --git a/google/ads/googleads/v23/resources/types/location_interest_view.py b/google/ads/googleads/v23/resources/types/location_interest_view.py new file mode 100644 index 000000000..1b4514a2e --- /dev/null +++ b/google/ads/googleads/v23/resources/types/location_interest_view.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "LocationInterestView", + }, +) + + +class LocationInterestView(proto.Message): + r"""A location interest view summarizes the performance of + adgroup location interest criteria. + + Attributes: + resource_name (str): + Output only. The resource name of the location interest + view. Location interest view resource names have the form: + + ``customers/{customer_id}/locationInterestViews/{campaign_id}~{ad_group_id}~{criterion_id}`` + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/location_view.py b/google/ads/googleads/v23/resources/types/location_view.py similarity index 94% rename from google/ads/googleads/v19/resources/types/location_view.py rename to google/ads/googleads/v23/resources/types/location_view.py index 869bed393..f5f7f4a64 100644 --- a/google/ads/googleads/v19/resources/types/location_view.py +++ b/google/ads/googleads/v23/resources/types/location_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "LocationView", }, diff --git a/google/ads/googleads/v19/resources/types/managed_placement_view.py b/google/ads/googleads/v23/resources/types/managed_placement_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/managed_placement_view.py rename to google/ads/googleads/v23/resources/types/managed_placement_view.py index c8900092d..9abd9c8ef 100644 --- a/google/ads/googleads/v19/resources/types/managed_placement_view.py +++ b/google/ads/googleads/v23/resources/types/managed_placement_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ManagedPlacementView", }, diff --git a/google/ads/googleads/v23/resources/types/matched_location_interest_view.py b/google/ads/googleads/v23/resources/types/matched_location_interest_view.py new file mode 100644 index 000000000..330199470 --- /dev/null +++ b/google/ads/googleads/v23/resources/types/matched_location_interest_view.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "MatchedLocationInterestView", + }, +) + + +class MatchedLocationInterestView(proto.Message): + r"""A view that reports metrics for locations where users showed + interest, and which matched the advertiser's location interest + targeting (defined as geo targets at the AdGroup level). The + data is aggregated at the country level by default. This view is + currently only available for AI Max campaigns. + + Attributes: + resource_name (str): + Output only. The resource name of the matched location + interest view. Matched location interest view resource names + have the form: + + ``customers/{customer_id}/matchedLocationInterestViews/{country_criterion_id}`` + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/media_file.py b/google/ads/googleads/v23/resources/types/media_file.py similarity index 93% rename from google/ads/googleads/v19/resources/types/media_file.py rename to google/ads/googleads/v23/resources/types/media_file.py index 3811bdd85..31f0edafc 100644 --- a/google/ads/googleads/v19/resources/types/media_file.py +++ b/google/ads/googleads/v23/resources/types/media_file.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import media_type -from google.ads.googleads.v19.enums.types import mime_type as gage_mime_type +from google.ads.googleads.v23.enums.types import media_type +from google.ads.googleads.v23.enums.types import mime_type as gage_mime_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "MediaFile", "MediaImage", @@ -55,9 +55,9 @@ class MediaFile(proto.Message): Output only. The ID of the media file. This field is a member of `oneof`_ ``_id``. - type_ (google.ads.googleads.v19.enums.types.MediaTypeEnum.MediaType): + type_ (google.ads.googleads.v23.enums.types.MediaTypeEnum.MediaType): Immutable. Type of the media file. - mime_type (google.ads.googleads.v19.enums.types.MimeTypeEnum.MimeType): + mime_type (google.ads.googleads.v23.enums.types.MimeTypeEnum.MimeType): Output only. The mime type of the media file. source_url (str): Immutable. The URL of where the original @@ -76,20 +76,20 @@ class MediaFile(proto.Message): bytes. This field is a member of `oneof`_ ``_file_size``. - image (google.ads.googleads.v19.resources.types.MediaImage): + image (google.ads.googleads.v23.resources.types.MediaImage): Immutable. Encapsulates an Image. This field is a member of `oneof`_ ``mediatype``. - media_bundle (google.ads.googleads.v19.resources.types.MediaBundle): + media_bundle (google.ads.googleads.v23.resources.types.MediaBundle): Immutable. A ZIP archive media the content of which contains HTML5 assets. This field is a member of `oneof`_ ``mediatype``. - audio (google.ads.googleads.v19.resources.types.MediaAudio): + audio (google.ads.googleads.v23.resources.types.MediaAudio): Output only. Encapsulates an Audio. This field is a member of `oneof`_ ``mediatype``. - video (google.ads.googleads.v19.resources.types.MediaVideo): + video (google.ads.googleads.v23.resources.types.MediaVideo): Immutable. Encapsulates a Video. This field is a member of `oneof`_ ``mediatype``. diff --git a/google/ads/googleads/v19/resources/types/mobile_app_category_constant.py b/google/ads/googleads/v23/resources/types/mobile_app_category_constant.py similarity index 95% rename from google/ads/googleads/v19/resources/types/mobile_app_category_constant.py rename to google/ads/googleads/v23/resources/types/mobile_app_category_constant.py index 60e635051..f84635ef2 100644 --- a/google/ads/googleads/v19/resources/types/mobile_app_category_constant.py +++ b/google/ads/googleads/v23/resources/types/mobile_app_category_constant.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "MobileAppCategoryConstant", }, diff --git a/google/ads/googleads/v19/resources/types/mobile_device_constant.py b/google/ads/googleads/v23/resources/types/mobile_device_constant.py similarity index 92% rename from google/ads/googleads/v19/resources/types/mobile_device_constant.py rename to google/ads/googleads/v23/resources/types/mobile_device_constant.py index 43a6d924e..c26661249 100644 --- a/google/ads/googleads/v19/resources/types/mobile_device_constant.py +++ b/google/ads/googleads/v23/resources/types/mobile_device_constant.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import mobile_device_type +from google.ads.googleads.v23.enums.types import mobile_device_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "MobileDeviceConstant", }, @@ -61,7 +61,7 @@ class MobileDeviceConstant(proto.Message): mobile device. This field is a member of `oneof`_ ``_operating_system_name``. - type_ (google.ads.googleads.v19.enums.types.MobileDeviceTypeEnum.MobileDeviceType): + type_ (google.ads.googleads.v23.enums.types.MobileDeviceTypeEnum.MobileDeviceType): Output only. The type of mobile device. """ diff --git a/google/ads/googleads/v19/resources/types/offline_conversion_upload_client_summary.py b/google/ads/googleads/v23/resources/types/offline_conversion_upload_client_summary.py similarity index 87% rename from google/ads/googleads/v19/resources/types/offline_conversion_upload_client_summary.py rename to google/ads/googleads/v23/resources/types/offline_conversion_upload_client_summary.py index 63542636b..4e24a34d5 100644 --- a/google/ads/googleads/v19/resources/types/offline_conversion_upload_client_summary.py +++ b/google/ads/googleads/v23/resources/types/offline_conversion_upload_client_summary.py @@ -19,45 +19,45 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( offline_conversion_diagnostic_status_enum, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( offline_event_upload_client_enum, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( collection_size_error as gage_collection_size_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( conversion_adjustment_upload_error as gage_conversion_adjustment_upload_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( conversion_upload_error as gage_conversion_upload_error, ) -from google.ads.googleads.v19.errors.types import date_error as gage_date_error -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import date_error as gage_date_error +from google.ads.googleads.v23.errors.types import ( distinct_error as gage_distinct_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( field_error as gage_field_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( mutate_error as gage_mutate_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( not_allowlisted_error as gage_not_allowlisted_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( string_format_error as gage_string_format_error, ) -from google.ads.googleads.v19.errors.types import ( +from google.ads.googleads.v23.errors.types import ( string_length_error as gage_string_length_error, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "OfflineConversionUploadClientSummary", "OfflineConversionSummary", @@ -77,9 +77,9 @@ class OfflineConversionUploadClientSummary(proto.Message): client summary resource names have the form: ``customers/{customer_id}/offlineConversionUploadClientSummaries/{client}`` - client (google.ads.googleads.v19.enums.types.OfflineEventUploadClientEnum.OfflineEventUploadClient): + client (google.ads.googleads.v23.enums.types.OfflineEventUploadClientEnum.OfflineEventUploadClient): Output only. Client type of the upload event. - status (google.ads.googleads.v19.enums.types.OfflineConversionDiagnosticStatusEnum.OfflineConversionDiagnosticStatus): + status (google.ads.googleads.v23.enums.types.OfflineConversionDiagnosticStatusEnum.OfflineConversionDiagnosticStatus): Output only. Overall status for offline conversion client summary. Status is generated from most recent calendar day with upload stats. @@ -100,13 +100,13 @@ class OfflineConversionUploadClientSummary(proto.Message): Output only. Date for the latest upload batch. The format is "yyyy-mm-dd hh:mm:ss", and it's in the time zone of the Google Ads account. - daily_summaries (MutableSequence[google.ads.googleads.v19.resources.types.OfflineConversionSummary]): + daily_summaries (MutableSequence[google.ads.googleads.v23.resources.types.OfflineConversionSummary]): Output only. Summary of history stats by last N days. - job_summaries (MutableSequence[google.ads.googleads.v19.resources.types.OfflineConversionSummary]): + job_summaries (MutableSequence[google.ads.googleads.v23.resources.types.OfflineConversionSummary]): Output only. Summary of history stats by last N jobs. - alerts (MutableSequence[google.ads.googleads.v19.resources.types.OfflineConversionAlert]): + alerts (MutableSequence[google.ads.googleads.v23.resources.types.OfflineConversionAlert]): Output only. Details for each error code. Alerts are generated from most recent calendar day with upload stats. @@ -231,7 +231,7 @@ class OfflineConversionAlert(proto.Message): r"""Alert for offline conversion client summary. Attributes: - error (google.ads.googleads.v19.resources.types.OfflineConversionError): + error (google.ads.googleads.v23.resources.types.OfflineConversionError): Output only. Error for offline conversion client alert. error_percentage (float): @@ -261,44 +261,44 @@ class OfflineConversionError(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - collection_size_error (google.ads.googleads.v19.errors.types.CollectionSizeErrorEnum.CollectionSizeError): + collection_size_error (google.ads.googleads.v23.errors.types.CollectionSizeErrorEnum.CollectionSizeError): Output only. Collection size error. This field is a member of `oneof`_ ``error_code``. - conversion_adjustment_upload_error (google.ads.googleads.v19.errors.types.ConversionAdjustmentUploadErrorEnum.ConversionAdjustmentUploadError): + conversion_adjustment_upload_error (google.ads.googleads.v23.errors.types.ConversionAdjustmentUploadErrorEnum.ConversionAdjustmentUploadError): Output only. Conversion adjustment upload error. This field is a member of `oneof`_ ``error_code``. - conversion_upload_error (google.ads.googleads.v19.errors.types.ConversionUploadErrorEnum.ConversionUploadError): + conversion_upload_error (google.ads.googleads.v23.errors.types.ConversionUploadErrorEnum.ConversionUploadError): Output only. Conversion upload error. This field is a member of `oneof`_ ``error_code``. - date_error (google.ads.googleads.v19.errors.types.DateErrorEnum.DateError): + date_error (google.ads.googleads.v23.errors.types.DateErrorEnum.DateError): Output only. Date error. This field is a member of `oneof`_ ``error_code``. - distinct_error (google.ads.googleads.v19.errors.types.DistinctErrorEnum.DistinctError): + distinct_error (google.ads.googleads.v23.errors.types.DistinctErrorEnum.DistinctError): Output only. Distinct error. This field is a member of `oneof`_ ``error_code``. - field_error (google.ads.googleads.v19.errors.types.FieldErrorEnum.FieldError): + field_error (google.ads.googleads.v23.errors.types.FieldErrorEnum.FieldError): Output only. Field error. This field is a member of `oneof`_ ``error_code``. - mutate_error (google.ads.googleads.v19.errors.types.MutateErrorEnum.MutateError): + mutate_error (google.ads.googleads.v23.errors.types.MutateErrorEnum.MutateError): Output only. Mutate error. This field is a member of `oneof`_ ``error_code``. - not_allowlisted_error (google.ads.googleads.v19.errors.types.NotAllowlistedErrorEnum.NotAllowlistedError): + not_allowlisted_error (google.ads.googleads.v23.errors.types.NotAllowlistedErrorEnum.NotAllowlistedError): Output only. Not allowlisted error. This field is a member of `oneof`_ ``error_code``. - string_format_error (google.ads.googleads.v19.errors.types.StringFormatErrorEnum.StringFormatError): + string_format_error (google.ads.googleads.v23.errors.types.StringFormatErrorEnum.StringFormatError): Output only. String format error. This field is a member of `oneof`_ ``error_code``. - string_length_error (google.ads.googleads.v19.errors.types.StringLengthErrorEnum.StringLengthError): + string_length_error (google.ads.googleads.v23.errors.types.StringLengthErrorEnum.StringLengthError): Output only. String length error. This field is a member of `oneof`_ ``error_code``. diff --git a/google/ads/googleads/v19/resources/types/offline_conversion_upload_conversion_action_summary.py b/google/ads/googleads/v23/resources/types/offline_conversion_upload_conversion_action_summary.py similarity index 89% rename from google/ads/googleads/v19/resources/types/offline_conversion_upload_conversion_action_summary.py rename to google/ads/googleads/v23/resources/types/offline_conversion_upload_conversion_action_summary.py index eb6e0cadc..267d888bf 100644 --- a/google/ads/googleads/v19/resources/types/offline_conversion_upload_conversion_action_summary.py +++ b/google/ads/googleads/v23/resources/types/offline_conversion_upload_conversion_action_summary.py @@ -19,20 +19,20 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( offline_conversion_diagnostic_status_enum, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( offline_event_upload_client_enum, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( offline_conversion_upload_client_summary, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "OfflineConversionUploadConversionActionSummary", }, @@ -50,14 +50,14 @@ class OfflineConversionUploadConversionActionSummary(proto.Message): have the form: ``customers/{customer_id}/offlineConversionUploadConversionActionSummaries/{conversion_action_id}~{client}`` - client (google.ads.googleads.v19.enums.types.OfflineEventUploadClientEnum.OfflineEventUploadClient): + client (google.ads.googleads.v23.enums.types.OfflineEventUploadClientEnum.OfflineEventUploadClient): Output only. Client type of the upload event. conversion_action_id (int): Output only. Conversion action id. conversion_action_name (str): Output only. The name of the conversion action. - status (google.ads.googleads.v19.enums.types.OfflineConversionDiagnosticStatusEnum.OfflineConversionDiagnosticStatus): + status (google.ads.googleads.v23.enums.types.OfflineConversionDiagnosticStatusEnum.OfflineConversionDiagnosticStatus): Output only. Overall status for offline conversion upload conversion action summary. Status is generated from most recent calendar @@ -74,13 +74,13 @@ class OfflineConversionUploadConversionActionSummary(proto.Message): Output only. Date for the latest upload batch. The format is "yyyy-mm-dd hh:mm:ss", and it's in the time zone of the Google Ads account. - daily_summaries (MutableSequence[google.ads.googleads.v19.resources.types.OfflineConversionSummary]): + daily_summaries (MutableSequence[google.ads.googleads.v23.resources.types.OfflineConversionSummary]): Output only. Summary of history stats by last N days. - job_summaries (MutableSequence[google.ads.googleads.v19.resources.types.OfflineConversionSummary]): + job_summaries (MutableSequence[google.ads.googleads.v23.resources.types.OfflineConversionSummary]): Output only. Summary of history stats by last N jobs. - alerts (MutableSequence[google.ads.googleads.v19.resources.types.OfflineConversionAlert]): + alerts (MutableSequence[google.ads.googleads.v23.resources.types.OfflineConversionAlert]): Output only. Details for each error code. Alerts are generated from most recent calendar day with upload stats. diff --git a/google/ads/googleads/v19/resources/types/offline_user_data_job.py b/google/ads/googleads/v23/resources/types/offline_user_data_job.py similarity index 87% rename from google/ads/googleads/v19/resources/types/offline_user_data_job.py rename to google/ads/googleads/v23/resources/types/offline_user_data_job.py index e7eac4d8a..32ee8b19f 100644 --- a/google/ads/googleads/v19/resources/types/offline_user_data_job.py +++ b/google/ads/googleads/v23/resources/types/offline_user_data_job.py @@ -18,20 +18,20 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import offline_user_data -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import offline_user_data +from google.ads.googleads.v23.enums.types import ( offline_user_data_job_failure_reason, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( offline_user_data_job_match_rate_range, ) -from google.ads.googleads.v19.enums.types import offline_user_data_job_status -from google.ads.googleads.v19.enums.types import offline_user_data_job_type +from google.ads.googleads.v23.enums.types import offline_user_data_job_status +from google.ads.googleads.v23.enums.types import offline_user_data_job_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "OfflineUserDataJob", "OfflineUserDataJobMetadata", @@ -67,22 +67,22 @@ class OfflineUserDataJob(proto.Message): Immutable. User specified job ID. This field is a member of `oneof`_ ``_external_id``. - type_ (google.ads.googleads.v19.enums.types.OfflineUserDataJobTypeEnum.OfflineUserDataJobType): + type_ (google.ads.googleads.v23.enums.types.OfflineUserDataJobTypeEnum.OfflineUserDataJobType): Immutable. Type of the job. - status (google.ads.googleads.v19.enums.types.OfflineUserDataJobStatusEnum.OfflineUserDataJobStatus): + status (google.ads.googleads.v23.enums.types.OfflineUserDataJobStatusEnum.OfflineUserDataJobStatus): Output only. Status of the job. - failure_reason (google.ads.googleads.v19.enums.types.OfflineUserDataJobFailureReasonEnum.OfflineUserDataJobFailureReason): + failure_reason (google.ads.googleads.v23.enums.types.OfflineUserDataJobFailureReasonEnum.OfflineUserDataJobFailureReason): Output only. Reason for the processing failure, if status is FAILED. - operation_metadata (google.ads.googleads.v19.resources.types.OfflineUserDataJobMetadata): + operation_metadata (google.ads.googleads.v23.resources.types.OfflineUserDataJobMetadata): Output only. Metadata of offline user data job depicting match rate range. - customer_match_user_list_metadata (google.ads.googleads.v19.common.types.CustomerMatchUserListMetadata): + customer_match_user_list_metadata (google.ads.googleads.v23.common.types.CustomerMatchUserListMetadata): Immutable. Metadata for data updates to a CRM-based user list. This field is a member of `oneof`_ ``metadata``. - store_sales_metadata (google.ads.googleads.v19.common.types.StoreSalesMetadata): + store_sales_metadata (google.ads.googleads.v23.common.types.StoreSalesMetadata): Immutable. Metadata for store sales data update. @@ -149,7 +149,7 @@ class OfflineUserDataJobMetadata(proto.Message): r"""Metadata of offline user data job. Attributes: - match_rate_range (google.ads.googleads.v19.enums.types.OfflineUserDataJobMatchRateRangeEnum.OfflineUserDataJobMatchRateRange): + match_rate_range (google.ads.googleads.v23.enums.types.OfflineUserDataJobMatchRateRangeEnum.OfflineUserDataJobMatchRateRange): Output only. Match rate of the Customer Match user list upload. Describes the estimated match rate when the status of the job is "RUNNING" and diff --git a/google/ads/googleads/v19/resources/types/operating_system_version_constant.py b/google/ads/googleads/v23/resources/types/operating_system_version_constant.py similarity index 93% rename from google/ads/googleads/v19/resources/types/operating_system_version_constant.py rename to google/ads/googleads/v23/resources/types/operating_system_version_constant.py index 463c2cff7..39de6c580 100644 --- a/google/ads/googleads/v19/resources/types/operating_system_version_constant.py +++ b/google/ads/googleads/v23/resources/types/operating_system_version_constant.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( operating_system_version_operator_type, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "OperatingSystemVersionConstant", }, @@ -64,7 +64,7 @@ class OperatingSystemVersionConstant(proto.Message): Output only. The OS Minor Version number. This field is a member of `oneof`_ ``_os_minor_version``. - operator_type (google.ads.googleads.v19.enums.types.OperatingSystemVersionOperatorTypeEnum.OperatingSystemVersionOperatorType): + operator_type (google.ads.googleads.v23.enums.types.OperatingSystemVersionOperatorTypeEnum.OperatingSystemVersionOperatorType): Output only. Determines whether this constant represents a single version or a range of versions. diff --git a/google/ads/googleads/v19/resources/types/paid_organic_search_term_view.py b/google/ads/googleads/v23/resources/types/paid_organic_search_term_view.py similarity index 95% rename from google/ads/googleads/v19/resources/types/paid_organic_search_term_view.py rename to google/ads/googleads/v23/resources/types/paid_organic_search_term_view.py index d8cc91f3d..311eaf5f3 100644 --- a/google/ads/googleads/v19/resources/types/paid_organic_search_term_view.py +++ b/google/ads/googleads/v23/resources/types/paid_organic_search_term_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "PaidOrganicSearchTermView", }, diff --git a/google/ads/googleads/v19/resources/types/parental_status_view.py b/google/ads/googleads/v23/resources/types/parental_status_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/parental_status_view.py rename to google/ads/googleads/v23/resources/types/parental_status_view.py index 075fe34fc..52b5ebe17 100644 --- a/google/ads/googleads/v19/resources/types/parental_status_view.py +++ b/google/ads/googleads/v23/resources/types/parental_status_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ParentalStatusView", }, diff --git a/google/ads/googleads/v19/resources/types/payments_account.py b/google/ads/googleads/v23/resources/types/payments_account.py similarity index 97% rename from google/ads/googleads/v19/resources/types/payments_account.py rename to google/ads/googleads/v23/resources/types/payments_account.py index ca011d3e9..38de55ec7 100644 --- a/google/ads/googleads/v19/resources/types/payments_account.py +++ b/google/ads/googleads/v23/resources/types/payments_account.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "PaymentsAccount", }, diff --git a/google/ads/googleads/v23/resources/types/per_store_view.py b/google/ads/googleads/v23/resources/types/per_store_view.py new file mode 100644 index 000000000..cb608978c --- /dev/null +++ b/google/ads/googleads/v23/resources/types/per_store_view.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "PerStoreView", + }, +) + + +class PerStoreView(proto.Message): + r"""A per store view. + This view provides per store impression reach and local action + conversion stats for advertisers. + + Attributes: + resource_name (str): + Output only. The resource name of the per store view. Per + Store view resource names have the form: + + ``customers/{customer_id}/perStoreViews/{place_id}`` + place_id (str): + Output only. The place ID of the per store + view. + address1 (str): + Output only. First line of the store's + address. + address2 (str): + Output only. Second line of the store's + address. + business_name (str): + Output only. The name of the business. + city (str): + Output only. The city where the store is + located. + country_code (str): + Output only. The two-letter country code for + the store's location (e.g., "US"). + phone_number (str): + Output only. The phone number of the store. + postal_code (str): + Output only. The postal code of the store's + address. + province (str): + Output only. The province or state of the + store's address. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + place_id: str = proto.Field( + proto.STRING, + number=2, + ) + address1: str = proto.Field( + proto.STRING, + number=3, + ) + address2: str = proto.Field( + proto.STRING, + number=4, + ) + business_name: str = proto.Field( + proto.STRING, + number=5, + ) + city: str = proto.Field( + proto.STRING, + number=6, + ) + country_code: str = proto.Field( + proto.STRING, + number=7, + ) + phone_number: str = proto.Field( + proto.STRING, + number=8, + ) + postal_code: str = proto.Field( + proto.STRING, + number=9, + ) + province: str = proto.Field( + proto.STRING, + number=10, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/performance_max_placement_view.py b/google/ads/googleads/v23/resources/types/performance_max_placement_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/performance_max_placement_view.py rename to google/ads/googleads/v23/resources/types/performance_max_placement_view.py index 2370501f9..68cb165a2 100644 --- a/google/ads/googleads/v19/resources/types/performance_max_placement_view.py +++ b/google/ads/googleads/v23/resources/types/performance_max_placement_view.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( placement_type as gage_placement_type, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "PerformanceMaxPlacementView", }, @@ -65,7 +65,7 @@ class PerformanceMaxPlacementView(proto.Message): in app store, or a YouTube video URL. This field is a member of `oneof`_ ``_target_url``. - placement_type (google.ads.googleads.v19.enums.types.PlacementTypeEnum.PlacementType): + placement_type (google.ads.googleads.v23.enums.types.PlacementTypeEnum.PlacementType): Output only. Type of the placement. Possible values for Performance Max placements are WEBSITE, MOBILE_APPLICATION, or YOUTUBE_VIDEO. diff --git a/google/ads/googleads/v19/resources/types/product_category_constant.py b/google/ads/googleads/v23/resources/types/product_category_constant.py similarity index 90% rename from google/ads/googleads/v19/resources/types/product_category_constant.py rename to google/ads/googleads/v23/resources/types/product_category_constant.py index e3040fdee..22f94b21d 100644 --- a/google/ads/googleads/v19/resources/types/product_category_constant.py +++ b/google/ads/googleads/v23/resources/types/product_category_constant.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import product_category_level -from google.ads.googleads.v19.enums.types import product_category_state +from google.ads.googleads.v23.enums.types import product_category_level +from google.ads.googleads.v23.enums.types import product_category_state __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ProductCategoryConstant", }, @@ -54,11 +54,11 @@ class ProductCategoryConstant(proto.Message): product category. This field is a member of `oneof`_ ``_product_category_constant_parent``. - level (google.ads.googleads.v19.enums.types.ProductCategoryLevelEnum.ProductCategoryLevel): + level (google.ads.googleads.v23.enums.types.ProductCategoryLevelEnum.ProductCategoryLevel): Output only. Level of the product category. - state (google.ads.googleads.v19.enums.types.ProductCategoryStateEnum.ProductCategoryState): + state (google.ads.googleads.v23.enums.types.ProductCategoryStateEnum.ProductCategoryState): Output only. State of the product category. - localizations (MutableSequence[google.ads.googleads.v19.resources.types.ProductCategoryConstant.ProductCategoryLocalization]): + localizations (MutableSequence[google.ads.googleads.v23.resources.types.ProductCategoryConstant.ProductCategoryLocalization]): Output only. List of all available localizations of the product category. """ diff --git a/google/ads/googleads/v19/resources/types/product_group_view.py b/google/ads/googleads/v23/resources/types/product_group_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/product_group_view.py rename to google/ads/googleads/v23/resources/types/product_group_view.py index 7db33bbf9..e81439591 100644 --- a/google/ads/googleads/v19/resources/types/product_group_view.py +++ b/google/ads/googleads/v23/resources/types/product_group_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ProductGroupView", }, diff --git a/google/ads/googleads/v19/resources/types/product_link.py b/google/ads/googleads/v23/resources/types/product_link.py similarity index 93% rename from google/ads/googleads/v19/resources/types/product_link.py rename to google/ads/googleads/v23/resources/types/product_link.py index b002fa5b4..5b9713106 100644 --- a/google/ads/googleads/v19/resources/types/product_link.py +++ b/google/ads/googleads/v23/resources/types/product_link.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import linked_product_type +from google.ads.googleads.v23.enums.types import linked_product_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ProductLink", "DataPartnerIdentifier", @@ -56,21 +56,21 @@ class ProductLink(proto.Message): This field is read only. This field is a member of `oneof`_ ``_product_link_id``. - type_ (google.ads.googleads.v19.enums.types.LinkedProductTypeEnum.LinkedProductType): + type_ (google.ads.googleads.v23.enums.types.LinkedProductTypeEnum.LinkedProductType): Output only. The type of the linked product. - data_partner (google.ads.googleads.v19.resources.types.DataPartnerIdentifier): + data_partner (google.ads.googleads.v23.resources.types.DataPartnerIdentifier): Immutable. Data partner link. This field is a member of `oneof`_ ``linked_product``. - google_ads (google.ads.googleads.v19.resources.types.GoogleAdsIdentifier): + google_ads (google.ads.googleads.v23.resources.types.GoogleAdsIdentifier): Immutable. Google Ads link. This field is a member of `oneof`_ ``linked_product``. - merchant_center (google.ads.googleads.v19.resources.types.MerchantCenterIdentifier): + merchant_center (google.ads.googleads.v23.resources.types.MerchantCenterIdentifier): Immutable. Google Merchant Center link. This field is a member of `oneof`_ ``linked_product``. - advertising_partner (google.ads.googleads.v19.resources.types.AdvertisingPartnerIdentifier): + advertising_partner (google.ads.googleads.v23.resources.types.AdvertisingPartnerIdentifier): Output only. Advertising Partner link. This field is a member of `oneof`_ ``linked_product``. diff --git a/google/ads/googleads/v19/resources/types/product_link_invitation.py b/google/ads/googleads/v23/resources/types/product_link_invitation.py similarity index 91% rename from google/ads/googleads/v19/resources/types/product_link_invitation.py rename to google/ads/googleads/v23/resources/types/product_link_invitation.py index 23f63ea2c..0d7f61875 100644 --- a/google/ads/googleads/v19/resources/types/product_link_invitation.py +++ b/google/ads/googleads/v23/resources/types/product_link_invitation.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import linked_product_type -from google.ads.googleads.v19.enums.types import product_link_invitation_status +from google.ads.googleads.v23.enums.types import linked_product_type +from google.ads.googleads.v23.enums.types import product_link_invitation_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ProductLinkInvitation", "HotelCenterLinkInvitationIdentifier", @@ -54,23 +54,23 @@ class ProductLinkInvitation(proto.Message): product_link_invitation_id (int): Output only. The ID of the product link invitation. This field is read only. - status (google.ads.googleads.v19.enums.types.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus): + status (google.ads.googleads.v23.enums.types.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus): Output only. The status of the product link invitation. This field is read only. - type_ (google.ads.googleads.v19.enums.types.LinkedProductTypeEnum.LinkedProductType): + type_ (google.ads.googleads.v23.enums.types.LinkedProductTypeEnum.LinkedProductType): Output only. The type of the invited account. This field is read only and can be used for filtering invitations with {@code GoogleAdsService.SearchGoogleAdsRequest}. - hotel_center (google.ads.googleads.v19.resources.types.HotelCenterLinkInvitationIdentifier): + hotel_center (google.ads.googleads.v23.resources.types.HotelCenterLinkInvitationIdentifier): Output only. Hotel link invitation. This field is a member of `oneof`_ ``invited_account``. - merchant_center (google.ads.googleads.v19.resources.types.MerchantCenterLinkInvitationIdentifier): + merchant_center (google.ads.googleads.v23.resources.types.MerchantCenterLinkInvitationIdentifier): Output only. Merchant Center link invitation. This field is a member of `oneof`_ ``invited_account``. - advertising_partner (google.ads.googleads.v19.resources.types.AdvertisingPartnerLinkInvitationIdentifier): + advertising_partner (google.ads.googleads.v23.resources.types.AdvertisingPartnerLinkInvitationIdentifier): Output only. Advertising Partner link invitation. diff --git a/google/ads/googleads/v19/resources/types/qualifying_question.py b/google/ads/googleads/v23/resources/types/qualifying_question.py similarity index 94% rename from google/ads/googleads/v19/resources/types/qualifying_question.py rename to google/ads/googleads/v23/resources/types/qualifying_question.py index 140671725..835b7457c 100644 --- a/google/ads/googleads/v19/resources/types/qualifying_question.py +++ b/google/ads/googleads/v23/resources/types/qualifying_question.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "QualifyingQuestion", }, diff --git a/google/ads/googleads/v19/resources/types/recommendation.py b/google/ads/googleads/v23/resources/types/recommendation.py similarity index 91% rename from google/ads/googleads/v19/resources/types/recommendation.py rename to google/ads/googleads/v23/resources/types/recommendation.py index 3d320a34c..48100d40c 100644 --- a/google/ads/googleads/v19/resources/types/recommendation.py +++ b/google/ads/googleads/v23/resources/types/recommendation.py @@ -19,26 +19,26 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.enums.types import ad_strength as gage_ad_strength -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import ad_strength as gage_ad_strength +from google.ads.googleads.v23.enums.types import ( app_bidding_goal as gage_app_bidding_goal, ) -from google.ads.googleads.v19.enums.types import keyword_match_type -from google.ads.googleads.v19.enums.types import recommendation_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import keyword_match_type +from google.ads.googleads.v23.enums.types import recommendation_type +from google.ads.googleads.v23.enums.types import ( shopping_add_products_to_campaign_recommendation_enum, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( target_cpa_opt_in_recommendation_goal, ) -from google.ads.googleads.v19.resources.types import ad as gagr_ad -from google.ads.googleads.v19.resources.types import asset +from google.ads.googleads.v23.resources.types import ad as gagr_ad +from google.ads.googleads.v23.resources.types import asset __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "Recommendation", }, @@ -60,9 +60,9 @@ class Recommendation(proto.Message): Immutable. The resource name of the recommendation. ``customers/{customer_id}/recommendations/{recommendation_id}`` - type_ (google.ads.googleads.v19.enums.types.RecommendationTypeEnum.RecommendationType): + type_ (google.ads.googleads.v23.enums.types.RecommendationTypeEnum.RecommendationType): Output only. The type of recommendation. - impact (google.ads.googleads.v19.resources.types.Recommendation.RecommendationImpact): + impact (google.ads.googleads.v23.resources.types.Recommendation.RecommendationImpact): Output only. The impact on account performance as a result of applying the recommendation. @@ -126,275 +126,275 @@ class Recommendation(proto.Message): This field will be set for the following recommendation types: CAMPAIGN_BUDGET, FORECASTING_CAMPAIGN_BUDGET, MARGINAL_ROI_CAMPAIGN_BUDGET and MOVE_UNUSED_BUDGET - campaign_budget_recommendation (google.ads.googleads.v19.resources.types.Recommendation.CampaignBudgetRecommendation): + campaign_budget_recommendation (google.ads.googleads.v23.resources.types.Recommendation.CampaignBudgetRecommendation): Output only. The campaign budget recommendation. This field is a member of `oneof`_ ``recommendation``. - forecasting_campaign_budget_recommendation (google.ads.googleads.v19.resources.types.Recommendation.CampaignBudgetRecommendation): + forecasting_campaign_budget_recommendation (google.ads.googleads.v23.resources.types.Recommendation.CampaignBudgetRecommendation): Output only. The forecasting campaign budget recommendation. This field is a member of `oneof`_ ``recommendation``. - keyword_recommendation (google.ads.googleads.v19.resources.types.Recommendation.KeywordRecommendation): + keyword_recommendation (google.ads.googleads.v23.resources.types.Recommendation.KeywordRecommendation): Output only. The keyword recommendation. This field is a member of `oneof`_ ``recommendation``. - text_ad_recommendation (google.ads.googleads.v19.resources.types.Recommendation.TextAdRecommendation): + text_ad_recommendation (google.ads.googleads.v23.resources.types.Recommendation.TextAdRecommendation): Output only. Add expanded text ad recommendation. This field is a member of `oneof`_ ``recommendation``. - target_cpa_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.TargetCpaOptInRecommendation): + target_cpa_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.TargetCpaOptInRecommendation): Output only. The TargetCPA opt-in recommendation. This field is a member of `oneof`_ ``recommendation``. - maximize_conversions_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.MaximizeConversionsOptInRecommendation): + maximize_conversions_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.MaximizeConversionsOptInRecommendation): Output only. The MaximizeConversions Opt-In recommendation. This field is a member of `oneof`_ ``recommendation``. - enhanced_cpc_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.EnhancedCpcOptInRecommendation): + enhanced_cpc_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.EnhancedCpcOptInRecommendation): Output only. The Enhanced Cost-Per-Click Opt-In recommendation. This field is a member of `oneof`_ ``recommendation``. - search_partners_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.SearchPartnersOptInRecommendation): + search_partners_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.SearchPartnersOptInRecommendation): Output only. The Search Partners Opt-In recommendation. This field is a member of `oneof`_ ``recommendation``. - maximize_clicks_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.MaximizeClicksOptInRecommendation): + maximize_clicks_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.MaximizeClicksOptInRecommendation): Output only. The MaximizeClicks Opt-In recommendation. This field is a member of `oneof`_ ``recommendation``. - optimize_ad_rotation_recommendation (google.ads.googleads.v19.resources.types.Recommendation.OptimizeAdRotationRecommendation): + optimize_ad_rotation_recommendation (google.ads.googleads.v23.resources.types.Recommendation.OptimizeAdRotationRecommendation): Output only. The Optimize Ad Rotation recommendation. This field is a member of `oneof`_ ``recommendation``. - keyword_match_type_recommendation (google.ads.googleads.v19.resources.types.Recommendation.KeywordMatchTypeRecommendation): + keyword_match_type_recommendation (google.ads.googleads.v23.resources.types.Recommendation.KeywordMatchTypeRecommendation): Output only. The keyword match type recommendation. This field is a member of `oneof`_ ``recommendation``. - move_unused_budget_recommendation (google.ads.googleads.v19.resources.types.Recommendation.MoveUnusedBudgetRecommendation): + move_unused_budget_recommendation (google.ads.googleads.v23.resources.types.Recommendation.MoveUnusedBudgetRecommendation): Output only. The move unused budget recommendation. This field is a member of `oneof`_ ``recommendation``. - target_roas_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.TargetRoasOptInRecommendation): + target_roas_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.TargetRoasOptInRecommendation): Output only. The Target ROAS opt-in recommendation. This field is a member of `oneof`_ ``recommendation``. - responsive_search_ad_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ResponsiveSearchAdRecommendation): + responsive_search_ad_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ResponsiveSearchAdRecommendation): Output only. The add responsive search ad recommendation. This field is a member of `oneof`_ ``recommendation``. - marginal_roi_campaign_budget_recommendation (google.ads.googleads.v19.resources.types.Recommendation.CampaignBudgetRecommendation): + marginal_roi_campaign_budget_recommendation (google.ads.googleads.v23.resources.types.Recommendation.CampaignBudgetRecommendation): Output only. The marginal ROI campaign budget recommendation. This field is a member of `oneof`_ ``recommendation``. - use_broad_match_keyword_recommendation (google.ads.googleads.v19.resources.types.Recommendation.UseBroadMatchKeywordRecommendation): + use_broad_match_keyword_recommendation (google.ads.googleads.v23.resources.types.Recommendation.UseBroadMatchKeywordRecommendation): Output only. The use broad match keyword recommendation. This field is a member of `oneof`_ ``recommendation``. - responsive_search_ad_asset_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ResponsiveSearchAdAssetRecommendation): + responsive_search_ad_asset_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ResponsiveSearchAdAssetRecommendation): Output only. The responsive search ad asset recommendation. This field is a member of `oneof`_ ``recommendation``. - upgrade_smart_shopping_campaign_to_performance_max_recommendation (google.ads.googleads.v19.resources.types.Recommendation.UpgradeSmartShoppingCampaignToPerformanceMaxRecommendation): + upgrade_smart_shopping_campaign_to_performance_max_recommendation (google.ads.googleads.v23.resources.types.Recommendation.UpgradeSmartShoppingCampaignToPerformanceMaxRecommendation): Output only. The upgrade a Smart Shopping campaign to a Performance Max campaign recommendation. This field is a member of `oneof`_ ``recommendation``. - responsive_search_ad_improve_ad_strength_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ResponsiveSearchAdImproveAdStrengthRecommendation): + responsive_search_ad_improve_ad_strength_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ResponsiveSearchAdImproveAdStrengthRecommendation): Output only. The responsive search ad improve ad strength recommendation. This field is a member of `oneof`_ ``recommendation``. - display_expansion_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.DisplayExpansionOptInRecommendation): + display_expansion_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.DisplayExpansionOptInRecommendation): Output only. The Display Expansion opt-in recommendation. This field is a member of `oneof`_ ``recommendation``. - upgrade_local_campaign_to_performance_max_recommendation (google.ads.googleads.v19.resources.types.Recommendation.UpgradeLocalCampaignToPerformanceMaxRecommendation): + upgrade_local_campaign_to_performance_max_recommendation (google.ads.googleads.v23.resources.types.Recommendation.UpgradeLocalCampaignToPerformanceMaxRecommendation): Output only. The upgrade a Local campaign to a Performance Max campaign recommendation. This field is a member of `oneof`_ ``recommendation``. - raise_target_cpa_bid_too_low_recommendation (google.ads.googleads.v19.resources.types.Recommendation.RaiseTargetCpaBidTooLowRecommendation): + raise_target_cpa_bid_too_low_recommendation (google.ads.googleads.v23.resources.types.Recommendation.RaiseTargetCpaBidTooLowRecommendation): Output only. The raise target CPA bid too low recommendation. This field is a member of `oneof`_ ``recommendation``. - forecasting_set_target_roas_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ForecastingSetTargetRoasRecommendation): + forecasting_set_target_roas_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ForecastingSetTargetRoasRecommendation): Output only. The forecasting set target ROAS recommendation. This field is a member of `oneof`_ ``recommendation``. - callout_asset_recommendation (google.ads.googleads.v19.resources.types.Recommendation.CalloutAssetRecommendation): + callout_asset_recommendation (google.ads.googleads.v23.resources.types.Recommendation.CalloutAssetRecommendation): Output only. The callout asset recommendation. This field is a member of `oneof`_ ``recommendation``. - sitelink_asset_recommendation (google.ads.googleads.v19.resources.types.Recommendation.SitelinkAssetRecommendation): + sitelink_asset_recommendation (google.ads.googleads.v23.resources.types.Recommendation.SitelinkAssetRecommendation): Output only. The sitelink asset recommendation. This field is a member of `oneof`_ ``recommendation``. - call_asset_recommendation (google.ads.googleads.v19.resources.types.Recommendation.CallAssetRecommendation): + call_asset_recommendation (google.ads.googleads.v23.resources.types.Recommendation.CallAssetRecommendation): Output only. The call asset recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_add_age_group_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): + shopping_add_age_group_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): Output only. The shopping add age group recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_add_color_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): + shopping_add_color_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): Output only. The shopping add color recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_add_gender_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): + shopping_add_gender_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): Output only. The shopping add gender recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_add_gtin_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): + shopping_add_gtin_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): Output only. The shopping add GTIN recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_add_more_identifiers_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): + shopping_add_more_identifiers_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): Output only. The shopping add more identifiers recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_add_size_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): + shopping_add_size_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingOfferAttributeRecommendation): Output only. The shopping add size recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_add_products_to_campaign_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingAddProductsToCampaignRecommendation): + shopping_add_products_to_campaign_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingAddProductsToCampaignRecommendation): Output only. The shopping add products to campaign recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_fix_disapproved_products_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingFixDisapprovedProductsRecommendation): + shopping_fix_disapproved_products_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingFixDisapprovedProductsRecommendation): Output only. The shopping fix disapproved products recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_target_all_offers_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingTargetAllOffersRecommendation): + shopping_target_all_offers_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingTargetAllOffersRecommendation): Output only. The shopping target all offers recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_fix_suspended_merchant_center_account_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingMerchantCenterAccountSuspensionRecommendation): + shopping_fix_suspended_merchant_center_account_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingMerchantCenterAccountSuspensionRecommendation): Output only. The shopping fix suspended Merchant Center account recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_fix_merchant_center_account_suspension_warning_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingMerchantCenterAccountSuspensionRecommendation): + shopping_fix_merchant_center_account_suspension_warning_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingMerchantCenterAccountSuspensionRecommendation): Output only. The shopping fix Merchant Center account suspension warning recommendation. This field is a member of `oneof`_ ``recommendation``. - shopping_migrate_regular_shopping_campaign_offers_to_performance_max_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ShoppingMigrateRegularShoppingCampaignOffersToPerformanceMaxRecommendation): + shopping_migrate_regular_shopping_campaign_offers_to_performance_max_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ShoppingMigrateRegularShoppingCampaignOffersToPerformanceMaxRecommendation): Output only. The shopping migrate Regular Shopping Campaign offers to Performance Max recommendation. This field is a member of `oneof`_ ``recommendation``. - dynamic_image_extension_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.DynamicImageExtensionOptInRecommendation): + dynamic_image_extension_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.DynamicImageExtensionOptInRecommendation): Output only. Recommendation to enable dynamic image extensions on the account, allowing Google to find the best images from ad landing pages and complement text ads. This field is a member of `oneof`_ ``recommendation``. - raise_target_cpa_recommendation (google.ads.googleads.v19.resources.types.Recommendation.RaiseTargetCpaRecommendation): + raise_target_cpa_recommendation (google.ads.googleads.v23.resources.types.Recommendation.RaiseTargetCpaRecommendation): Output only. Recommendation to raise Target CPA. This field is a member of `oneof`_ ``recommendation``. - lower_target_roas_recommendation (google.ads.googleads.v19.resources.types.Recommendation.LowerTargetRoasRecommendation): + lower_target_roas_recommendation (google.ads.googleads.v23.resources.types.Recommendation.LowerTargetRoasRecommendation): Output only. Recommendation to lower Target ROAS. This field is a member of `oneof`_ ``recommendation``. - performance_max_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.PerformanceMaxOptInRecommendation): + performance_max_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.PerformanceMaxOptInRecommendation): Output only. The Performance Max Opt In recommendation. This field is a member of `oneof`_ ``recommendation``. - improve_performance_max_ad_strength_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ImprovePerformanceMaxAdStrengthRecommendation): + improve_performance_max_ad_strength_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ImprovePerformanceMaxAdStrengthRecommendation): Output only. The improve Performance Max ad strength recommendation. This field is a member of `oneof`_ ``recommendation``. - migrate_dynamic_search_ads_campaign_to_performance_max_recommendation (google.ads.googleads.v19.resources.types.Recommendation.MigrateDynamicSearchAdsCampaignToPerformanceMaxRecommendation): + migrate_dynamic_search_ads_campaign_to_performance_max_recommendation (google.ads.googleads.v23.resources.types.Recommendation.MigrateDynamicSearchAdsCampaignToPerformanceMaxRecommendation): Output only. The Dynamic Search Ads to Performance Max migration recommendation. This field is a member of `oneof`_ ``recommendation``. - forecasting_set_target_cpa_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ForecastingSetTargetCpaRecommendation): + forecasting_set_target_cpa_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ForecastingSetTargetCpaRecommendation): Output only. The forecasting set target CPA recommendation. This field is a member of `oneof`_ ``recommendation``. - set_target_cpa_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ForecastingSetTargetCpaRecommendation): + set_target_cpa_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ForecastingSetTargetCpaRecommendation): Output only. The set target CPA recommendation. This field is a member of `oneof`_ ``recommendation``. - set_target_roas_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ForecastingSetTargetRoasRecommendation): + set_target_roas_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ForecastingSetTargetRoasRecommendation): Output only. The set target ROAS recommendation. This field is a member of `oneof`_ ``recommendation``. - maximize_conversion_value_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.MaximizeConversionValueOptInRecommendation): + maximize_conversion_value_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.MaximizeConversionValueOptInRecommendation): Output only. The Maximize Conversion Value opt-in recommendation. This field is a member of `oneof`_ ``recommendation``. - improve_google_tag_coverage_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ImproveGoogleTagCoverageRecommendation): + improve_google_tag_coverage_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ImproveGoogleTagCoverageRecommendation): Output only. Recommendation to deploy Google Tag on more pages. This field is a member of `oneof`_ ``recommendation``. - performance_max_final_url_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.PerformanceMaxFinalUrlOptInRecommendation): + performance_max_final_url_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.PerformanceMaxFinalUrlOptInRecommendation): Output only. Recommendation to turn on Final URL expansion for your Performance Max campaigns. This field is a member of `oneof`_ ``recommendation``. - refresh_customer_match_list_recommendation (google.ads.googleads.v19.resources.types.Recommendation.RefreshCustomerMatchListRecommendation): + refresh_customer_match_list_recommendation (google.ads.googleads.v23.resources.types.Recommendation.RefreshCustomerMatchListRecommendation): Output only. The refresh customer list recommendation. This field is a member of `oneof`_ ``recommendation``. - custom_audience_opt_in_recommendation (google.ads.googleads.v19.resources.types.Recommendation.CustomAudienceOptInRecommendation): + custom_audience_opt_in_recommendation (google.ads.googleads.v23.resources.types.Recommendation.CustomAudienceOptInRecommendation): Output only. The custom audience opt in recommendation. This field is a member of `oneof`_ ``recommendation``. - lead_form_asset_recommendation (google.ads.googleads.v19.resources.types.Recommendation.LeadFormAssetRecommendation): + lead_form_asset_recommendation (google.ads.googleads.v23.resources.types.Recommendation.LeadFormAssetRecommendation): Output only. The lead form asset recommendation. This field is a member of `oneof`_ ``recommendation``. - improve_demand_gen_ad_strength_recommendation (google.ads.googleads.v19.resources.types.Recommendation.ImproveDemandGenAdStrengthRecommendation): + improve_demand_gen_ad_strength_recommendation (google.ads.googleads.v23.resources.types.Recommendation.ImproveDemandGenAdStrengthRecommendation): Output only. The improve Demand Gen ad strength recommendation. @@ -434,10 +434,10 @@ class RecommendationImpact(proto.Message): impact information. Attributes: - base_metrics (google.ads.googleads.v19.resources.types.Recommendation.RecommendationMetrics): + base_metrics (google.ads.googleads.v23.resources.types.Recommendation.RecommendationMetrics): Output only. Base metrics at the time the recommendation was generated. - potential_metrics (google.ads.googleads.v19.resources.types.Recommendation.RecommendationMetrics): + potential_metrics (google.ads.googleads.v23.resources.types.Recommendation.RecommendationMetrics): Output only. Estimated metrics if the recommendation is applied. """ @@ -539,7 +539,7 @@ class CampaignBudgetRecommendation(proto.Message): micros. This field is a member of `oneof`_ ``_recommended_budget_amount_micros``. - budget_options (MutableSequence[google.ads.googleads.v19.resources.types.Recommendation.CampaignBudgetRecommendation.CampaignBudgetRecommendationOption]): + budget_options (MutableSequence[google.ads.googleads.v23.resources.types.Recommendation.CampaignBudgetRecommendation.CampaignBudgetRecommendationOption]): Output only. The budget amounts and associated impact estimates for some values of possible budget amounts. @@ -556,7 +556,7 @@ class CampaignBudgetRecommendationOption(proto.Message): option. This field is a member of `oneof`_ ``_budget_amount_micros``. - impact (google.ads.googleads.v19.resources.types.Recommendation.RecommendationImpact): + impact (google.ads.googleads.v23.resources.types.Recommendation.RecommendationImpact): Output only. The impact estimate if budget is changed to amount specified in this option. """ @@ -596,9 +596,9 @@ class KeywordRecommendation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - keyword (google.ads.googleads.v19.common.types.KeywordInfo): + keyword (google.ads.googleads.v23.common.types.KeywordInfo): Output only. The recommended keyword. - search_terms (MutableSequence[google.ads.googleads.v19.resources.types.Recommendation.KeywordRecommendation.SearchTerm]): + search_terms (MutableSequence[google.ads.googleads.v23.resources.types.Recommendation.KeywordRecommendation.SearchTerm]): Output only. A list of search terms this keyword matches. The same search term may be repeated for multiple keywords. @@ -654,7 +654,7 @@ class TextAdRecommendation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - ad (google.ads.googleads.v19.resources.types.Ad): + ad (google.ads.googleads.v23.resources.types.Ad): Output only. Recommended ad. creation_date (str): Output only. Creation date of the recommended @@ -692,7 +692,7 @@ class TargetCpaOptInRecommendation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - options (MutableSequence[google.ads.googleads.v19.resources.types.Recommendation.TargetCpaOptInRecommendation.TargetCpaOptInRecommendationOption]): + options (MutableSequence[google.ads.googleads.v23.resources.types.Recommendation.TargetCpaOptInRecommendation.TargetCpaOptInRecommendationOption]): Output only. The available goals and corresponding options for Target CPA strategy. recommended_target_cpa_micros (int): @@ -709,7 +709,7 @@ class TargetCpaOptInRecommendationOption(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - goal (google.ads.googleads.v19.enums.types.TargetCpaOptInRecommendationGoalEnum.TargetCpaOptInRecommendationGoal): + goal (google.ads.googleads.v23.enums.types.TargetCpaOptInRecommendationGoalEnum.TargetCpaOptInRecommendationGoal): Output only. The goal achieved by this option. target_cpa_micros (int): @@ -724,7 +724,7 @@ class TargetCpaOptInRecommendationOption(proto.Message): currency unit. This field is a member of `oneof`_ ``_required_campaign_budget_amount_micros``. - impact (google.ads.googleads.v19.resources.types.Recommendation.RecommendationImpact): + impact (google.ads.googleads.v23.resources.types.Recommendation.RecommendationImpact): Output only. The impact estimate if this option is selected. """ @@ -817,10 +817,10 @@ class CalloutAssetRecommendation(proto.Message): r"""The callout asset recommendation. Attributes: - recommended_campaign_callout_assets (MutableSequence[google.ads.googleads.v19.resources.types.Asset]): + recommended_campaign_callout_assets (MutableSequence[google.ads.googleads.v23.resources.types.Asset]): Output only. New callout extension assets recommended at the campaign level. - recommended_customer_callout_assets (MutableSequence[google.ads.googleads.v19.resources.types.Asset]): + recommended_customer_callout_assets (MutableSequence[google.ads.googleads.v23.resources.types.Asset]): Output only. New callout extension assets recommended at the customer level. """ @@ -844,10 +844,10 @@ class SitelinkAssetRecommendation(proto.Message): r"""The sitelink asset recommendation. Attributes: - recommended_campaign_sitelink_assets (MutableSequence[google.ads.googleads.v19.resources.types.Asset]): + recommended_campaign_sitelink_assets (MutableSequence[google.ads.googleads.v23.resources.types.Asset]): Output only. New sitelink assets recommended at the campaign level. - recommended_customer_sitelink_assets (MutableSequence[google.ads.googleads.v19.resources.types.Asset]): + recommended_customer_sitelink_assets (MutableSequence[google.ads.googleads.v23.resources.types.Asset]): Output only. New sitelink assets recommended at the customer level. """ @@ -874,10 +874,10 @@ class KeywordMatchTypeRecommendation(proto.Message): r"""The keyword match type recommendation. Attributes: - keyword (google.ads.googleads.v19.common.types.KeywordInfo): + keyword (google.ads.googleads.v23.common.types.KeywordInfo): Output only. The existing keyword where the match type should be more broad. - recommended_match_type (google.ads.googleads.v19.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + recommended_match_type (google.ads.googleads.v23.enums.types.KeywordMatchTypeEnum.KeywordMatchType): Output only. The recommended new match type. """ @@ -904,7 +904,7 @@ class MoveUnusedBudgetRecommendation(proto.Message): Output only. The excess budget's resource_name. This field is a member of `oneof`_ ``_excess_campaign_budget``. - budget_recommendation (google.ads.googleads.v19.resources.types.Recommendation.CampaignBudgetRecommendation): + budget_recommendation (google.ads.googleads.v23.resources.types.Recommendation.CampaignBudgetRecommendation): Output only. The recommendation for the constrained budget to increase. """ @@ -959,9 +959,9 @@ class ResponsiveSearchAdAssetRecommendation(proto.Message): r"""The add responsive search ad asset recommendation. Attributes: - current_ad (google.ads.googleads.v19.resources.types.Ad): + current_ad (google.ads.googleads.v23.resources.types.Ad): Output only. The current ad to be updated. - recommended_assets (google.ads.googleads.v19.resources.types.Ad): + recommended_assets (google.ads.googleads.v23.resources.types.Ad): Output only. The recommended assets. This is populated only with the new headlines and/or descriptions, and is otherwise empty. @@ -982,9 +982,9 @@ class ResponsiveSearchAdImproveAdStrengthRecommendation(proto.Message): r"""The responsive search ad improve ad strength recommendation. Attributes: - current_ad (google.ads.googleads.v19.resources.types.Ad): + current_ad (google.ads.googleads.v23.resources.types.Ad): Output only. The current ad to be updated. - recommended_ad (google.ads.googleads.v19.resources.types.Ad): + recommended_ad (google.ads.googleads.v23.resources.types.Ad): Output only. The updated ad. """ @@ -1003,7 +1003,7 @@ class ResponsiveSearchAdRecommendation(proto.Message): r"""The add responsive search ad recommendation. Attributes: - ad (google.ads.googleads.v19.resources.types.Ad): + ad (google.ads.googleads.v23.resources.types.Ad): Output only. Recommended ad. """ @@ -1017,7 +1017,7 @@ class UseBroadMatchKeywordRecommendation(proto.Message): r"""The use broad match keyword recommendation. Attributes: - keyword (MutableSequence[google.ads.googleads.v19.common.types.KeywordInfo]): + keyword (MutableSequence[google.ads.googleads.v23.common.types.KeywordInfo]): Output only. Sample of keywords to be expanded to Broad Match. suggested_keywords_count (int): @@ -1128,7 +1128,7 @@ class ForecastingSetTargetRoasRecommendation(proto.Message): Output only. The recommended target ROAS (revenue per unit of spend). The value is between 0.01 and 1000.0, inclusive. - campaign_budget (google.ads.googleads.v19.resources.types.Recommendation.CampaignBudget): + campaign_budget (google.ads.googleads.v23.resources.types.Recommendation.CampaignBudget): Output only. The campaign budget. """ @@ -1147,7 +1147,7 @@ class ShoppingOfferAttributeRecommendation(proto.Message): that are demoted because it is missing. Attributes: - merchant (google.ads.googleads.v19.resources.types.Recommendation.MerchantInfo): + merchant (google.ads.googleads.v23.resources.types.Recommendation.MerchantInfo): Output only. The details of the Merchant Center account. feed_label (str): @@ -1184,7 +1184,7 @@ class ShoppingFixDisapprovedProductsRecommendation(proto.Message): Shopping Campaign Inventory. Attributes: - merchant (google.ads.googleads.v19.resources.types.Recommendation.MerchantInfo): + merchant (google.ads.googleads.v23.resources.types.Recommendation.MerchantInfo): Output only. The details of the Merchant Center account. feed_label (str): @@ -1220,7 +1220,7 @@ class ShoppingTargetAllOffersRecommendation(proto.Message): that targets all offers. Attributes: - merchant (google.ads.googleads.v19.resources.types.Recommendation.MerchantInfo): + merchant (google.ads.googleads.v23.resources.types.Recommendation.MerchantInfo): Output only. The details of the Merchant Center account. untargeted_offers_count (int): @@ -1248,12 +1248,12 @@ class ShoppingAddProductsToCampaignRecommendation(proto.Message): Campaign Inventory. Attributes: - merchant (google.ads.googleads.v19.resources.types.Recommendation.MerchantInfo): + merchant (google.ads.googleads.v23.resources.types.Recommendation.MerchantInfo): Output only. The details of the Merchant Center account. feed_label (str): Output only. The feed label for the campaign. - reason (google.ads.googleads.v19.enums.types.ShoppingAddProductsToCampaignRecommendationEnum.Reason): + reason (google.ads.googleads.v23.enums.types.ShoppingAddProductsToCampaignRecommendationEnum.Reason): Output only. The reason why no products are attached to the campaign. """ @@ -1280,7 +1280,7 @@ class ShoppingMerchantCenterAccountSuspensionRecommendation(proto.Message): suspension issues. Attributes: - merchant (google.ads.googleads.v19.resources.types.Recommendation.MerchantInfo): + merchant (google.ads.googleads.v23.resources.types.Recommendation.MerchantInfo): Output only. The details of the Merchant Center account. feed_label (str): @@ -1305,7 +1305,7 @@ class ShoppingMigrateRegularShoppingCampaignOffersToPerformanceMaxRecommendation Campaign targeted offers to Performance Max campaigns. Attributes: - merchant (google.ads.googleads.v19.resources.types.Recommendation.MerchantInfo): + merchant (google.ads.googleads.v23.resources.types.Recommendation.MerchantInfo): Output only. The details of the Merchant Center account. feed_label (str): @@ -1366,10 +1366,10 @@ class RaiseTargetCpaRecommendation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - target_adjustment (google.ads.googleads.v19.resources.types.Recommendation.TargetAdjustmentInfo): + target_adjustment (google.ads.googleads.v23.resources.types.Recommendation.TargetAdjustmentInfo): Output only. The relevant information describing the recommended target adjustment. - app_bidding_goal (google.ads.googleads.v19.enums.types.AppBiddingGoalEnum.AppBiddingGoal): + app_bidding_goal (google.ads.googleads.v23.enums.types.AppBiddingGoalEnum.AppBiddingGoal): Output only. Represents the goal towards which the bidding strategy should optimize. Only populated for App Campaigns. @@ -1395,7 +1395,7 @@ class LowerTargetRoasRecommendation(proto.Message): r"""Recommendation to lower Target ROAS. Attributes: - target_adjustment (google.ads.googleads.v19.resources.types.Recommendation.TargetAdjustmentInfo): + target_adjustment (google.ads.googleads.v23.resources.types.Recommendation.TargetAdjustmentInfo): Output only. The relevant information describing the recommended target adjustment. """ @@ -1453,7 +1453,7 @@ class ImprovePerformanceMaxAdStrengthRecommendation(proto.Message): Attributes: asset_group (str): Output only. The asset group resource name. - ad_strength (google.ads.googleads.v19.enums.types.AdStrengthEnum.AdStrength): + ad_strength (google.ads.googleads.v23.enums.types.AdStrengthEnum.AdStrength): Output only. The current ad strength score of the asset group. """ @@ -1492,7 +1492,7 @@ class ForecastingSetTargetCpaRecommendation(proto.Message): Attributes: recommended_target_cpa_micros (int): Output only. The recommended target CPA. - campaign_budget (google.ads.googleads.v19.resources.types.Recommendation.CampaignBudget): + campaign_budget (google.ads.googleads.v23.resources.types.Recommendation.CampaignBudget): Output only. The campaign budget. """ @@ -1534,13 +1534,13 @@ class RefreshCustomerMatchListRecommendation(proto.Message): Output only. The name of the list. days_since_last_refresh (int): Output only. Days since last refresh. - top_spending_account (MutableSequence[google.ads.googleads.v19.resources.types.Recommendation.AccountInfo]): + top_spending_account (MutableSequence[google.ads.googleads.v23.resources.types.Recommendation.AccountInfo]): Output only. The top spending account. targeting_accounts_count (int): Output only. User lists can be shared with other accounts by the owner. targeting_accounts_count is the number of those accounts that can use it for targeting. - owner_account (google.ads.googleads.v19.resources.types.Recommendation.AccountInfo): + owner_account (google.ads.googleads.v23.resources.types.Recommendation.AccountInfo): Output only. The owner account. This is the account that should update the customer list. """ @@ -1598,7 +1598,7 @@ class CustomAudienceOptInRecommendation(proto.Message): r"""The Custom Audience Opt In recommendation. Attributes: - keywords (MutableSequence[google.ads.googleads.v19.common.types.KeywordInfo]): + keywords (MutableSequence[google.ads.googleads.v23.common.types.KeywordInfo]): Output only. The list of keywords to use for custom audience creation. """ @@ -1619,7 +1619,7 @@ class ImproveDemandGenAdStrengthRecommendation(proto.Message): ad (str): Output only. The resource name of the ad that can be improved. - ad_strength (google.ads.googleads.v19.enums.types.AdStrengthEnum.AdStrength): + ad_strength (google.ads.googleads.v23.enums.types.AdStrengthEnum.AdStrength): Output only. The current ad strength. demand_gen_asset_action_items (MutableSequence[str]): Output only. A list of recommendations to diff --git a/google/ads/googleads/v19/resources/types/recommendation_subscription.py b/google/ads/googleads/v23/resources/types/recommendation_subscription.py similarity index 90% rename from google/ads/googleads/v19/resources/types/recommendation_subscription.py rename to google/ads/googleads/v23/resources/types/recommendation_subscription.py index 0e62d3373..068fd74bf 100644 --- a/google/ads/googleads/v19/resources/types/recommendation_subscription.py +++ b/google/ads/googleads/v23/resources/types/recommendation_subscription.py @@ -18,15 +18,15 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( recommendation_subscription_status, ) -from google.ads.googleads.v19.enums.types import recommendation_type +from google.ads.googleads.v23.enums.types import recommendation_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "RecommendationSubscription", }, @@ -44,7 +44,7 @@ class RecommendationSubscription(proto.Message): subscription. ``customers/{customer_id}/recommendationSubscriptions/{recommendation_type}`` - type_ (google.ads.googleads.v19.enums.types.RecommendationTypeEnum.RecommendationType): + type_ (google.ads.googleads.v23.enums.types.RecommendationTypeEnum.RecommendationType): Required. Immutable. The type of recommendation subscribed to. create_date_time (str): @@ -62,7 +62,7 @@ class RecommendationSubscription(proto.Message): HH:mm:ss.ssssss" format. This field is a member of `oneof`_ ``_modify_date_time``. - status (google.ads.googleads.v19.enums.types.RecommendationSubscriptionStatusEnum.RecommendationSubscriptionStatus): + status (google.ads.googleads.v23.enums.types.RecommendationSubscriptionStatusEnum.RecommendationSubscriptionStatus): Required. Status of the subscription, either enabled or paused. diff --git a/google/ads/googleads/v19/resources/types/remarketing_action.py b/google/ads/googleads/v23/resources/types/remarketing_action.py similarity index 91% rename from google/ads/googleads/v19/resources/types/remarketing_action.py rename to google/ads/googleads/v23/resources/types/remarketing_action.py index 4e09ab91c..c847e27c7 100644 --- a/google/ads/googleads/v19/resources/types/remarketing_action.py +++ b/google/ads/googleads/v23/resources/types/remarketing_action.py @@ -19,12 +19,12 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import tag_snippet +from google.ads.googleads.v23.common.types import tag_snippet __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "RemarketingAction", }, @@ -57,7 +57,7 @@ class RemarketingAction(proto.Message): when creating new remarketing actions. This field is a member of `oneof`_ ``_name``. - tag_snippets (MutableSequence[google.ads.googleads.v19.common.types.TagSnippet]): + tag_snippets (MutableSequence[google.ads.googleads.v23.common.types.TagSnippet]): Output only. The snippets used for tracking remarketing actions. """ diff --git a/google/ads/googleads/v19/resources/types/search_term_view.py b/google/ads/googleads/v23/resources/types/search_term_view.py similarity index 92% rename from google/ads/googleads/v19/resources/types/search_term_view.py rename to google/ads/googleads/v23/resources/types/search_term_view.py index 4df85b94e..8021c8926 100644 --- a/google/ads/googleads/v19/resources/types/search_term_view.py +++ b/google/ads/googleads/v23/resources/types/search_term_view.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import search_term_targeting_status +from google.ads.googleads.v23.enums.types import search_term_targeting_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "SearchTermView", }, @@ -54,7 +54,7 @@ class SearchTermView(proto.Message): served in. This field is a member of `oneof`_ ``_ad_group``. - status (google.ads.googleads.v19.enums.types.SearchTermTargetingStatusEnum.SearchTermTargetingStatus): + status (google.ads.googleads.v23.enums.types.SearchTermTargetingStatusEnum.SearchTermTargetingStatus): Output only. Indicates whether the search term is currently one of your targeted or excluded keywords. diff --git a/google/ads/googleads/v23/resources/types/shared_criterion.py b/google/ads/googleads/v23/resources/types/shared_criterion.py new file mode 100644 index 000000000..2e6be5571 --- /dev/null +++ b/google/ads/googleads/v23/resources/types/shared_criterion.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import criterion_type + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "SharedCriterion", + }, +) + + +class SharedCriterion(proto.Message): + r"""A criterion belonging to a shared set. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the shared criterion. Shared + set resource names have the form: + + ``customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}`` + shared_set (str): + Immutable. The shared set to which the shared + criterion belongs. + + This field is a member of `oneof`_ ``_shared_set``. + criterion_id (int): + Output only. The ID of the criterion. + + This field is ignored for mutates. + + This field is a member of `oneof`_ ``_criterion_id``. + type_ (google.ads.googleads.v23.enums.types.CriterionTypeEnum.CriterionType): + Output only. The type of the criterion. + negative (bool): + Immutable. If true, the criterion is + excluded. If false, the criterion is targeted. + + This field is a member of `oneof`_ ``_negative``. + keyword (google.ads.googleads.v23.common.types.KeywordInfo): + Immutable. Keyword. + + This field is a member of `oneof`_ ``criterion``. + youtube_video (google.ads.googleads.v23.common.types.YouTubeVideoInfo): + Immutable. YouTube Video. + + This field is a member of `oneof`_ ``criterion``. + youtube_channel (google.ads.googleads.v23.common.types.YouTubeChannelInfo): + Immutable. YouTube Channel. + + This field is a member of `oneof`_ ``criterion``. + placement (google.ads.googleads.v23.common.types.PlacementInfo): + Immutable. Placement. + + This field is a member of `oneof`_ ``criterion``. + mobile_app_category (google.ads.googleads.v23.common.types.MobileAppCategoryInfo): + Immutable. Mobile App Category. + + This field is a member of `oneof`_ ``criterion``. + mobile_application (google.ads.googleads.v23.common.types.MobileApplicationInfo): + Immutable. Mobile application. + + This field is a member of `oneof`_ ``criterion``. + brand (google.ads.googleads.v23.common.types.BrandInfo): + Immutable. Brand. + + This field is a member of `oneof`_ ``criterion``. + webpage (google.ads.googleads.v23.common.types.WebpageInfo): + Immutable. Webpage. + + This field is a member of `oneof`_ ``criterion``. + vertical_ads_item_group_rule (google.ads.googleads.v23.common.types.VerticalAdsItemGroupRuleInfo): + Immutable. Vertical ads item group rule. + + This field is a member of `oneof`_ ``criterion``. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + shared_set: str = proto.Field( + proto.STRING, + number=10, + optional=True, + ) + criterion_id: int = proto.Field( + proto.INT64, + number=11, + optional=True, + ) + type_: criterion_type.CriterionTypeEnum.CriterionType = proto.Field( + proto.ENUM, + number=4, + enum=criterion_type.CriterionTypeEnum.CriterionType, + ) + negative: bool = proto.Field( + proto.BOOL, + number=15, + optional=True, + ) + keyword: criteria.KeywordInfo = proto.Field( + proto.MESSAGE, + number=3, + oneof="criterion", + message=criteria.KeywordInfo, + ) + youtube_video: criteria.YouTubeVideoInfo = proto.Field( + proto.MESSAGE, + number=5, + oneof="criterion", + message=criteria.YouTubeVideoInfo, + ) + youtube_channel: criteria.YouTubeChannelInfo = proto.Field( + proto.MESSAGE, + number=6, + oneof="criterion", + message=criteria.YouTubeChannelInfo, + ) + placement: criteria.PlacementInfo = proto.Field( + proto.MESSAGE, + number=7, + oneof="criterion", + message=criteria.PlacementInfo, + ) + mobile_app_category: criteria.MobileAppCategoryInfo = proto.Field( + proto.MESSAGE, + number=8, + oneof="criterion", + message=criteria.MobileAppCategoryInfo, + ) + mobile_application: criteria.MobileApplicationInfo = proto.Field( + proto.MESSAGE, + number=9, + oneof="criterion", + message=criteria.MobileApplicationInfo, + ) + brand: criteria.BrandInfo = proto.Field( + proto.MESSAGE, + number=12, + oneof="criterion", + message=criteria.BrandInfo, + ) + webpage: criteria.WebpageInfo = proto.Field( + proto.MESSAGE, + number=13, + oneof="criterion", + message=criteria.WebpageInfo, + ) + vertical_ads_item_group_rule: criteria.VerticalAdsItemGroupRuleInfo = ( + proto.Field( + proto.MESSAGE, + number=14, + oneof="criterion", + message=criteria.VerticalAdsItemGroupRuleInfo, + ) + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/resources/types/shared_set.py b/google/ads/googleads/v23/resources/types/shared_set.py new file mode 100644 index 000000000..2cfef16cf --- /dev/null +++ b/google/ads/googleads/v23/resources/types/shared_set.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.ads.googleads.v23.enums.types import shared_set_status +from google.ads.googleads.v23.enums.types import shared_set_type +from google.ads.googleads.v23.enums.types import ( + vertical_ads_item_vertical_type as gage_vertical_ads_item_vertical_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "SharedSet", + }, +) + + +class SharedSet(proto.Message): + r"""SharedSets are used for sharing criterion exclusions across + multiple campaigns. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + resource_name (str): + Immutable. The resource name of the shared set. Shared set + resource names have the form: + + ``customers/{customer_id}/sharedSets/{shared_set_id}`` + id (int): + Output only. The ID of this shared set. Read + only. + + This field is a member of `oneof`_ ``_id``. + type_ (google.ads.googleads.v23.enums.types.SharedSetTypeEnum.SharedSetType): + Immutable. The type of this shared set: each + shared set holds only a single kind of resource. + Required. Immutable. + name (str): + The name of this shared set. Required. + Shared Sets must have names that are unique + among active shared sets of the same type. + The length of this string should be between 1 + and 255 UTF-8 bytes, inclusive. + + This field is a member of `oneof`_ ``_name``. + status (google.ads.googleads.v23.enums.types.SharedSetStatusEnum.SharedSetStatus): + Output only. The status of this shared set. + Read only. + member_count (int): + Output only. The number of shared criteria + within this shared set. Read only. + + This field is a member of `oneof`_ ``_member_count``. + reference_count (int): + Output only. The number of campaigns + associated with this shared set. Read only. + + This field is a member of `oneof`_ ``_reference_count``. + vertical_ads_item_vertical_type (google.ads.googleads.v23.enums.types.VerticalAdsItemVerticalTypeEnum.VerticalAdsItemVerticalType): + Immutable. Shared sets of type + VERTICAL_ADS_ITEM_GROUP_RULE_LIST are associated with a + particular vertical (e.g. hotels, things to do, flights, + etc.). This field is required for shared sets of type + VERTICAL_ADS_ITEM_GROUP_RULE_LIST. + + This field is a member of `oneof`_ ``_vertical_ads_item_vertical_type``. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + id: int = proto.Field( + proto.INT64, + number=8, + optional=True, + ) + type_: shared_set_type.SharedSetTypeEnum.SharedSetType = proto.Field( + proto.ENUM, + number=3, + enum=shared_set_type.SharedSetTypeEnum.SharedSetType, + ) + name: str = proto.Field( + proto.STRING, + number=9, + optional=True, + ) + status: shared_set_status.SharedSetStatusEnum.SharedSetStatus = proto.Field( + proto.ENUM, + number=5, + enum=shared_set_status.SharedSetStatusEnum.SharedSetStatus, + ) + member_count: int = proto.Field( + proto.INT64, + number=10, + optional=True, + ) + reference_count: int = proto.Field( + proto.INT64, + number=11, + optional=True, + ) + vertical_ads_item_vertical_type: ( + gage_vertical_ads_item_vertical_type.VerticalAdsItemVerticalTypeEnum.VerticalAdsItemVerticalType + ) = proto.Field( + proto.ENUM, + number=12, + optional=True, + enum=gage_vertical_ads_item_vertical_type.VerticalAdsItemVerticalTypeEnum.VerticalAdsItemVerticalType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/resources/types/shopping_performance_view.py b/google/ads/googleads/v23/resources/types/shopping_performance_view.py new file mode 100644 index 000000000..90bc9eae6 --- /dev/null +++ b/google/ads/googleads/v23/resources/types/shopping_performance_view.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "ShoppingPerformanceView", + }, +) + + +class ShoppingPerformanceView(proto.Message): + r"""Shopping performance view. + + Provides Shopping campaign and Performance Max campaign statistics + aggregated at several product dimension levels. Product dimension + values from Merchant Center such as brand, category, custom + attributes, product condition, and product type will reflect the + state of each dimension as of the date and time when the + corresponding event was recorded. + + The number of impressions and clicks that + ``shopping_performance_view`` returns stats for may be different + from campaign reports. ``shopping_performance_view`` shows + impressions and clicks on products appearing in ads, while campaign + reports show impressions and clicks on the ads themselves. Depending + on the format, an ad can show from zero to several products, so the + numbers may not match. + + In Google Ads UI, you can query impressions and clicks of products + appearing in ads by selecting a column from "Product attributes" in + the report editor. For example, selecting the "Brand" column is + equivalent to selecting ``segments.product_brand``. + + Attributes: + resource_name (str): + Output only. The resource name of the Shopping performance + view. Shopping performance view resource names have the + form: ``customers/{customer_id}/shoppingPerformanceView`` + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/shopping_product.py b/google/ads/googleads/v23/resources/types/shopping_product.py similarity index 85% rename from google/ads/googleads/v19/resources/types/shopping_product.py rename to google/ads/googleads/v23/resources/types/shopping_product.py index aacbd44e0..13c3ebb89 100644 --- a/google/ads/googleads/v19/resources/types/shopping_product.py +++ b/google/ads/googleads/v23/resources/types/shopping_product.py @@ -19,17 +19,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import product_availability -from google.ads.googleads.v19.enums.types import product_channel -from google.ads.googleads.v19.enums.types import product_channel_exclusivity -from google.ads.googleads.v19.enums.types import product_condition -from google.ads.googleads.v19.enums.types import product_issue_severity -from google.ads.googleads.v19.enums.types import product_status +from google.ads.googleads.v23.enums.types import product_availability +from google.ads.googleads.v23.enums.types import product_channel +from google.ads.googleads.v23.enums.types import product_channel_exclusivity +from google.ads.googleads.v23.enums.types import product_condition +from google.ads.googleads.v23.enums.types import product_issue_severity +from google.ads.googleads.v23.enums.types import product_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ShoppingProduct", }, @@ -50,27 +50,31 @@ class ShoppingProduct(proto.Message): Queries to this resource specify a scope: Account: - - Filters on campaigns or ad groups are not specified. - - All products from the linked Google Merchant Center accounts are - returned. - - Metrics and some fields (see the per-field documentation) are - aggregated across all Shopping and Performance Max campaigns that - include a product. Campaign: - - An equality filter on ``campaign`` is specified. Supported - campaign types are Shopping, Performance Max, Demand Gen, Video. - - Only products that are included by the specified campaign are - returned. - - Metrics and some fields (see the per-field documentation) are - restricted to the specified campaign. Ad group: - - An equality filter on ``ad group`` and ``campaign`` is specified. - Supported campaign types are Shopping, Demand Gen, Video. - - Only products that are included by the specified campaign are - returned. - - Metrics and some fields (see the per-field documentation) are - restricted to the specified ad group. Note that segmentation by - date segments is not permitted and will return - UNSUPPORTED_DATE_SEGMENTATION error. On the other hand, filtering - on date segments is allowed. + - Filters on campaigns or ad groups are not specified. + - All products from the linked Google Merchant Center accounts are + returned. + - Metrics and some fields (see the per-field documentation) are + aggregated across all Shopping and Performance Max campaigns that + include a product. Campaign: + - An equality filter on ``campaign`` is specified. Supported + campaign types are Shopping, Performance Max, Demand Gen, Video. + - Only products that are included by the specified campaign are + returned. + - Metrics and some fields (see the per-field documentation) are + restricted to the specified campaign. + - Only the following metrics are supported for Demand Gen and Video + campaigns: impressions, clicks, ctr. Ad group: + - An equality filter on ``ad group`` and ``campaign`` is specified. + Supported campaign types are Shopping, Demand Gen, Video. + - Only products that are included by the specified campaign are + returned. + - Metrics and some fields (see the per-field documentation) are + restricted to the specified ad group. + - Only the following metrics are supported for Demand Gen and Video + campaigns: impressions, clicks, ctr. Note that segmentation by + date segments is not permitted and will return + UNSUPPORTED_DATE_SEGMENTATION error. On the other hand, filtering + on date segments is allowed. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -84,7 +88,7 @@ class ShoppingProduct(proto.Message): merchant_center_id (int): Output only. The id of the merchant that owns the product. - channel (google.ads.googleads.v19.enums.types.ProductChannelEnum.ProductChannel): + channel (google.ads.googleads.v23.enums.types.ProductChannelEnum.ProductChannel): Output only. The product channel describing the locality of the product. language_code (str): @@ -111,6 +115,11 @@ class ShoppingProduct(proto.Message): provided by the merchant. This field is a member of `oneof`_ ``_brand``. + product_image_uri (str): + Output only. The URI of the product image as + provided by the merchant. + + This field is a member of `oneof`_ ``_product_image_uri``. price_micros (int): Output only. The price of the product in micros as provided by the merchant, in the currency specified in @@ -122,17 +131,17 @@ class ShoppingProduct(proto.Message): the merchant, in ISO 4217 format. This field is a member of `oneof`_ ``_currency_code``. - channel_exclusivity (google.ads.googleads.v19.enums.types.ProductChannelExclusivityEnum.ProductChannelExclusivity): + channel_exclusivity (google.ads.googleads.v23.enums.types.ProductChannelExclusivityEnum.ProductChannelExclusivity): Output only. The channel exclusivity of the product as provided by the merchant. This field is a member of `oneof`_ ``_channel_exclusivity``. - condition (google.ads.googleads.v19.enums.types.ProductConditionEnum.ProductCondition): + condition (google.ads.googleads.v23.enums.types.ProductConditionEnum.ProductCondition): Output only. The condition of the product as provided by the merchant. This field is a member of `oneof`_ ``_condition``. - availability (google.ads.googleads.v19.enums.types.ProductAvailabilityEnum.ProductAvailability): + availability (google.ads.googleads.v23.enums.types.ProductAvailabilityEnum.ProductAvailability): Output only. The availability of the product as provided by the merchant. @@ -229,14 +238,14 @@ class ShoppingProduct(proto.Message): 24 hours to update. This field is a member of `oneof`_ ``_effective_max_cpc_micros``. - status (google.ads.googleads.v19.enums.types.ProductStatusEnum.ProductStatus): + status (google.ads.googleads.v23.enums.types.ProductStatusEnum.ProductStatus): Output only. The status that indicates whether the product can show in ads. The value of this field is restricted to the scope specified in the query, see the documentation of the resource. This field can take up to 24 hours to update. - issues (MutableSequence[google.ads.googleads.v19.resources.types.ShoppingProduct.ProductIssue]): + issues (MutableSequence[google.ads.googleads.v23.resources.types.ShoppingProduct.ProductIssue]): Output only. The list of issues affecting whether the product can show in ads. The value of this field is restricted to the scope @@ -267,7 +276,7 @@ class ProductIssue(proto.Message): error_code (str): Output only. The error code that identifies the issue. - ads_severity (google.ads.googleads.v19.enums.types.ProductIssueSeverityEnum.ProductIssueSeverity): + ads_severity (google.ads.googleads.v23.enums.types.ProductIssueSeverityEnum.ProductIssueSeverity): Output only. The severity of the issue in Google Ads. attribute_name (str): @@ -363,6 +372,11 @@ class ProductIssue(proto.Message): number=9, optional=True, ) + product_image_uri: str = proto.Field( + proto.STRING, + number=36, + optional=True, + ) price_micros: int = proto.Field( proto.INT64, number=10, diff --git a/google/ads/googleads/v19/resources/types/smart_campaign_search_term_view.py b/google/ads/googleads/v23/resources/types/smart_campaign_search_term_view.py similarity index 94% rename from google/ads/googleads/v19/resources/types/smart_campaign_search_term_view.py rename to google/ads/googleads/v23/resources/types/smart_campaign_search_term_view.py index 662cc2e9b..7b6b20c13 100644 --- a/google/ads/googleads/v19/resources/types/smart_campaign_search_term_view.py +++ b/google/ads/googleads/v23/resources/types/smart_campaign_search_term_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "SmartCampaignSearchTermView", }, diff --git a/google/ads/googleads/v19/resources/types/smart_campaign_setting.py b/google/ads/googleads/v23/resources/types/smart_campaign_setting.py similarity index 96% rename from google/ads/googleads/v19/resources/types/smart_campaign_setting.py rename to google/ads/googleads/v23/resources/types/smart_campaign_setting.py index bc2c6e28d..cf58704db 100644 --- a/google/ads/googleads/v19/resources/types/smart_campaign_setting.py +++ b/google/ads/googleads/v23/resources/types/smart_campaign_setting.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "SmartCampaignSetting", }, @@ -47,7 +47,7 @@ class SmartCampaignSetting(proto.Message): campaign (str): Output only. The campaign to which these settings apply. - phone_number (google.ads.googleads.v19.resources.types.SmartCampaignSetting.PhoneNumber): + phone_number (google.ads.googleads.v23.resources.types.SmartCampaignSetting.PhoneNumber): Phone number and country code. advertising_language_code (str): The language code to advertise in from the set of [supported @@ -58,7 +58,7 @@ class SmartCampaignSetting(proto.Message): Campaign. This field is a member of `oneof`_ ``landing_page``. - ad_optimized_business_profile_setting (google.ads.googleads.v19.resources.types.SmartCampaignSetting.AdOptimizedBusinessProfileSetting): + ad_optimized_business_profile_setting (google.ads.googleads.v23.resources.types.SmartCampaignSetting.AdOptimizedBusinessProfileSetting): Settings for configuring a business profile optimized for ads as this campaign's landing page. This campaign must be linked to a diff --git a/google/ads/googleads/v23/resources/types/targeting_expansion_view.py b/google/ads/googleads/v23/resources/types/targeting_expansion_view.py new file mode 100644 index 000000000..a7c28afbe --- /dev/null +++ b/google/ads/googleads/v23/resources/types/targeting_expansion_view.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", + manifest={ + "TargetingExpansionView", + }, +) + + +class TargetingExpansionView(proto.Message): + r"""A targeting expansion view with metrics. + Returns metrics for automated expansion over manual targeting. + + Attributes: + resource_name (str): + Output only. The resource name of the targeting expansion + view. Targeting expansion view resource names have the form: + + ``customers/{customer_id}/targetingExpansionViews/{campaign_id}~{targeting_expansion_type}`` + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/resources/types/third_party_app_analytics_link.py b/google/ads/googleads/v23/resources/types/third_party_app_analytics_link.py similarity index 95% rename from google/ads/googleads/v19/resources/types/third_party_app_analytics_link.py rename to google/ads/googleads/v23/resources/types/third_party_app_analytics_link.py index 42ab6293b..e316a9339 100644 --- a/google/ads/googleads/v19/resources/types/third_party_app_analytics_link.py +++ b/google/ads/googleads/v23/resources/types/third_party_app_analytics_link.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "ThirdPartyAppAnalyticsLink", }, diff --git a/google/ads/googleads/v19/resources/types/topic_constant.py b/google/ads/googleads/v23/resources/types/topic_constant.py similarity index 96% rename from google/ads/googleads/v19/resources/types/topic_constant.py rename to google/ads/googleads/v23/resources/types/topic_constant.py index f3d1f7d2e..473d12a81 100644 --- a/google/ads/googleads/v19/resources/types/topic_constant.py +++ b/google/ads/googleads/v23/resources/types/topic_constant.py @@ -21,8 +21,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "TopicConstant", }, diff --git a/google/ads/googleads/v19/resources/types/topic_view.py b/google/ads/googleads/v23/resources/types/topic_view.py similarity index 92% rename from google/ads/googleads/v19/resources/types/topic_view.py rename to google/ads/googleads/v23/resources/types/topic_view.py index 3ed2c9d5e..5063405d3 100644 --- a/google/ads/googleads/v19/resources/types/topic_view.py +++ b/google/ads/googleads/v23/resources/types/topic_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "TopicView", }, diff --git a/google/ads/googleads/v19/resources/types/travel_activity_group_view.py b/google/ads/googleads/v23/resources/types/travel_activity_group_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/travel_activity_group_view.py rename to google/ads/googleads/v23/resources/types/travel_activity_group_view.py index 8cf966352..276f50beb 100644 --- a/google/ads/googleads/v19/resources/types/travel_activity_group_view.py +++ b/google/ads/googleads/v23/resources/types/travel_activity_group_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "TravelActivityGroupView", }, diff --git a/google/ads/googleads/v19/resources/types/travel_activity_performance_view.py b/google/ads/googleads/v23/resources/types/travel_activity_performance_view.py similarity index 93% rename from google/ads/googleads/v19/resources/types/travel_activity_performance_view.py rename to google/ads/googleads/v23/resources/types/travel_activity_performance_view.py index ec560b131..0cbe15bda 100644 --- a/google/ads/googleads/v19/resources/types/travel_activity_performance_view.py +++ b/google/ads/googleads/v23/resources/types/travel_activity_performance_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "TravelActivityPerformanceView", }, diff --git a/google/ads/googleads/v19/resources/types/user_interest.py b/google/ads/googleads/v23/resources/types/user_interest.py similarity index 90% rename from google/ads/googleads/v19/resources/types/user_interest.py rename to google/ads/googleads/v23/resources/types/user_interest.py index acd83c552..7aad514f6 100644 --- a/google/ads/googleads/v19/resources/types/user_interest.py +++ b/google/ads/googleads/v23/resources/types/user_interest.py @@ -19,15 +19,15 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import ( +from google.ads.googleads.v23.common.types import ( criterion_category_availability, ) -from google.ads.googleads.v19.enums.types import user_interest_taxonomy_type +from google.ads.googleads.v23.enums.types import user_interest_taxonomy_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "UserInterest", }, @@ -47,7 +47,7 @@ class UserInterest(proto.Message): interest resource names have the form: ``customers/{customer_id}/userInterests/{user_interest_id}`` - taxonomy_type (google.ads.googleads.v19.enums.types.UserInterestTaxonomyTypeEnum.UserInterestTaxonomyType): + taxonomy_type (google.ads.googleads.v23.enums.types.UserInterestTaxonomyTypeEnum.UserInterestTaxonomyType): Output only. Taxonomy type of the user interest. user_interest_id (int): @@ -67,7 +67,7 @@ class UserInterest(proto.Message): launched to all channels and locales. This field is a member of `oneof`_ ``_launched_to_all``. - availabilities (MutableSequence[google.ads.googleads.v19.common.types.CriterionCategoryAvailability]): + availabilities (MutableSequence[google.ads.googleads.v23.common.types.CriterionCategoryAvailability]): Output only. Availability information of the user interest. """ diff --git a/google/ads/googleads/v19/resources/types/user_list.py b/google/ads/googleads/v23/resources/types/user_list.py similarity index 89% rename from google/ads/googleads/v19/resources/types/user_list.py rename to google/ads/googleads/v23/resources/types/user_list.py index 6fc3895b0..e599dc0ce 100644 --- a/google/ads/googleads/v19/resources/types/user_list.py +++ b/google/ads/googleads/v23/resources/types/user_list.py @@ -18,20 +18,20 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import user_lists -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import user_lists +from google.ads.googleads.v23.enums.types import ( access_reason as gage_access_reason, ) -from google.ads.googleads.v19.enums.types import user_list_access_status -from google.ads.googleads.v19.enums.types import user_list_closing_reason -from google.ads.googleads.v19.enums.types import user_list_membership_status -from google.ads.googleads.v19.enums.types import user_list_size_range -from google.ads.googleads.v19.enums.types import user_list_type +from google.ads.googleads.v23.enums.types import user_list_access_status +from google.ads.googleads.v23.enums.types import user_list_closing_reason +from google.ads.googleads.v23.enums.types import user_list_membership_status +from google.ads.googleads.v23.enums.types import user_list_size_range +from google.ads.googleads.v23.enums.types import user_list_type __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "UserList", }, @@ -77,7 +77,7 @@ class UserList(proto.Message): Description of this user list. This field is a member of `oneof`_ ``_description``. - membership_status (google.ads.googleads.v19.enums.types.UserListMembershipStatusEnum.UserListMembershipStatus): + membership_status (google.ads.googleads.v23.enums.types.UserListMembershipStatusEnum.UserListMembershipStatus): Membership status of this user list. Indicates whether a user list is open or active. Only open user lists can accumulate more users @@ -110,7 +110,7 @@ class UserList(proto.Message): This field is read-only. This field is a member of `oneof`_ ``_size_for_display``. - size_range_for_display (google.ads.googleads.v19.enums.types.UserListSizeRangeEnum.UserListSizeRange): + size_range_for_display (google.ads.googleads.v23.enums.types.UserListSizeRangeEnum.UserListSizeRange): Output only. Size range in terms of number of users of the UserList, on the Google Display Network. @@ -126,29 +126,29 @@ class UserList(proto.Message): This field is read-only. This field is a member of `oneof`_ ``_size_for_search``. - size_range_for_search (google.ads.googleads.v19.enums.types.UserListSizeRangeEnum.UserListSizeRange): + size_range_for_search (google.ads.googleads.v23.enums.types.UserListSizeRangeEnum.UserListSizeRange): Output only. Size range in terms of number of users of the UserList, for Search ads. This field is read-only. - type_ (google.ads.googleads.v19.enums.types.UserListTypeEnum.UserListType): + type_ (google.ads.googleads.v23.enums.types.UserListTypeEnum.UserListType): Output only. Type of this list. This field is read-only. - closing_reason (google.ads.googleads.v19.enums.types.UserListClosingReasonEnum.UserListClosingReason): + closing_reason (google.ads.googleads.v23.enums.types.UserListClosingReasonEnum.UserListClosingReason): Indicating the reason why this user list membership status is closed. It is only populated on lists that were automatically closed due to inactivity, and will be cleared once the list membership status becomes open. - access_reason (google.ads.googleads.v19.enums.types.AccessReasonEnum.AccessReason): + access_reason (google.ads.googleads.v23.enums.types.AccessReasonEnum.AccessReason): Output only. Indicates the reason this account has been granted access to the list. The reason can be SHARED, OWNED, LICENSED or SUBSCRIBED. This field is read-only. - account_user_list_status (google.ads.googleads.v19.enums.types.UserListAccessStatusEnum.UserListAccessStatus): + account_user_list_status (google.ads.googleads.v23.enums.types.UserListAccessStatusEnum.UserListAccessStatus): Indicates if this share is still enabled. When a UserList is shared with the user this field is set to ENABLED. Later the userList @@ -177,32 +177,32 @@ class UserList(proto.Message): This field is read-only. This field is a member of `oneof`_ ``_match_rate_percentage``. - crm_based_user_list (google.ads.googleads.v19.common.types.CrmBasedUserListInfo): + crm_based_user_list (google.ads.googleads.v23.common.types.CrmBasedUserListInfo): User list of CRM users provided by the advertiser. This field is a member of `oneof`_ ``user_list``. - similar_user_list (google.ads.googleads.v19.common.types.SimilarUserListInfo): + similar_user_list (google.ads.googleads.v23.common.types.SimilarUserListInfo): Output only. User list which are similar to users from another UserList. These lists are readonly and automatically created by google. This field is a member of `oneof`_ ``user_list``. - rule_based_user_list (google.ads.googleads.v19.common.types.RuleBasedUserListInfo): + rule_based_user_list (google.ads.googleads.v23.common.types.RuleBasedUserListInfo): User list generated by a rule. This field is a member of `oneof`_ ``user_list``. - logical_user_list (google.ads.googleads.v19.common.types.LogicalUserListInfo): + logical_user_list (google.ads.googleads.v23.common.types.LogicalUserListInfo): User list that is a custom combination of user lists and user interests. This field is a member of `oneof`_ ``user_list``. - basic_user_list (google.ads.googleads.v19.common.types.BasicUserListInfo): + basic_user_list (google.ads.googleads.v23.common.types.BasicUserListInfo): User list targeting as a collection of conversion or remarketing actions. This field is a member of `oneof`_ ``user_list``. - lookalike_user_list (google.ads.googleads.v19.common.types.LookalikeUserListInfo): + lookalike_user_list (google.ads.googleads.v23.common.types.LookalikeUserListInfo): Immutable. Lookalike User List. This field is a member of `oneof`_ ``user_list``. diff --git a/google/ads/googleads/v19/resources/types/user_list_customer_type.py b/google/ads/googleads/v23/resources/types/user_list_customer_type.py similarity index 90% rename from google/ads/googleads/v19/resources/types/user_list_customer_type.py rename to google/ads/googleads/v23/resources/types/user_list_customer_type.py index 7f88fc1a2..ad0a8f124 100644 --- a/google/ads/googleads/v19/resources/types/user_list_customer_type.py +++ b/google/ads/googleads/v23/resources/types/user_list_customer_type.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( user_list_customer_type_category, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "UserListCustomerType", }, @@ -44,7 +44,7 @@ class UserListCustomerType(proto.Message): Immutable. The resource name for the user list this user list customer type is associated with - customer_type_category (google.ads.googleads.v19.enums.types.UserListCustomerTypeCategoryEnum.UserListCustomerTypeCategory): + customer_type_category (google.ads.googleads.v23.enums.types.UserListCustomerTypeCategoryEnum.UserListCustomerTypeCategory): Immutable. The user list customer type category """ diff --git a/google/ads/googleads/v19/resources/types/user_location_view.py b/google/ads/googleads/v23/resources/types/user_location_view.py similarity index 96% rename from google/ads/googleads/v19/resources/types/user_location_view.py rename to google/ads/googleads/v23/resources/types/user_location_view.py index 1397aa8df..52320386f 100644 --- a/google/ads/googleads/v19/resources/types/user_location_view.py +++ b/google/ads/googleads/v23/resources/types/user_location_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "UserLocationView", }, diff --git a/google/ads/googleads/v19/resources/types/video.py b/google/ads/googleads/v23/resources/types/video.py similarity index 96% rename from google/ads/googleads/v19/resources/types/video.py rename to google/ads/googleads/v23/resources/types/video.py index d8265136e..e9be16bcc 100644 --- a/google/ads/googleads/v19/resources/types/video.py +++ b/google/ads/googleads/v23/resources/types/video.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "Video", }, diff --git a/google/ads/googleads/v19/resources/types/webpage_view.py b/google/ads/googleads/v23/resources/types/webpage_view.py similarity index 92% rename from google/ads/googleads/v19/resources/types/webpage_view.py rename to google/ads/googleads/v23/resources/types/webpage_view.py index 6203a8d88..ea5998f0d 100644 --- a/google/ads/googleads/v19/resources/types/webpage_view.py +++ b/google/ads/googleads/v23/resources/types/webpage_view.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.resources", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.resources", + marshal="google.ads.googleads.v23", manifest={ "WebpageView", }, diff --git a/google/ads/googleads/v23/services/__init__.py b/google/ads/googleads/v23/services/__init__.py new file mode 100644 index 000000000..60671663b --- /dev/null +++ b/google/ads/googleads/v23/services/__init__.py @@ -0,0 +1,1464 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .types.account_budget_proposal_service import ( + AccountBudgetProposalOperation, + MutateAccountBudgetProposalRequest, + MutateAccountBudgetProposalResponse, + MutateAccountBudgetProposalResult, +) +from .types.account_link_service import ( + AccountLinkOperation, + CreateAccountLinkRequest, + CreateAccountLinkResponse, + MutateAccountLinkRequest, + MutateAccountLinkResponse, + MutateAccountLinkResult, +) +from .types.ad_group_ad_label_service import ( + AdGroupAdLabelOperation, + MutateAdGroupAdLabelResult, + MutateAdGroupAdLabelsRequest, + MutateAdGroupAdLabelsResponse, +) +from .types.ad_group_ad_service import ( + AdGroupAdOperation, + AssetsWithFieldType, + MutateAdGroupAdResult, + MutateAdGroupAdsRequest, + MutateAdGroupAdsResponse, + RemoveAutomaticallyCreatedAssetsRequest, +) +from .types.ad_group_asset_service import ( + AdGroupAssetOperation, + MutateAdGroupAssetResult, + MutateAdGroupAssetsRequest, + MutateAdGroupAssetsResponse, +) +from .types.ad_group_asset_set_service import ( + AdGroupAssetSetOperation, + MutateAdGroupAssetSetResult, + MutateAdGroupAssetSetsRequest, + MutateAdGroupAssetSetsResponse, +) +from .types.ad_group_bid_modifier_service import ( + AdGroupBidModifierOperation, + MutateAdGroupBidModifierResult, + MutateAdGroupBidModifiersRequest, + MutateAdGroupBidModifiersResponse, +) +from .types.ad_group_criterion_customizer_service import ( + AdGroupCriterionCustomizerOperation, + MutateAdGroupCriterionCustomizerResult, + MutateAdGroupCriterionCustomizersRequest, + MutateAdGroupCriterionCustomizersResponse, +) +from .types.ad_group_criterion_label_service import ( + AdGroupCriterionLabelOperation, + MutateAdGroupCriterionLabelResult, + MutateAdGroupCriterionLabelsRequest, + MutateAdGroupCriterionLabelsResponse, +) +from .types.ad_group_criterion_service import ( + AdGroupCriterionOperation, + MutateAdGroupCriteriaRequest, + MutateAdGroupCriteriaResponse, + MutateAdGroupCriterionResult, +) +from .types.ad_group_customizer_service import ( + AdGroupCustomizerOperation, + MutateAdGroupCustomizerResult, + MutateAdGroupCustomizersRequest, + MutateAdGroupCustomizersResponse, +) +from .types.ad_group_label_service import ( + AdGroupLabelOperation, + MutateAdGroupLabelResult, + MutateAdGroupLabelsRequest, + MutateAdGroupLabelsResponse, +) +from .types.ad_group_service import ( + AdGroupOperation, + MutateAdGroupResult, + MutateAdGroupsRequest, + MutateAdGroupsResponse, +) +from .types.ad_parameter_service import ( + AdParameterOperation, + MutateAdParameterResult, + MutateAdParametersRequest, + MutateAdParametersResponse, +) +from .types.ad_service import ( + AdOperation, + MutateAdResult, + MutateAdsRequest, + MutateAdsResponse, +) +from .types.asset_generation_service import ( + AssetGenerationExistingContext, + FinalUrlImageGenerationInput, + FreeformImageGenerationInput, + GeneratedImage, + GeneratedText, + GenerateImagesRequest, + GenerateImagesResponse, + GenerateTextRequest, + GenerateTextResponse, + ProductRecontextGenerationImageInput, + SourceImage, +) +from .types.asset_group_asset_service import ( + AssetGroupAssetOperation, + MutateAssetGroupAssetResult, + MutateAssetGroupAssetsRequest, + MutateAssetGroupAssetsResponse, +) +from .types.asset_group_listing_group_filter_service import ( + AssetGroupListingGroupFilterOperation, + MutateAssetGroupListingGroupFilterResult, + MutateAssetGroupListingGroupFiltersRequest, + MutateAssetGroupListingGroupFiltersResponse, +) +from .types.asset_group_service import ( + AssetGroupOperation, + MutateAssetGroupResult, + MutateAssetGroupsRequest, + MutateAssetGroupsResponse, +) +from .types.asset_group_signal_service import ( + AssetGroupSignalOperation, + MutateAssetGroupSignalResult, + MutateAssetGroupSignalsRequest, + MutateAssetGroupSignalsResponse, +) +from .types.asset_service import ( + AssetOperation, + MutateAssetResult, + MutateAssetsRequest, + MutateAssetsResponse, +) +from .types.asset_set_asset_service import ( + AssetSetAssetOperation, + MutateAssetSetAssetResult, + MutateAssetSetAssetsRequest, + MutateAssetSetAssetsResponse, +) +from .types.asset_set_service import ( + AssetSetOperation, + MutateAssetSetResult, + MutateAssetSetsRequest, + MutateAssetSetsResponse, +) +from .types.audience_insights_service import ( + AudienceCompositionAttribute, + AudienceCompositionAttributeCluster, + AudienceCompositionMetrics, + AudienceCompositionSection, + AudienceInsightsDimensions, + AudienceOverlapItem, + DimensionOverlapResult, + GenerateAudienceCompositionInsightsRequest, + GenerateAudienceCompositionInsightsResponse, + GenerateAudienceDefinitionRequest, + GenerateAudienceDefinitionResponse, + GenerateAudienceOverlapInsightsRequest, + GenerateAudienceOverlapInsightsResponse, + GenerateInsightsFinderReportRequest, + GenerateInsightsFinderReportResponse, + GenerateSuggestedTargetingInsightsRequest, + GenerateSuggestedTargetingInsightsResponse, + GenerateTargetingSuggestionMetricsRequest, + GenerateTargetingSuggestionMetricsResponse, + InsightsAudience, + InsightsAudienceAttributeGroup, + InsightsAudienceDefinition, + InsightsAudienceDescription, + ListAudienceInsightsAttributesRequest, + ListAudienceInsightsAttributesResponse, + ListInsightsEligibleDatesRequest, + ListInsightsEligibleDatesResponse, + TargetingSuggestionMetrics, +) +from .types.audience_service import ( + AudienceOperation, + MutateAudienceResult, + MutateAudiencesRequest, + MutateAudiencesResponse, +) +from .types.automatically_created_asset_removal_service import ( + RemoveCampaignAutomaticallyCreatedAssetOperation, + RemoveCampaignAutomaticallyCreatedAssetRequest, + RemoveCampaignAutomaticallyCreatedAssetResponse, +) +from .types.batch_job_service import ( + AddBatchJobOperationsRequest, + AddBatchJobOperationsResponse, + BatchJobOperation, + BatchJobResult, + ListBatchJobResultsRequest, + ListBatchJobResultsResponse, + MutateBatchJobRequest, + MutateBatchJobResponse, + MutateBatchJobResult, + RunBatchJobRequest, +) +from .types.benchmarks_service import ( + BenchmarksLocation, + BenchmarksProductMetadata, + BenchmarksSource, + BenchmarksSourceMetadata, + GenerateBenchmarksMetricsRequest, + GenerateBenchmarksMetricsResponse, + IndustryVerticalInfo, + ListBenchmarksAvailableDatesRequest, + ListBenchmarksAvailableDatesResponse, + ListBenchmarksLocationsRequest, + ListBenchmarksLocationsResponse, + ListBenchmarksProductsRequest, + ListBenchmarksProductsResponse, + ListBenchmarksSourcesRequest, + ListBenchmarksSourcesResponse, + Metrics, + ProductFilter, + RateMetrics, +) +from .types.bidding_data_exclusion_service import ( + BiddingDataExclusionOperation, + MutateBiddingDataExclusionsRequest, + MutateBiddingDataExclusionsResponse, + MutateBiddingDataExclusionsResult, +) +from .types.bidding_seasonality_adjustment_service import ( + BiddingSeasonalityAdjustmentOperation, + MutateBiddingSeasonalityAdjustmentsRequest, + MutateBiddingSeasonalityAdjustmentsResponse, + MutateBiddingSeasonalityAdjustmentsResult, +) +from .types.bidding_strategy_service import ( + BiddingStrategyOperation, + MutateBiddingStrategiesRequest, + MutateBiddingStrategiesResponse, + MutateBiddingStrategyResult, +) +from .types.billing_setup_service import ( + BillingSetupOperation, + MutateBillingSetupRequest, + MutateBillingSetupResponse, + MutateBillingSetupResult, +) +from .types.brand_suggestion_service import ( + BrandSuggestion, + SuggestBrandsRequest, + SuggestBrandsResponse, +) +from .types.campaign_asset_service import ( + CampaignAssetOperation, + MutateCampaignAssetResult, + MutateCampaignAssetsRequest, + MutateCampaignAssetsResponse, +) +from .types.campaign_asset_set_service import ( + CampaignAssetSetOperation, + MutateCampaignAssetSetResult, + MutateCampaignAssetSetsRequest, + MutateCampaignAssetSetsResponse, +) +from .types.campaign_bid_modifier_service import ( + CampaignBidModifierOperation, + MutateCampaignBidModifierResult, + MutateCampaignBidModifiersRequest, + MutateCampaignBidModifiersResponse, +) +from .types.campaign_budget_service import ( + CampaignBudgetOperation, + MutateCampaignBudgetResult, + MutateCampaignBudgetsRequest, + MutateCampaignBudgetsResponse, +) +from .types.campaign_conversion_goal_service import ( + CampaignConversionGoalOperation, + MutateCampaignConversionGoalResult, + MutateCampaignConversionGoalsRequest, + MutateCampaignConversionGoalsResponse, +) +from .types.campaign_criterion_service import ( + CampaignCriterionOperation, + MutateCampaignCriteriaRequest, + MutateCampaignCriteriaResponse, + MutateCampaignCriterionResult, +) +from .types.campaign_customizer_service import ( + CampaignCustomizerOperation, + MutateCampaignCustomizerResult, + MutateCampaignCustomizersRequest, + MutateCampaignCustomizersResponse, +) +from .types.campaign_draft_service import ( + CampaignDraftOperation, + ListCampaignDraftAsyncErrorsRequest, + ListCampaignDraftAsyncErrorsResponse, + MutateCampaignDraftResult, + MutateCampaignDraftsRequest, + MutateCampaignDraftsResponse, + PromoteCampaignDraftRequest, +) +from .types.campaign_goal_config_service import ( + CampaignGoalConfigOperation, + MutateCampaignGoalConfigResult, + MutateCampaignGoalConfigsRequest, + MutateCampaignGoalConfigsResponse, +) +from .types.campaign_group_service import ( + CampaignGroupOperation, + MutateCampaignGroupResult, + MutateCampaignGroupsRequest, + MutateCampaignGroupsResponse, +) +from .types.campaign_label_service import ( + CampaignLabelOperation, + MutateCampaignLabelResult, + MutateCampaignLabelsRequest, + MutateCampaignLabelsResponse, +) +from .types.campaign_lifecycle_goal_service import ( + CampaignLifecycleGoalOperation, + ConfigureCampaignLifecycleGoalsRequest, + ConfigureCampaignLifecycleGoalsResponse, + ConfigureCampaignLifecycleGoalsResult, +) +from .types.campaign_service import ( + BrandCampaignAssets, + CampaignOperation, + EnablementResult, + EnableOperation, + EnablePMaxBrandGuidelinesRequest, + EnablePMaxBrandGuidelinesResponse, + MutateCampaignResult, + MutateCampaignsRequest, + MutateCampaignsResponse, +) +from .types.campaign_shared_set_service import ( + CampaignSharedSetOperation, + MutateCampaignSharedSetResult, + MutateCampaignSharedSetsRequest, + MutateCampaignSharedSetsResponse, +) +from .types.content_creator_insights_service import ( + GenerateCreatorInsightsRequest, + GenerateCreatorInsightsResponse, + GenerateTrendingInsightsRequest, + GenerateTrendingInsightsResponse, + LanguageDistribution, + SearchAudience, + SearchTopics, + TrendInsight, + TrendInsightMetrics, + YouTubeChannelInsights, + YouTubeCreatorInsights, + YouTubeMetrics, +) +from .types.conversion_action_service import ( + ConversionActionOperation, + MutateConversionActionResult, + MutateConversionActionsRequest, + MutateConversionActionsResponse, +) +from .types.conversion_adjustment_upload_service import ( + ConversionAdjustment, + ConversionAdjustmentResult, + GclidDateTimePair, + RestatementValue, + UploadConversionAdjustmentsRequest, + UploadConversionAdjustmentsResponse, +) +from .types.conversion_custom_variable_service import ( + ConversionCustomVariableOperation, + MutateConversionCustomVariableResult, + MutateConversionCustomVariablesRequest, + MutateConversionCustomVariablesResponse, +) +from .types.conversion_goal_campaign_config_service import ( + ConversionGoalCampaignConfigOperation, + MutateConversionGoalCampaignConfigResult, + MutateConversionGoalCampaignConfigsRequest, + MutateConversionGoalCampaignConfigsResponse, +) +from .types.conversion_upload_service import ( + CallConversion, + CallConversionResult, + CartData, + ClickConversion, + ClickConversionResult, + CustomVariable, + ExternalAttributionData, + SessionAttributeKeyValuePair, + SessionAttributesKeyValuePairs, + UploadCallConversionsRequest, + UploadCallConversionsResponse, + UploadClickConversionsRequest, + UploadClickConversionsResponse, +) +from .types.conversion_value_rule_service import ( + ConversionValueRuleOperation, + MutateConversionValueRuleResult, + MutateConversionValueRulesRequest, + MutateConversionValueRulesResponse, +) +from .types.conversion_value_rule_set_service import ( + ConversionValueRuleSetOperation, + MutateConversionValueRuleSetResult, + MutateConversionValueRuleSetsRequest, + MutateConversionValueRuleSetsResponse, +) +from .types.custom_audience_service import ( + CustomAudienceOperation, + MutateCustomAudienceResult, + MutateCustomAudiencesRequest, + MutateCustomAudiencesResponse, +) +from .types.custom_conversion_goal_service import ( + CustomConversionGoalOperation, + MutateCustomConversionGoalResult, + MutateCustomConversionGoalsRequest, + MutateCustomConversionGoalsResponse, +) +from .types.custom_interest_service import ( + CustomInterestOperation, + MutateCustomInterestResult, + MutateCustomInterestsRequest, + MutateCustomInterestsResponse, +) +from .types.customer_asset_service import ( + CustomerAssetOperation, + MutateCustomerAssetResult, + MutateCustomerAssetsRequest, + MutateCustomerAssetsResponse, +) +from .types.customer_asset_set_service import ( + CustomerAssetSetOperation, + MutateCustomerAssetSetResult, + MutateCustomerAssetSetsRequest, + MutateCustomerAssetSetsResponse, +) +from .types.customer_client_link_service import ( + CustomerClientLinkOperation, + MutateCustomerClientLinkRequest, + MutateCustomerClientLinkResponse, + MutateCustomerClientLinkResult, +) +from .types.customer_conversion_goal_service import ( + CustomerConversionGoalOperation, + MutateCustomerConversionGoalResult, + MutateCustomerConversionGoalsRequest, + MutateCustomerConversionGoalsResponse, +) +from .types.customer_customizer_service import ( + CustomerCustomizerOperation, + MutateCustomerCustomizerResult, + MutateCustomerCustomizersRequest, + MutateCustomerCustomizersResponse, +) +from .types.customer_label_service import ( + CustomerLabelOperation, + MutateCustomerLabelResult, + MutateCustomerLabelsRequest, + MutateCustomerLabelsResponse, +) +from .types.customer_lifecycle_goal_service import ( + ConfigureCustomerLifecycleGoalsRequest, + ConfigureCustomerLifecycleGoalsResponse, + ConfigureCustomerLifecycleGoalsResult, + CustomerLifecycleGoalOperation, +) +from .types.customer_manager_link_service import ( + CustomerManagerLinkOperation, + MoveManagerLinkRequest, + MoveManagerLinkResponse, + MutateCustomerManagerLinkRequest, + MutateCustomerManagerLinkResponse, + MutateCustomerManagerLinkResult, +) +from .types.customer_negative_criterion_service import ( + CustomerNegativeCriterionOperation, + MutateCustomerNegativeCriteriaRequest, + MutateCustomerNegativeCriteriaResponse, + MutateCustomerNegativeCriteriaResult, +) +from .types.customer_service import ( + CreateCustomerClientRequest, + CreateCustomerClientResponse, + CustomerOperation, + ListAccessibleCustomersRequest, + ListAccessibleCustomersResponse, + MutateCustomerRequest, + MutateCustomerResponse, + MutateCustomerResult, +) +from .types.customer_sk_ad_network_conversion_value_schema_service import ( + CustomerSkAdNetworkConversionValueSchemaOperation, + MutateCustomerSkAdNetworkConversionValueSchemaRequest, + MutateCustomerSkAdNetworkConversionValueSchemaResponse, + MutateCustomerSkAdNetworkConversionValueSchemaResult, +) +from .types.customer_user_access_invitation_service import ( + CustomerUserAccessInvitationOperation, + MutateCustomerUserAccessInvitationRequest, + MutateCustomerUserAccessInvitationResponse, + MutateCustomerUserAccessInvitationResult, +) +from .types.customer_user_access_service import ( + CustomerUserAccessOperation, + MutateCustomerUserAccessRequest, + MutateCustomerUserAccessResponse, + MutateCustomerUserAccessResult, +) +from .types.customizer_attribute_service import ( + CustomizerAttributeOperation, + MutateCustomizerAttributeResult, + MutateCustomizerAttributesRequest, + MutateCustomizerAttributesResponse, +) +from .types.data_link_service import ( + CreateDataLinkRequest, + CreateDataLinkResponse, + RemoveDataLinkRequest, + RemoveDataLinkResponse, + UpdateDataLinkRequest, + UpdateDataLinkResponse, +) +from .types.experiment_arm_service import ( + ExperimentArmOperation, + MutateExperimentArmResult, + MutateExperimentArmsRequest, + MutateExperimentArmsResponse, +) +from .types.experiment_service import ( + CampaignBudgetMapping, + EndExperimentRequest, + ExperimentOperation, + GraduateExperimentRequest, + ListExperimentAsyncErrorsRequest, + ListExperimentAsyncErrorsResponse, + MutateExperimentResult, + MutateExperimentsRequest, + MutateExperimentsResponse, + PromoteExperimentMetadata, + PromoteExperimentRequest, + ScheduleExperimentMetadata, + ScheduleExperimentRequest, +) +from .types.geo_target_constant_service import ( + GeoTargetConstantSuggestion, + SuggestGeoTargetConstantsRequest, + SuggestGeoTargetConstantsResponse, +) +from .types.goal_service import ( + GoalOperation, + MutateGoalResult, + MutateGoalsRequest, + MutateGoalsResponse, +) +from .types.google_ads_field_service import ( + GetGoogleAdsFieldRequest, + SearchGoogleAdsFieldsRequest, + SearchGoogleAdsFieldsResponse, +) +from .types.google_ads_service import ( + GoogleAdsRow, + MetricAttributes, + MutateGoogleAdsRequest, + MutateGoogleAdsResponse, + MutateOperation, + MutateOperationResponse, + SearchGoogleAdsRequest, + SearchGoogleAdsResponse, + SearchGoogleAdsStreamRequest, + SearchGoogleAdsStreamResponse, + SearchSettings, +) +from .types.identity_verification_service import ( + GetIdentityVerificationRequest, + GetIdentityVerificationResponse, + IdentityVerification, + IdentityVerificationProgress, + IdentityVerificationRequirement, + StartIdentityVerificationRequest, +) +from .types.incentive_service import ( + ApplyIncentiveRequest, + ApplyIncentiveResponse, + CyoIncentives, + FetchIncentiveRequest, + FetchIncentiveResponse, + Incentive, + IncentiveOffer, +) +from .types.invoice_service import ( + ListInvoicesRequest, + ListInvoicesResponse, +) +from .types.keyword_plan_ad_group_keyword_service import ( + KeywordPlanAdGroupKeywordOperation, + MutateKeywordPlanAdGroupKeywordResult, + MutateKeywordPlanAdGroupKeywordsRequest, + MutateKeywordPlanAdGroupKeywordsResponse, +) +from .types.keyword_plan_ad_group_service import ( + KeywordPlanAdGroupOperation, + MutateKeywordPlanAdGroupResult, + MutateKeywordPlanAdGroupsRequest, + MutateKeywordPlanAdGroupsResponse, +) +from .types.keyword_plan_campaign_keyword_service import ( + KeywordPlanCampaignKeywordOperation, + MutateKeywordPlanCampaignKeywordResult, + MutateKeywordPlanCampaignKeywordsRequest, + MutateKeywordPlanCampaignKeywordsResponse, +) +from .types.keyword_plan_campaign_service import ( + KeywordPlanCampaignOperation, + MutateKeywordPlanCampaignResult, + MutateKeywordPlanCampaignsRequest, + MutateKeywordPlanCampaignsResponse, +) +from .types.keyword_plan_idea_service import ( + AdGroupKeywordSuggestion, + BiddableKeyword, + CampaignToForecast, + CriterionBidModifier, + ForecastAdGroup, + GenerateAdGroupThemesRequest, + GenerateAdGroupThemesResponse, + GenerateKeywordForecastMetricsRequest, + GenerateKeywordForecastMetricsResponse, + GenerateKeywordHistoricalMetricsRequest, + GenerateKeywordHistoricalMetricsResponse, + GenerateKeywordHistoricalMetricsResult, + GenerateKeywordIdeaResponse, + GenerateKeywordIdeaResult, + GenerateKeywordIdeasRequest, + KeywordAndUrlSeed, + KeywordForecastMetrics, + KeywordSeed, + ManualCpcBiddingStrategy, + MaximizeClicksBiddingStrategy, + MaximizeConversionsBiddingStrategy, + SiteSeed, + UnusableAdGroup, + UrlSeed, +) +from .types.keyword_plan_service import ( + KeywordPlanOperation, + MutateKeywordPlansRequest, + MutateKeywordPlansResponse, + MutateKeywordPlansResult, +) +from .types.keyword_theme_constant_service import ( + SuggestKeywordThemeConstantsRequest, + SuggestKeywordThemeConstantsResponse, +) +from .types.label_service import ( + LabelOperation, + MutateLabelResult, + MutateLabelsRequest, + MutateLabelsResponse, +) +from .types.local_services_lead_service import ( + AppendLeadConversationRequest, + AppendLeadConversationResponse, + Conversation, + ConversationOrError, + ProvideLeadFeedbackRequest, + ProvideLeadFeedbackResponse, + SurveyDissatisfied, + SurveySatisfied, +) +from .types.offline_user_data_job_service import ( + AddOfflineUserDataJobOperationsRequest, + AddOfflineUserDataJobOperationsResponse, + CreateOfflineUserDataJobRequest, + CreateOfflineUserDataJobResponse, + OfflineUserDataJobOperation, + RunOfflineUserDataJobRequest, +) +from .types.payments_account_service import ( + ListPaymentsAccountsRequest, + ListPaymentsAccountsResponse, +) +from .types.product_link_invitation_service import ( + CreateProductLinkInvitationRequest, + CreateProductLinkInvitationResponse, + RemoveProductLinkInvitationRequest, + RemoveProductLinkInvitationResponse, + UpdateProductLinkInvitationRequest, + UpdateProductLinkInvitationResponse, +) +from .types.product_link_service import ( + CreateProductLinkRequest, + CreateProductLinkResponse, + RemoveProductLinkRequest, + RemoveProductLinkResponse, +) +from .types.reach_plan_service import ( + AdvancedProductTargeting, + AudienceTargeting, + CampaignDuration, + ConversionRateSuggestion, + EffectiveFrequencyBreakdown, + EffectiveFrequencyLimit, + Forecast, + ForecastMetricOptions, + FrequencyCap, + GenerateConversionRatesRequest, + GenerateConversionRatesResponse, + GenerateReachForecastRequest, + GenerateReachForecastResponse, + ListPlannableLocationsRequest, + ListPlannableLocationsResponse, + ListPlannableProductsRequest, + ListPlannableProductsResponse, + ListPlannableUserInterestsRequest, + ListPlannableUserInterestsResponse, + ListPlannableUserListsRequest, + ListPlannableUserListsResponse, + OnTargetAudienceMetrics, + PlannableLocation, + PlannableTargeting, + PlannableUserInterest, + PlannableUserList, + PlannableUserListMetadata, + PlannedProduct, + PlannedProductForecast, + PlannedProductReachForecast, + ProductMetadata, + ReachCurve, + ReachForecast, + SurfaceTargeting, + SurfaceTargetingCombinations, + TargetFrequencySettings, + Targeting, + YouTubeSelectLineUp, + YouTubeSelectSettings, +) +from .types.recommendation_service import ( + ApplyRecommendationOperation, + ApplyRecommendationRequest, + ApplyRecommendationResponse, + ApplyRecommendationResult, + DismissRecommendationRequest, + DismissRecommendationResponse, + GenerateRecommendationsRequest, + GenerateRecommendationsResponse, +) +from .types.recommendation_subscription_service import ( + MutateRecommendationSubscriptionRequest, + MutateRecommendationSubscriptionResponse, + MutateRecommendationSubscriptionResult, + RecommendationSubscriptionOperation, +) +from .types.remarketing_action_service import ( + MutateRemarketingActionResult, + MutateRemarketingActionsRequest, + MutateRemarketingActionsResponse, + RemarketingActionOperation, +) +from .types.shareable_preview_service import ( + AssetGroupIdentifier, + GenerateShareablePreviewsRequest, + GenerateShareablePreviewsResponse, + ShareablePreview, + ShareablePreviewOrError, + ShareablePreviewResult, +) +from .types.shared_criterion_service import ( + MutateSharedCriteriaRequest, + MutateSharedCriteriaResponse, + MutateSharedCriterionResult, + SharedCriterionOperation, +) +from .types.shared_set_service import ( + MutateSharedSetResult, + MutateSharedSetsRequest, + MutateSharedSetsResponse, + SharedSetOperation, +) +from .types.smart_campaign_setting_service import ( + GetSmartCampaignStatusRequest, + GetSmartCampaignStatusResponse, + MutateSmartCampaignSettingResult, + MutateSmartCampaignSettingsRequest, + MutateSmartCampaignSettingsResponse, + SmartCampaignEligibleDetails, + SmartCampaignEndedDetails, + SmartCampaignNotEligibleDetails, + SmartCampaignPausedDetails, + SmartCampaignRemovedDetails, + SmartCampaignSettingOperation, +) +from .types.smart_campaign_suggest_service import ( + SmartCampaignSuggestionInfo, + SuggestKeywordThemesRequest, + SuggestKeywordThemesResponse, + SuggestSmartCampaignAdRequest, + SuggestSmartCampaignAdResponse, + SuggestSmartCampaignBudgetOptionsRequest, + SuggestSmartCampaignBudgetOptionsResponse, +) +from .types.third_party_app_analytics_link_service import ( + RegenerateShareableLinkIdRequest, + RegenerateShareableLinkIdResponse, +) +from .types.travel_asset_suggestion_service import ( + HotelAssetSuggestion, + HotelImageAsset, + HotelTextAsset, + SuggestTravelAssetsRequest, + SuggestTravelAssetsResponse, +) +from .types.user_data_service import ( + UploadUserDataRequest, + UploadUserDataResponse, + UserDataOperation, +) +from .types.user_list_customer_type_service import ( + MutateUserListCustomerTypeResult, + MutateUserListCustomerTypesRequest, + MutateUserListCustomerTypesResponse, + UserListCustomerTypeOperation, +) +from .types.user_list_service import ( + MutateUserListResult, + MutateUserListsRequest, + MutateUserListsResponse, + UserListOperation, +) + +__all__ = ( + "AccountBudgetProposalOperation", + "MutateAccountBudgetProposalRequest", + "MutateAccountBudgetProposalResponse", + "MutateAccountBudgetProposalResult", + "AccountLinkOperation", + "CreateAccountLinkRequest", + "CreateAccountLinkResponse", + "MutateAccountLinkRequest", + "MutateAccountLinkResponse", + "MutateAccountLinkResult", + "AdGroupAdLabelOperation", + "MutateAdGroupAdLabelResult", + "MutateAdGroupAdLabelsRequest", + "MutateAdGroupAdLabelsResponse", + "AdGroupAdOperation", + "AssetsWithFieldType", + "MutateAdGroupAdResult", + "MutateAdGroupAdsRequest", + "MutateAdGroupAdsResponse", + "RemoveAutomaticallyCreatedAssetsRequest", + "AdGroupAssetOperation", + "MutateAdGroupAssetResult", + "MutateAdGroupAssetsRequest", + "MutateAdGroupAssetsResponse", + "AdGroupAssetSetOperation", + "MutateAdGroupAssetSetResult", + "MutateAdGroupAssetSetsRequest", + "MutateAdGroupAssetSetsResponse", + "AdGroupBidModifierOperation", + "MutateAdGroupBidModifierResult", + "MutateAdGroupBidModifiersRequest", + "MutateAdGroupBidModifiersResponse", + "AdGroupCriterionCustomizerOperation", + "MutateAdGroupCriterionCustomizerResult", + "MutateAdGroupCriterionCustomizersRequest", + "MutateAdGroupCriterionCustomizersResponse", + "AdGroupCriterionLabelOperation", + "MutateAdGroupCriterionLabelResult", + "MutateAdGroupCriterionLabelsRequest", + "MutateAdGroupCriterionLabelsResponse", + "AdGroupCriterionOperation", + "MutateAdGroupCriteriaRequest", + "MutateAdGroupCriteriaResponse", + "MutateAdGroupCriterionResult", + "AdGroupCustomizerOperation", + "MutateAdGroupCustomizerResult", + "MutateAdGroupCustomizersRequest", + "MutateAdGroupCustomizersResponse", + "AdGroupLabelOperation", + "MutateAdGroupLabelResult", + "MutateAdGroupLabelsRequest", + "MutateAdGroupLabelsResponse", + "AdGroupOperation", + "MutateAdGroupResult", + "MutateAdGroupsRequest", + "MutateAdGroupsResponse", + "AdParameterOperation", + "MutateAdParameterResult", + "MutateAdParametersRequest", + "MutateAdParametersResponse", + "AdOperation", + "MutateAdResult", + "MutateAdsRequest", + "MutateAdsResponse", + "AssetGenerationExistingContext", + "FinalUrlImageGenerationInput", + "FreeformImageGenerationInput", + "GeneratedImage", + "GeneratedText", + "GenerateImagesRequest", + "GenerateImagesResponse", + "GenerateTextRequest", + "GenerateTextResponse", + "ProductRecontextGenerationImageInput", + "SourceImage", + "AssetGroupAssetOperation", + "MutateAssetGroupAssetResult", + "MutateAssetGroupAssetsRequest", + "MutateAssetGroupAssetsResponse", + "AssetGroupListingGroupFilterOperation", + "MutateAssetGroupListingGroupFilterResult", + "MutateAssetGroupListingGroupFiltersRequest", + "MutateAssetGroupListingGroupFiltersResponse", + "AssetGroupOperation", + "MutateAssetGroupResult", + "MutateAssetGroupsRequest", + "MutateAssetGroupsResponse", + "AssetGroupSignalOperation", + "MutateAssetGroupSignalResult", + "MutateAssetGroupSignalsRequest", + "MutateAssetGroupSignalsResponse", + "AssetOperation", + "MutateAssetResult", + "MutateAssetsRequest", + "MutateAssetsResponse", + "AssetSetAssetOperation", + "MutateAssetSetAssetResult", + "MutateAssetSetAssetsRequest", + "MutateAssetSetAssetsResponse", + "AssetSetOperation", + "MutateAssetSetResult", + "MutateAssetSetsRequest", + "MutateAssetSetsResponse", + "AudienceCompositionAttribute", + "AudienceCompositionAttributeCluster", + "AudienceCompositionMetrics", + "AudienceCompositionSection", + "AudienceInsightsDimensions", + "AudienceOverlapItem", + "DimensionOverlapResult", + "GenerateAudienceCompositionInsightsRequest", + "GenerateAudienceCompositionInsightsResponse", + "GenerateAudienceDefinitionRequest", + "GenerateAudienceDefinitionResponse", + "GenerateAudienceOverlapInsightsRequest", + "GenerateAudienceOverlapInsightsResponse", + "GenerateInsightsFinderReportRequest", + "GenerateInsightsFinderReportResponse", + "GenerateSuggestedTargetingInsightsRequest", + "GenerateSuggestedTargetingInsightsResponse", + "GenerateTargetingSuggestionMetricsRequest", + "GenerateTargetingSuggestionMetricsResponse", + "InsightsAudience", + "InsightsAudienceAttributeGroup", + "InsightsAudienceDefinition", + "InsightsAudienceDescription", + "ListAudienceInsightsAttributesRequest", + "ListAudienceInsightsAttributesResponse", + "ListInsightsEligibleDatesRequest", + "ListInsightsEligibleDatesResponse", + "TargetingSuggestionMetrics", + "AudienceOperation", + "MutateAudienceResult", + "MutateAudiencesRequest", + "MutateAudiencesResponse", + "RemoveCampaignAutomaticallyCreatedAssetOperation", + "RemoveCampaignAutomaticallyCreatedAssetRequest", + "RemoveCampaignAutomaticallyCreatedAssetResponse", + "AddBatchJobOperationsRequest", + "AddBatchJobOperationsResponse", + "BatchJobOperation", + "BatchJobResult", + "ListBatchJobResultsRequest", + "ListBatchJobResultsResponse", + "MutateBatchJobRequest", + "MutateBatchJobResponse", + "MutateBatchJobResult", + "RunBatchJobRequest", + "BenchmarksLocation", + "BenchmarksProductMetadata", + "BenchmarksSource", + "BenchmarksSourceMetadata", + "GenerateBenchmarksMetricsRequest", + "GenerateBenchmarksMetricsResponse", + "IndustryVerticalInfo", + "ListBenchmarksAvailableDatesRequest", + "ListBenchmarksAvailableDatesResponse", + "ListBenchmarksLocationsRequest", + "ListBenchmarksLocationsResponse", + "ListBenchmarksProductsRequest", + "ListBenchmarksProductsResponse", + "ListBenchmarksSourcesRequest", + "ListBenchmarksSourcesResponse", + "Metrics", + "ProductFilter", + "RateMetrics", + "BiddingDataExclusionOperation", + "MutateBiddingDataExclusionsRequest", + "MutateBiddingDataExclusionsResponse", + "MutateBiddingDataExclusionsResult", + "BiddingSeasonalityAdjustmentOperation", + "MutateBiddingSeasonalityAdjustmentsRequest", + "MutateBiddingSeasonalityAdjustmentsResponse", + "MutateBiddingSeasonalityAdjustmentsResult", + "BiddingStrategyOperation", + "MutateBiddingStrategiesRequest", + "MutateBiddingStrategiesResponse", + "MutateBiddingStrategyResult", + "BillingSetupOperation", + "MutateBillingSetupRequest", + "MutateBillingSetupResponse", + "MutateBillingSetupResult", + "BrandSuggestion", + "SuggestBrandsRequest", + "SuggestBrandsResponse", + "CampaignAssetOperation", + "MutateCampaignAssetResult", + "MutateCampaignAssetsRequest", + "MutateCampaignAssetsResponse", + "CampaignAssetSetOperation", + "MutateCampaignAssetSetResult", + "MutateCampaignAssetSetsRequest", + "MutateCampaignAssetSetsResponse", + "CampaignBidModifierOperation", + "MutateCampaignBidModifierResult", + "MutateCampaignBidModifiersRequest", + "MutateCampaignBidModifiersResponse", + "CampaignBudgetOperation", + "MutateCampaignBudgetResult", + "MutateCampaignBudgetsRequest", + "MutateCampaignBudgetsResponse", + "CampaignConversionGoalOperation", + "MutateCampaignConversionGoalResult", + "MutateCampaignConversionGoalsRequest", + "MutateCampaignConversionGoalsResponse", + "CampaignCriterionOperation", + "MutateCampaignCriteriaRequest", + "MutateCampaignCriteriaResponse", + "MutateCampaignCriterionResult", + "CampaignCustomizerOperation", + "MutateCampaignCustomizerResult", + "MutateCampaignCustomizersRequest", + "MutateCampaignCustomizersResponse", + "CampaignDraftOperation", + "ListCampaignDraftAsyncErrorsRequest", + "ListCampaignDraftAsyncErrorsResponse", + "MutateCampaignDraftResult", + "MutateCampaignDraftsRequest", + "MutateCampaignDraftsResponse", + "PromoteCampaignDraftRequest", + "CampaignGoalConfigOperation", + "MutateCampaignGoalConfigResult", + "MutateCampaignGoalConfigsRequest", + "MutateCampaignGoalConfigsResponse", + "CampaignGroupOperation", + "MutateCampaignGroupResult", + "MutateCampaignGroupsRequest", + "MutateCampaignGroupsResponse", + "CampaignLabelOperation", + "MutateCampaignLabelResult", + "MutateCampaignLabelsRequest", + "MutateCampaignLabelsResponse", + "CampaignLifecycleGoalOperation", + "ConfigureCampaignLifecycleGoalsRequest", + "ConfigureCampaignLifecycleGoalsResponse", + "ConfigureCampaignLifecycleGoalsResult", + "BrandCampaignAssets", + "CampaignOperation", + "EnablementResult", + "EnableOperation", + "EnablePMaxBrandGuidelinesRequest", + "EnablePMaxBrandGuidelinesResponse", + "MutateCampaignResult", + "MutateCampaignsRequest", + "MutateCampaignsResponse", + "CampaignSharedSetOperation", + "MutateCampaignSharedSetResult", + "MutateCampaignSharedSetsRequest", + "MutateCampaignSharedSetsResponse", + "GenerateCreatorInsightsRequest", + "GenerateCreatorInsightsResponse", + "GenerateTrendingInsightsRequest", + "GenerateTrendingInsightsResponse", + "LanguageDistribution", + "SearchAudience", + "SearchTopics", + "TrendInsight", + "TrendInsightMetrics", + "YouTubeChannelInsights", + "YouTubeCreatorInsights", + "YouTubeMetrics", + "ConversionActionOperation", + "MutateConversionActionResult", + "MutateConversionActionsRequest", + "MutateConversionActionsResponse", + "ConversionAdjustment", + "ConversionAdjustmentResult", + "GclidDateTimePair", + "RestatementValue", + "UploadConversionAdjustmentsRequest", + "UploadConversionAdjustmentsResponse", + "ConversionCustomVariableOperation", + "MutateConversionCustomVariableResult", + "MutateConversionCustomVariablesRequest", + "MutateConversionCustomVariablesResponse", + "ConversionGoalCampaignConfigOperation", + "MutateConversionGoalCampaignConfigResult", + "MutateConversionGoalCampaignConfigsRequest", + "MutateConversionGoalCampaignConfigsResponse", + "CallConversion", + "CallConversionResult", + "CartData", + "ClickConversion", + "ClickConversionResult", + "CustomVariable", + "ExternalAttributionData", + "SessionAttributeKeyValuePair", + "SessionAttributesKeyValuePairs", + "UploadCallConversionsRequest", + "UploadCallConversionsResponse", + "UploadClickConversionsRequest", + "UploadClickConversionsResponse", + "ConversionValueRuleOperation", + "MutateConversionValueRuleResult", + "MutateConversionValueRulesRequest", + "MutateConversionValueRulesResponse", + "ConversionValueRuleSetOperation", + "MutateConversionValueRuleSetResult", + "MutateConversionValueRuleSetsRequest", + "MutateConversionValueRuleSetsResponse", + "CustomAudienceOperation", + "MutateCustomAudienceResult", + "MutateCustomAudiencesRequest", + "MutateCustomAudiencesResponse", + "CustomConversionGoalOperation", + "MutateCustomConversionGoalResult", + "MutateCustomConversionGoalsRequest", + "MutateCustomConversionGoalsResponse", + "CustomInterestOperation", + "MutateCustomInterestResult", + "MutateCustomInterestsRequest", + "MutateCustomInterestsResponse", + "CustomerAssetOperation", + "MutateCustomerAssetResult", + "MutateCustomerAssetsRequest", + "MutateCustomerAssetsResponse", + "CustomerAssetSetOperation", + "MutateCustomerAssetSetResult", + "MutateCustomerAssetSetsRequest", + "MutateCustomerAssetSetsResponse", + "CustomerClientLinkOperation", + "MutateCustomerClientLinkRequest", + "MutateCustomerClientLinkResponse", + "MutateCustomerClientLinkResult", + "CustomerConversionGoalOperation", + "MutateCustomerConversionGoalResult", + "MutateCustomerConversionGoalsRequest", + "MutateCustomerConversionGoalsResponse", + "CustomerCustomizerOperation", + "MutateCustomerCustomizerResult", + "MutateCustomerCustomizersRequest", + "MutateCustomerCustomizersResponse", + "CustomerLabelOperation", + "MutateCustomerLabelResult", + "MutateCustomerLabelsRequest", + "MutateCustomerLabelsResponse", + "ConfigureCustomerLifecycleGoalsRequest", + "ConfigureCustomerLifecycleGoalsResponse", + "ConfigureCustomerLifecycleGoalsResult", + "CustomerLifecycleGoalOperation", + "CustomerManagerLinkOperation", + "MoveManagerLinkRequest", + "MoveManagerLinkResponse", + "MutateCustomerManagerLinkRequest", + "MutateCustomerManagerLinkResponse", + "MutateCustomerManagerLinkResult", + "CustomerNegativeCriterionOperation", + "MutateCustomerNegativeCriteriaRequest", + "MutateCustomerNegativeCriteriaResponse", + "MutateCustomerNegativeCriteriaResult", + "CreateCustomerClientRequest", + "CreateCustomerClientResponse", + "CustomerOperation", + "ListAccessibleCustomersRequest", + "ListAccessibleCustomersResponse", + "MutateCustomerRequest", + "MutateCustomerResponse", + "MutateCustomerResult", + "CustomerSkAdNetworkConversionValueSchemaOperation", + "MutateCustomerSkAdNetworkConversionValueSchemaRequest", + "MutateCustomerSkAdNetworkConversionValueSchemaResponse", + "MutateCustomerSkAdNetworkConversionValueSchemaResult", + "CustomerUserAccessInvitationOperation", + "MutateCustomerUserAccessInvitationRequest", + "MutateCustomerUserAccessInvitationResponse", + "MutateCustomerUserAccessInvitationResult", + "CustomerUserAccessOperation", + "MutateCustomerUserAccessRequest", + "MutateCustomerUserAccessResponse", + "MutateCustomerUserAccessResult", + "CustomizerAttributeOperation", + "MutateCustomizerAttributeResult", + "MutateCustomizerAttributesRequest", + "MutateCustomizerAttributesResponse", + "CreateDataLinkRequest", + "CreateDataLinkResponse", + "RemoveDataLinkRequest", + "RemoveDataLinkResponse", + "UpdateDataLinkRequest", + "UpdateDataLinkResponse", + "ExperimentArmOperation", + "MutateExperimentArmResult", + "MutateExperimentArmsRequest", + "MutateExperimentArmsResponse", + "CampaignBudgetMapping", + "EndExperimentRequest", + "ExperimentOperation", + "GraduateExperimentRequest", + "ListExperimentAsyncErrorsRequest", + "ListExperimentAsyncErrorsResponse", + "MutateExperimentResult", + "MutateExperimentsRequest", + "MutateExperimentsResponse", + "PromoteExperimentMetadata", + "PromoteExperimentRequest", + "ScheduleExperimentMetadata", + "ScheduleExperimentRequest", + "GeoTargetConstantSuggestion", + "SuggestGeoTargetConstantsRequest", + "SuggestGeoTargetConstantsResponse", + "GoalOperation", + "MutateGoalResult", + "MutateGoalsRequest", + "MutateGoalsResponse", + "GetGoogleAdsFieldRequest", + "SearchGoogleAdsFieldsRequest", + "SearchGoogleAdsFieldsResponse", + "GoogleAdsRow", + "MetricAttributes", + "MutateGoogleAdsRequest", + "MutateGoogleAdsResponse", + "MutateOperation", + "MutateOperationResponse", + "SearchGoogleAdsRequest", + "SearchGoogleAdsResponse", + "SearchGoogleAdsStreamRequest", + "SearchGoogleAdsStreamResponse", + "SearchSettings", + "GetIdentityVerificationRequest", + "GetIdentityVerificationResponse", + "IdentityVerification", + "IdentityVerificationProgress", + "IdentityVerificationRequirement", + "StartIdentityVerificationRequest", + "ApplyIncentiveRequest", + "ApplyIncentiveResponse", + "CyoIncentives", + "FetchIncentiveRequest", + "FetchIncentiveResponse", + "Incentive", + "IncentiveOffer", + "ListInvoicesRequest", + "ListInvoicesResponse", + "KeywordPlanAdGroupKeywordOperation", + "MutateKeywordPlanAdGroupKeywordResult", + "MutateKeywordPlanAdGroupKeywordsRequest", + "MutateKeywordPlanAdGroupKeywordsResponse", + "KeywordPlanAdGroupOperation", + "MutateKeywordPlanAdGroupResult", + "MutateKeywordPlanAdGroupsRequest", + "MutateKeywordPlanAdGroupsResponse", + "KeywordPlanCampaignKeywordOperation", + "MutateKeywordPlanCampaignKeywordResult", + "MutateKeywordPlanCampaignKeywordsRequest", + "MutateKeywordPlanCampaignKeywordsResponse", + "KeywordPlanCampaignOperation", + "MutateKeywordPlanCampaignResult", + "MutateKeywordPlanCampaignsRequest", + "MutateKeywordPlanCampaignsResponse", + "AdGroupKeywordSuggestion", + "BiddableKeyword", + "CampaignToForecast", + "CriterionBidModifier", + "ForecastAdGroup", + "GenerateAdGroupThemesRequest", + "GenerateAdGroupThemesResponse", + "GenerateKeywordForecastMetricsRequest", + "GenerateKeywordForecastMetricsResponse", + "GenerateKeywordHistoricalMetricsRequest", + "GenerateKeywordHistoricalMetricsResponse", + "GenerateKeywordHistoricalMetricsResult", + "GenerateKeywordIdeaResponse", + "GenerateKeywordIdeaResult", + "GenerateKeywordIdeasRequest", + "KeywordAndUrlSeed", + "KeywordForecastMetrics", + "KeywordSeed", + "ManualCpcBiddingStrategy", + "MaximizeClicksBiddingStrategy", + "MaximizeConversionsBiddingStrategy", + "SiteSeed", + "UnusableAdGroup", + "UrlSeed", + "KeywordPlanOperation", + "MutateKeywordPlansRequest", + "MutateKeywordPlansResponse", + "MutateKeywordPlansResult", + "SuggestKeywordThemeConstantsRequest", + "SuggestKeywordThemeConstantsResponse", + "LabelOperation", + "MutateLabelResult", + "MutateLabelsRequest", + "MutateLabelsResponse", + "AppendLeadConversationRequest", + "AppendLeadConversationResponse", + "Conversation", + "ConversationOrError", + "ProvideLeadFeedbackRequest", + "ProvideLeadFeedbackResponse", + "SurveyDissatisfied", + "SurveySatisfied", + "AddOfflineUserDataJobOperationsRequest", + "AddOfflineUserDataJobOperationsResponse", + "CreateOfflineUserDataJobRequest", + "CreateOfflineUserDataJobResponse", + "OfflineUserDataJobOperation", + "RunOfflineUserDataJobRequest", + "ListPaymentsAccountsRequest", + "ListPaymentsAccountsResponse", + "CreateProductLinkInvitationRequest", + "CreateProductLinkInvitationResponse", + "RemoveProductLinkInvitationRequest", + "RemoveProductLinkInvitationResponse", + "UpdateProductLinkInvitationRequest", + "UpdateProductLinkInvitationResponse", + "CreateProductLinkRequest", + "CreateProductLinkResponse", + "RemoveProductLinkRequest", + "RemoveProductLinkResponse", + "AdvancedProductTargeting", + "AudienceTargeting", + "CampaignDuration", + "ConversionRateSuggestion", + "EffectiveFrequencyBreakdown", + "EffectiveFrequencyLimit", + "Forecast", + "ForecastMetricOptions", + "FrequencyCap", + "GenerateConversionRatesRequest", + "GenerateConversionRatesResponse", + "GenerateReachForecastRequest", + "GenerateReachForecastResponse", + "ListPlannableLocationsRequest", + "ListPlannableLocationsResponse", + "ListPlannableProductsRequest", + "ListPlannableProductsResponse", + "ListPlannableUserInterestsRequest", + "ListPlannableUserInterestsResponse", + "ListPlannableUserListsRequest", + "ListPlannableUserListsResponse", + "OnTargetAudienceMetrics", + "PlannableLocation", + "PlannableTargeting", + "PlannableUserInterest", + "PlannableUserList", + "PlannableUserListMetadata", + "PlannedProduct", + "PlannedProductForecast", + "PlannedProductReachForecast", + "ProductMetadata", + "ReachCurve", + "ReachForecast", + "SurfaceTargeting", + "SurfaceTargetingCombinations", + "TargetFrequencySettings", + "Targeting", + "YouTubeSelectLineUp", + "YouTubeSelectSettings", + "ApplyRecommendationOperation", + "ApplyRecommendationRequest", + "ApplyRecommendationResponse", + "ApplyRecommendationResult", + "DismissRecommendationRequest", + "DismissRecommendationResponse", + "GenerateRecommendationsRequest", + "GenerateRecommendationsResponse", + "MutateRecommendationSubscriptionRequest", + "MutateRecommendationSubscriptionResponse", + "MutateRecommendationSubscriptionResult", + "RecommendationSubscriptionOperation", + "MutateRemarketingActionResult", + "MutateRemarketingActionsRequest", + "MutateRemarketingActionsResponse", + "RemarketingActionOperation", + "AssetGroupIdentifier", + "GenerateShareablePreviewsRequest", + "GenerateShareablePreviewsResponse", + "ShareablePreview", + "ShareablePreviewOrError", + "ShareablePreviewResult", + "MutateSharedCriteriaRequest", + "MutateSharedCriteriaResponse", + "MutateSharedCriterionResult", + "SharedCriterionOperation", + "MutateSharedSetResult", + "MutateSharedSetsRequest", + "MutateSharedSetsResponse", + "SharedSetOperation", + "GetSmartCampaignStatusRequest", + "GetSmartCampaignStatusResponse", + "MutateSmartCampaignSettingResult", + "MutateSmartCampaignSettingsRequest", + "MutateSmartCampaignSettingsResponse", + "SmartCampaignEligibleDetails", + "SmartCampaignEndedDetails", + "SmartCampaignNotEligibleDetails", + "SmartCampaignPausedDetails", + "SmartCampaignRemovedDetails", + "SmartCampaignSettingOperation", + "SmartCampaignSuggestionInfo", + "SuggestKeywordThemesRequest", + "SuggestKeywordThemesResponse", + "SuggestSmartCampaignAdRequest", + "SuggestSmartCampaignAdResponse", + "SuggestSmartCampaignBudgetOptionsRequest", + "SuggestSmartCampaignBudgetOptionsResponse", + "RegenerateShareableLinkIdRequest", + "RegenerateShareableLinkIdResponse", + "HotelAssetSuggestion", + "HotelImageAsset", + "HotelTextAsset", + "SuggestTravelAssetsRequest", + "SuggestTravelAssetsResponse", + "UploadUserDataRequest", + "UploadUserDataResponse", + "UserDataOperation", + "MutateUserListCustomerTypeResult", + "MutateUserListCustomerTypesRequest", + "MutateUserListCustomerTypesResponse", + "UserListCustomerTypeOperation", + "MutateUserListResult", + "MutateUserListsRequest", + "MutateUserListsResponse", + "UserListOperation", +) diff --git a/google/ads/googleads/v19/services/services/__init__.py b/google/ads/googleads/v23/services/services/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/__init__.py rename to google/ads/googleads/v23/services/services/__init__.py diff --git a/google/ads/googleads/v19/services/services/account_budget_proposal_service/__init__.py b/google/ads/googleads/v23/services/services/account_budget_proposal_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/account_budget_proposal_service/__init__.py rename to google/ads/googleads/v23/services/services/account_budget_proposal_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/account_budget_proposal_service/async_client.py b/google/ads/googleads/v23/services/services/account_budget_proposal_service/async_client.py new file mode 100644 index 000000000..633b4fc78 --- /dev/null +++ b/google/ads/googleads/v23/services/services/account_budget_proposal_service/async_client.py @@ -0,0 +1,458 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + account_budget_proposal_service, +) +from .transports.base import ( + AccountBudgetProposalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AccountBudgetProposalServiceClient + +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 AccountBudgetProposalServiceAsyncClient: + """A service for managing account-level budgets through + proposals. + A proposal is a request to create a new budget or make changes + to an existing one. + + Mutates: + + The CREATE operation creates a new proposal. + UPDATE operations aren't supported. + The REMOVE operation cancels a pending proposal. + """ + + _client: AccountBudgetProposalServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AccountBudgetProposalServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + AccountBudgetProposalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + AccountBudgetProposalServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AccountBudgetProposalServiceClient._DEFAULT_UNIVERSE + + account_budget_path = staticmethod( + AccountBudgetProposalServiceClient.account_budget_path + ) + parse_account_budget_path = staticmethod( + AccountBudgetProposalServiceClient.parse_account_budget_path + ) + account_budget_proposal_path = staticmethod( + AccountBudgetProposalServiceClient.account_budget_proposal_path + ) + parse_account_budget_proposal_path = staticmethod( + AccountBudgetProposalServiceClient.parse_account_budget_proposal_path + ) + billing_setup_path = staticmethod( + AccountBudgetProposalServiceClient.billing_setup_path + ) + parse_billing_setup_path = staticmethod( + AccountBudgetProposalServiceClient.parse_billing_setup_path + ) + common_billing_account_path = staticmethod( + AccountBudgetProposalServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AccountBudgetProposalServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AccountBudgetProposalServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AccountBudgetProposalServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AccountBudgetProposalServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AccountBudgetProposalServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AccountBudgetProposalServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AccountBudgetProposalServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AccountBudgetProposalServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AccountBudgetProposalServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountBudgetProposalServiceAsyncClient: The constructed client. + """ + return AccountBudgetProposalServiceClient.from_service_account_info.__func__(AccountBudgetProposalServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountBudgetProposalServiceAsyncClient: The constructed client. + """ + return AccountBudgetProposalServiceClient.from_service_account_file.__func__(AccountBudgetProposalServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AccountBudgetProposalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AccountBudgetProposalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AccountBudgetProposalServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AccountBudgetProposalServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AccountBudgetProposalServiceTransport, + Callable[..., AccountBudgetProposalServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the account budget proposal service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AccountBudgetProposalServiceTransport,Callable[..., AccountBudgetProposalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AccountBudgetProposalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AccountBudgetProposalServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AccountBudgetProposalServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AccountBudgetProposalService", + "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.ads.googleads.v23.services.AccountBudgetProposalService", + "credentialsType": None, + } + ), + ) + + async def mutate_account_budget_proposal( + self, + request: Optional[ + Union[ + account_budget_proposal_service.MutateAccountBudgetProposalRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + account_budget_proposal_service.AccountBudgetProposalOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> account_budget_proposal_service.MutateAccountBudgetProposalResponse: + r"""Creates, updates, or removes account budget proposals. Operation + statuses are returned. + + List of thrown errors: `AccountBudgetProposalError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `DatabaseError <>`__ `DateError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAccountBudgetProposalRequest, dict]]): + The request object. Request message for + [AccountBudgetProposalService.MutateAccountBudgetProposal][google.ads.googleads.v23.services.AccountBudgetProposalService.MutateAccountBudgetProposal]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (:class:`google.ads.googleads.v23.services.types.AccountBudgetProposalOperation`): + Required. The operation to perform on + an individual account-level budget + proposal. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAccountBudgetProposalResponse: + Response message for account-level + budget mutate operations. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + account_budget_proposal_service.MutateAccountBudgetProposalRequest, + ): + request = account_budget_proposal_service.MutateAccountBudgetProposalRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_account_budget_proposal + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AccountBudgetProposalServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AccountBudgetProposalServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/account_budget_proposal_service/client.py b/google/ads/googleads/v23/services/services/account_budget_proposal_service/client.py new file mode 100644 index 000000000..d9a13d69e --- /dev/null +++ b/google/ads/googleads/v23/services/services/account_budget_proposal_service/client.py @@ -0,0 +1,965 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + account_budget_proposal_service, +) +from .transports.base import ( + AccountBudgetProposalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AccountBudgetProposalServiceGrpcTransport +from .transports.grpc_asyncio import ( + AccountBudgetProposalServiceGrpcAsyncIOTransport, +) + + +class AccountBudgetProposalServiceClientMeta(type): + """Metaclass for the AccountBudgetProposalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AccountBudgetProposalServiceTransport]] + _transport_registry["grpc"] = AccountBudgetProposalServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AccountBudgetProposalServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AccountBudgetProposalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AccountBudgetProposalServiceClient( + metaclass=AccountBudgetProposalServiceClientMeta +): + """A service for managing account-level budgets through + proposals. + A proposal is a request to create a new budget or make changes + to an existing one. + + Mutates: + + The CREATE operation creates a new proposal. + UPDATE operations aren't supported. + The REMOVE operation cancels a pending proposal. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountBudgetProposalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountBudgetProposalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AccountBudgetProposalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AccountBudgetProposalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def account_budget_path( + customer_id: str, + account_budget_id: str, + ) -> str: + """Returns a fully-qualified account_budget string.""" + return ( + "customers/{customer_id}/accountBudgets/{account_budget_id}".format( + customer_id=customer_id, + account_budget_id=account_budget_id, + ) + ) + + @staticmethod + def parse_account_budget_path(path: str) -> Dict[str, str]: + """Parses a account_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def account_budget_proposal_path( + customer_id: str, + account_budget_proposal_id: str, + ) -> str: + """Returns a fully-qualified account_budget_proposal string.""" + return "customers/{customer_id}/accountBudgetProposals/{account_budget_proposal_id}".format( + customer_id=customer_id, + account_budget_proposal_id=account_budget_proposal_id, + ) + + @staticmethod + def parse_account_budget_proposal_path(path: str) -> Dict[str, str]: + """Parses a account_budget_proposal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountBudgetProposals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def billing_setup_path( + customer_id: str, + billing_setup_id: str, + ) -> str: + """Returns a fully-qualified billing_setup string.""" + return ( + "customers/{customer_id}/billingSetups/{billing_setup_id}".format( + customer_id=customer_id, + billing_setup_id=billing_setup_id, + ) + ) + + @staticmethod + def parse_billing_setup_path(path: str) -> Dict[str, str]: + """Parses a billing_setup path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/billingSetups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AccountBudgetProposalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AccountBudgetProposalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + AccountBudgetProposalServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + AccountBudgetProposalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = AccountBudgetProposalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AccountBudgetProposalServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AccountBudgetProposalServiceTransport, + Callable[..., AccountBudgetProposalServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the account budget proposal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AccountBudgetProposalServiceTransport,Callable[..., AccountBudgetProposalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AccountBudgetProposalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AccountBudgetProposalServiceClient._read_environment_variables() + self._client_cert_source = ( + AccountBudgetProposalServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AccountBudgetProposalServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AccountBudgetProposalServiceTransport + ) + if transport_provided: + # transport is a AccountBudgetProposalServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + AccountBudgetProposalServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AccountBudgetProposalServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AccountBudgetProposalServiceTransport], + Callable[..., AccountBudgetProposalServiceTransport], + ] = ( + AccountBudgetProposalServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AccountBudgetProposalServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AccountBudgetProposalServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AccountBudgetProposalService", + "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.ads.googleads.v23.services.AccountBudgetProposalService", + "credentialsType": None, + } + ), + ) + + def mutate_account_budget_proposal( + self, + request: Optional[ + Union[ + account_budget_proposal_service.MutateAccountBudgetProposalRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + account_budget_proposal_service.AccountBudgetProposalOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> account_budget_proposal_service.MutateAccountBudgetProposalResponse: + r"""Creates, updates, or removes account budget proposals. Operation + statuses are returned. + + List of thrown errors: `AccountBudgetProposalError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `DatabaseError <>`__ `DateError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAccountBudgetProposalRequest, dict]): + The request object. Request message for + [AccountBudgetProposalService.MutateAccountBudgetProposal][google.ads.googleads.v23.services.AccountBudgetProposalService.MutateAccountBudgetProposal]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v23.services.types.AccountBudgetProposalOperation): + Required. The operation to perform on + an individual account-level budget + proposal. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAccountBudgetProposalResponse: + Response message for account-level + budget mutate operations. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + account_budget_proposal_service.MutateAccountBudgetProposalRequest, + ): + request = account_budget_proposal_service.MutateAccountBudgetProposalRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_account_budget_proposal + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AccountBudgetProposalServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AccountBudgetProposalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/README.rst b/google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/README.rst rename to google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/__init__.py b/google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/account_budget_proposal_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/base.py b/google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/base.py new file mode 100644 index 000000000..0e54b0e5e --- /dev/null +++ b/google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + account_budget_proposal_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AccountBudgetProposalServiceTransport(abc.ABC): + """Abstract transport class for AccountBudgetProposalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_account_budget_proposal: gapic_v1.method.wrap_method( + self.mutate_account_budget_proposal, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_account_budget_proposal( + self, + ) -> Callable[ + [account_budget_proposal_service.MutateAccountBudgetProposalRequest], + Union[ + account_budget_proposal_service.MutateAccountBudgetProposalResponse, + Awaitable[ + account_budget_proposal_service.MutateAccountBudgetProposalResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AccountBudgetProposalServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/grpc.py b/google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/grpc.py new file mode 100644 index 000000000..a506b4b36 --- /dev/null +++ b/google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/grpc.py @@ -0,0 +1,404 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + account_budget_proposal_service, +) +from .base import AccountBudgetProposalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AccountBudgetProposalService", + "rpcName": str(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.ads.googleads.v23.services.AccountBudgetProposalService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AccountBudgetProposalServiceGrpcTransport( + AccountBudgetProposalServiceTransport +): + """gRPC backend transport for AccountBudgetProposalService. + + A service for managing account-level budgets through + proposals. + A proposal is a request to create a new budget or make changes + to an existing one. + + Mutates: + + The CREATE operation creates a new proposal. + UPDATE operations aren't supported. + The REMOVE operation cancels a pending proposal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_account_budget_proposal( + self, + ) -> Callable[ + [account_budget_proposal_service.MutateAccountBudgetProposalRequest], + account_budget_proposal_service.MutateAccountBudgetProposalResponse, + ]: + r"""Return a callable for the mutate account budget proposal method over gRPC. + + Creates, updates, or removes account budget proposals. Operation + statuses are returned. + + List of thrown errors: `AccountBudgetProposalError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `DatabaseError <>`__ `DateError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateAccountBudgetProposalRequest], + ~.MutateAccountBudgetProposalResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_account_budget_proposal" not in self._stubs: + self._stubs["mutate_account_budget_proposal"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AccountBudgetProposalService/MutateAccountBudgetProposal", + request_serializer=account_budget_proposal_service.MutateAccountBudgetProposalRequest.serialize, + response_deserializer=account_budget_proposal_service.MutateAccountBudgetProposalResponse.deserialize, + ) + ) + return self._stubs["mutate_account_budget_proposal"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AccountBudgetProposalServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..da05c5883 --- /dev/null +++ b/google/ads/googleads/v23/services/services/account_budget_proposal_service/transports/grpc_asyncio.py @@ -0,0 +1,427 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + account_budget_proposal_service, +) +from .base import AccountBudgetProposalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AccountBudgetProposalService", + "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.ads.googleads.v23.services.AccountBudgetProposalService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AccountBudgetProposalServiceGrpcAsyncIOTransport( + AccountBudgetProposalServiceTransport +): + """gRPC AsyncIO backend transport for AccountBudgetProposalService. + + A service for managing account-level budgets through + proposals. + A proposal is a request to create a new budget or make changes + to an existing one. + + Mutates: + + The CREATE operation creates a new proposal. + UPDATE operations aren't supported. + The REMOVE operation cancels a pending proposal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_account_budget_proposal( + self, + ) -> Callable[ + [account_budget_proposal_service.MutateAccountBudgetProposalRequest], + Awaitable[ + account_budget_proposal_service.MutateAccountBudgetProposalResponse + ], + ]: + r"""Return a callable for the mutate account budget proposal method over gRPC. + + Creates, updates, or removes account budget proposals. Operation + statuses are returned. + + List of thrown errors: `AccountBudgetProposalError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `DatabaseError <>`__ `DateError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateAccountBudgetProposalRequest], + Awaitable[~.MutateAccountBudgetProposalResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_account_budget_proposal" not in self._stubs: + self._stubs["mutate_account_budget_proposal"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AccountBudgetProposalService/MutateAccountBudgetProposal", + request_serializer=account_budget_proposal_service.MutateAccountBudgetProposalRequest.serialize, + response_deserializer=account_budget_proposal_service.MutateAccountBudgetProposalResponse.deserialize, + ) + ) + return self._stubs["mutate_account_budget_proposal"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_account_budget_proposal: self._wrap_method( + self.mutate_account_budget_proposal, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AccountBudgetProposalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/account_link_service/__init__.py b/google/ads/googleads/v23/services/services/account_link_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/account_link_service/__init__.py rename to google/ads/googleads/v23/services/services/account_link_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/account_link_service/async_client.py b/google/ads/googleads/v23/services/services/account_link_service/async_client.py new file mode 100644 index 000000000..10ba28caf --- /dev/null +++ b/google/ads/googleads/v23/services/services/account_link_service/async_client.py @@ -0,0 +1,532 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.resources.types import ( + account_link as gagr_account_link, +) +from google.ads.googleads.v23.services.types import account_link_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AccountLinkServiceTransport, DEFAULT_CLIENT_INFO +from .client import AccountLinkServiceClient + +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 AccountLinkServiceAsyncClient: + """This service allows management of links between Google Ads + accounts and other accounts. + """ + + _client: AccountLinkServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AccountLinkServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AccountLinkServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AccountLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AccountLinkServiceClient._DEFAULT_UNIVERSE + + account_link_path = staticmethod(AccountLinkServiceClient.account_link_path) + parse_account_link_path = staticmethod( + AccountLinkServiceClient.parse_account_link_path + ) + common_billing_account_path = staticmethod( + AccountLinkServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AccountLinkServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AccountLinkServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AccountLinkServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AccountLinkServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AccountLinkServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AccountLinkServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AccountLinkServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AccountLinkServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AccountLinkServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountLinkServiceAsyncClient: The constructed client. + """ + return AccountLinkServiceClient.from_service_account_info.__func__(AccountLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountLinkServiceAsyncClient: The constructed client. + """ + return AccountLinkServiceClient.from_service_account_file.__func__(AccountLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AccountLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AccountLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AccountLinkServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AccountLinkServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AccountLinkServiceTransport, + Callable[..., AccountLinkServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the account link service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AccountLinkServiceTransport,Callable[..., AccountLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AccountLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AccountLinkServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AccountLinkServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AccountLinkService", + "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.ads.googleads.v23.services.AccountLinkService", + "credentialsType": None, + } + ), + ) + + async def create_account_link( + self, + request: Optional[ + Union[account_link_service.CreateAccountLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + account_link: Optional[gagr_account_link.AccountLink] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> account_link_service.CreateAccountLinkResponse: + r"""Creates an account link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ThirdPartyAppAnalyticsLinkError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.CreateAccountLinkRequest, dict]]): + The request object. Request message for + [AccountLinkService.CreateAccountLink][google.ads.googleads.v23.services.AccountLinkService.CreateAccountLink]. + customer_id (:class:`str`): + Required. The ID of the customer for + which the account link is created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + account_link (:class:`google.ads.googleads.v23.resources.types.AccountLink`): + Required. The account link to be + created. + + This corresponds to the ``account_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateAccountLinkResponse: + Response message for + [AccountLinkService.CreateAccountLink][google.ads.googleads.v23.services.AccountLinkService.CreateAccountLink]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, account_link] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, account_link_service.CreateAccountLinkRequest + ): + request = account_link_service.CreateAccountLinkRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if account_link is not None: + request.account_link = account_link + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_account_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def mutate_account_link( + self, + request: Optional[ + Union[account_link_service.MutateAccountLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[account_link_service.AccountLinkOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> account_link_service.MutateAccountLinkResponse: + r"""Creates or removes an account link. From V5, create is not + supported through AccountLinkService.MutateAccountLink. Use + AccountLinkService.CreateAccountLink instead. + + List of thrown errors: `AccountLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAccountLinkRequest, dict]]): + The request object. Request message for + [AccountLinkService.MutateAccountLink][google.ads.googleads.v23.services.AccountLinkService.MutateAccountLink]. + customer_id (:class:`str`): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (:class:`google.ads.googleads.v23.services.types.AccountLinkOperation`): + Required. The operation to perform on + the link. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAccountLinkResponse: + Response message for account link + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, account_link_service.MutateAccountLinkRequest + ): + request = account_link_service.MutateAccountLinkRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_account_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AccountLinkServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AccountLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/account_link_service/client.py b/google/ads/googleads/v23/services/services/account_link_service/client.py new file mode 100644 index 000000000..d02d2d238 --- /dev/null +++ b/google/ads/googleads/v23/services/services/account_link_service/client.py @@ -0,0 +1,987 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.resources.types import ( + account_link as gagr_account_link, +) +from google.ads.googleads.v23.services.types import account_link_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AccountLinkServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AccountLinkServiceGrpcTransport +from .transports.grpc_asyncio import AccountLinkServiceGrpcAsyncIOTransport + + +class AccountLinkServiceClientMeta(type): + """Metaclass for the AccountLinkService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AccountLinkServiceTransport]] + _transport_registry["grpc"] = AccountLinkServiceGrpcTransport + _transport_registry["grpc_asyncio"] = AccountLinkServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AccountLinkServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AccountLinkServiceClient(metaclass=AccountLinkServiceClientMeta): + """This service allows management of links between Google Ads + accounts and other accounts. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AccountLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AccountLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AccountLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def account_link_path( + customer_id: str, + account_link_id: str, + ) -> str: + """Returns a fully-qualified account_link string.""" + return "customers/{customer_id}/accountLinks/{account_link_id}".format( + customer_id=customer_id, + account_link_id=account_link_id, + ) + + @staticmethod + def parse_account_link_path(path: str) -> Dict[str, str]: + """Parses a account_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AccountLinkServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AccountLinkServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AccountLinkServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AccountLinkServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AccountLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AccountLinkServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AccountLinkServiceTransport, + Callable[..., AccountLinkServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the account link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AccountLinkServiceTransport,Callable[..., AccountLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AccountLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AccountLinkServiceClient._read_environment_variables() + self._client_cert_source = ( + AccountLinkServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = AccountLinkServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AccountLinkServiceTransport) + if transport_provided: + # transport is a AccountLinkServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AccountLinkServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AccountLinkServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AccountLinkServiceTransport], + Callable[..., AccountLinkServiceTransport], + ] = ( + AccountLinkServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AccountLinkServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AccountLinkServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AccountLinkService", + "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.ads.googleads.v23.services.AccountLinkService", + "credentialsType": None, + } + ), + ) + + def create_account_link( + self, + request: Optional[ + Union[account_link_service.CreateAccountLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + account_link: Optional[gagr_account_link.AccountLink] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> account_link_service.CreateAccountLinkResponse: + r"""Creates an account link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ThirdPartyAppAnalyticsLinkError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.CreateAccountLinkRequest, dict]): + The request object. Request message for + [AccountLinkService.CreateAccountLink][google.ads.googleads.v23.services.AccountLinkService.CreateAccountLink]. + customer_id (str): + Required. The ID of the customer for + which the account link is created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + account_link (google.ads.googleads.v23.resources.types.AccountLink): + Required. The account link to be + created. + + This corresponds to the ``account_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateAccountLinkResponse: + Response message for + [AccountLinkService.CreateAccountLink][google.ads.googleads.v23.services.AccountLinkService.CreateAccountLink]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, account_link] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, account_link_service.CreateAccountLinkRequest + ): + request = account_link_service.CreateAccountLinkRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if account_link is not None: + request.account_link = account_link + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_account_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def mutate_account_link( + self, + request: Optional[ + Union[account_link_service.MutateAccountLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[account_link_service.AccountLinkOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> account_link_service.MutateAccountLinkResponse: + r"""Creates or removes an account link. From V5, create is not + supported through AccountLinkService.MutateAccountLink. Use + AccountLinkService.CreateAccountLink instead. + + List of thrown errors: `AccountLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAccountLinkRequest, dict]): + The request object. Request message for + [AccountLinkService.MutateAccountLink][google.ads.googleads.v23.services.AccountLinkService.MutateAccountLink]. + customer_id (str): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v23.services.types.AccountLinkOperation): + Required. The operation to perform on + the link. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAccountLinkResponse: + Response message for account link + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, account_link_service.MutateAccountLinkRequest + ): + request = account_link_service.MutateAccountLinkRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_account_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AccountLinkServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AccountLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/account_link_service/transports/README.rst b/google/ads/googleads/v23/services/services/account_link_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/account_link_service/transports/README.rst rename to google/ads/googleads/v23/services/services/account_link_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/account_link_service/transports/__init__.py b/google/ads/googleads/v23/services/services/account_link_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/account_link_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/account_link_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/account_link_service/transports/base.py b/google/ads/googleads/v23/services/services/account_link_service/transports/base.py new file mode 100644 index 000000000..f95655a45 --- /dev/null +++ b/google/ads/googleads/v23/services/services/account_link_service/transports/base.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import account_link_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AccountLinkServiceTransport(abc.ABC): + """Abstract transport class for AccountLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_account_link: gapic_v1.method.wrap_method( + self.create_account_link, + default_timeout=None, + client_info=client_info, + ), + self.mutate_account_link: gapic_v1.method.wrap_method( + self.mutate_account_link, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def create_account_link( + self, + ) -> Callable[ + [account_link_service.CreateAccountLinkRequest], + Union[ + account_link_service.CreateAccountLinkResponse, + Awaitable[account_link_service.CreateAccountLinkResponse], + ], + ]: + raise NotImplementedError() + + @property + def mutate_account_link( + self, + ) -> Callable[ + [account_link_service.MutateAccountLinkRequest], + Union[ + account_link_service.MutateAccountLinkResponse, + Awaitable[account_link_service.MutateAccountLinkResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AccountLinkServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/account_link_service/transports/grpc.py b/google/ads/googleads/v23/services/services/account_link_service/transports/grpc.py new file mode 100644 index 000000000..f8ebe8dbd --- /dev/null +++ b/google/ads/googleads/v23/services/services/account_link_service/transports/grpc.py @@ -0,0 +1,428 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import account_link_service +from .base import AccountLinkServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AccountLinkService", + "rpcName": str(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.ads.googleads.v23.services.AccountLinkService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AccountLinkServiceGrpcTransport(AccountLinkServiceTransport): + """gRPC backend transport for AccountLinkService. + + This service allows management of links between Google Ads + accounts and other accounts. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def create_account_link( + self, + ) -> Callable[ + [account_link_service.CreateAccountLinkRequest], + account_link_service.CreateAccountLinkResponse, + ]: + r"""Return a callable for the create account link method over gRPC. + + Creates an account link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ThirdPartyAppAnalyticsLinkError <>`__ + + Returns: + Callable[[~.CreateAccountLinkRequest], + ~.CreateAccountLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_account_link" not in self._stubs: + self._stubs["create_account_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AccountLinkService/CreateAccountLink", + request_serializer=account_link_service.CreateAccountLinkRequest.serialize, + response_deserializer=account_link_service.CreateAccountLinkResponse.deserialize, + ) + ) + return self._stubs["create_account_link"] + + @property + def mutate_account_link( + self, + ) -> Callable[ + [account_link_service.MutateAccountLinkRequest], + account_link_service.MutateAccountLinkResponse, + ]: + r"""Return a callable for the mutate account link method over gRPC. + + Creates or removes an account link. From V5, create is not + supported through AccountLinkService.MutateAccountLink. Use + AccountLinkService.CreateAccountLink instead. + + List of thrown errors: `AccountLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAccountLinkRequest], + ~.MutateAccountLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_account_link" not in self._stubs: + self._stubs["mutate_account_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AccountLinkService/MutateAccountLink", + request_serializer=account_link_service.MutateAccountLinkRequest.serialize, + response_deserializer=account_link_service.MutateAccountLinkResponse.deserialize, + ) + ) + return self._stubs["mutate_account_link"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AccountLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/account_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/account_link_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..24742d36d --- /dev/null +++ b/google/ads/googleads/v23/services/services/account_link_service/transports/grpc_asyncio.py @@ -0,0 +1,454 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import account_link_service +from .base import AccountLinkServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AccountLinkService", + "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.ads.googleads.v23.services.AccountLinkService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AccountLinkServiceGrpcAsyncIOTransport(AccountLinkServiceTransport): + """gRPC AsyncIO backend transport for AccountLinkService. + + This service allows management of links between Google Ads + accounts and other accounts. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def create_account_link( + self, + ) -> Callable[ + [account_link_service.CreateAccountLinkRequest], + Awaitable[account_link_service.CreateAccountLinkResponse], + ]: + r"""Return a callable for the create account link method over gRPC. + + Creates an account link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ThirdPartyAppAnalyticsLinkError <>`__ + + Returns: + Callable[[~.CreateAccountLinkRequest], + Awaitable[~.CreateAccountLinkResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_account_link" not in self._stubs: + self._stubs["create_account_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AccountLinkService/CreateAccountLink", + request_serializer=account_link_service.CreateAccountLinkRequest.serialize, + response_deserializer=account_link_service.CreateAccountLinkResponse.deserialize, + ) + ) + return self._stubs["create_account_link"] + + @property + def mutate_account_link( + self, + ) -> Callable[ + [account_link_service.MutateAccountLinkRequest], + Awaitable[account_link_service.MutateAccountLinkResponse], + ]: + r"""Return a callable for the mutate account link method over gRPC. + + Creates or removes an account link. From V5, create is not + supported through AccountLinkService.MutateAccountLink. Use + AccountLinkService.CreateAccountLink instead. + + List of thrown errors: `AccountLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAccountLinkRequest], + Awaitable[~.MutateAccountLinkResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_account_link" not in self._stubs: + self._stubs["mutate_account_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AccountLinkService/MutateAccountLink", + request_serializer=account_link_service.MutateAccountLinkRequest.serialize, + response_deserializer=account_link_service.MutateAccountLinkResponse.deserialize, + ) + ) + return self._stubs["mutate_account_link"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.create_account_link: self._wrap_method( + self.create_account_link, + default_timeout=None, + client_info=client_info, + ), + self.mutate_account_link: self._wrap_method( + self.mutate_account_link, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AccountLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/__init__.py b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_ad_label_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_ad_label_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_ad_label_service/async_client.py b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/async_client.py new file mode 100644 index 000000000..ca44cee12 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/async_client.py @@ -0,0 +1,436 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_ad_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupAdLabelServiceTransport, DEFAULT_CLIENT_INFO +from .client import AdGroupAdLabelServiceClient + +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 AdGroupAdLabelServiceAsyncClient: + """Service to manage labels on ad group ads.""" + + _client: AdGroupAdLabelServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdGroupAdLabelServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AdGroupAdLabelServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AdGroupAdLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AdGroupAdLabelServiceClient._DEFAULT_UNIVERSE + + ad_group_ad_path = staticmethod( + AdGroupAdLabelServiceClient.ad_group_ad_path + ) + parse_ad_group_ad_path = staticmethod( + AdGroupAdLabelServiceClient.parse_ad_group_ad_path + ) + ad_group_ad_label_path = staticmethod( + AdGroupAdLabelServiceClient.ad_group_ad_label_path + ) + parse_ad_group_ad_label_path = staticmethod( + AdGroupAdLabelServiceClient.parse_ad_group_ad_label_path + ) + label_path = staticmethod(AdGroupAdLabelServiceClient.label_path) + parse_label_path = staticmethod( + AdGroupAdLabelServiceClient.parse_label_path + ) + common_billing_account_path = staticmethod( + AdGroupAdLabelServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdGroupAdLabelServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AdGroupAdLabelServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AdGroupAdLabelServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdGroupAdLabelServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdGroupAdLabelServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AdGroupAdLabelServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AdGroupAdLabelServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdGroupAdLabelServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdGroupAdLabelServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdLabelServiceAsyncClient: The constructed client. + """ + return AdGroupAdLabelServiceClient.from_service_account_info.__func__(AdGroupAdLabelServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdLabelServiceAsyncClient: The constructed client. + """ + return AdGroupAdLabelServiceClient.from_service_account_file.__func__(AdGroupAdLabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdGroupAdLabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdGroupAdLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAdLabelServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdGroupAdLabelServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupAdLabelServiceTransport, + Callable[..., AdGroupAdLabelServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group ad label service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupAdLabelServiceTransport,Callable[..., AdGroupAdLabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupAdLabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdGroupAdLabelServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdGroupAdLabelServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupAdLabelService", + "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.ads.googleads.v23.services.AdGroupAdLabelService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_group_ad_labels( + self, + request: Optional[ + Union[ad_group_ad_label_service.MutateAdGroupAdLabelsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_ad_label_service.AdGroupAdLabelOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_ad_label_service.MutateAdGroupAdLabelsResponse: + r"""Creates and removes ad group ad labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdGroupAdLabelsRequest, dict]]): + The request object. Request message for + [AdGroupAdLabelService.MutateAdGroupAdLabels][google.ads.googleads.v23.services.AdGroupAdLabelService.MutateAdGroupAdLabels]. + customer_id (:class:`str`): + Required. ID of the customer whose ad + group ad labels are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdGroupAdLabelOperation]`): + Required. The list of operations to + perform on ad group ad labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupAdLabelsResponse: + Response message for an ad group ad + labels mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_ad_label_service.MutateAdGroupAdLabelsRequest + ): + request = ad_group_ad_label_service.MutateAdGroupAdLabelsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_group_ad_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AdGroupAdLabelServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdGroupAdLabelServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_group_ad_label_service/client.py b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/client.py new file mode 100644 index 000000000..aef31cd2b --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/client.py @@ -0,0 +1,949 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ad_group_ad_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupAdLabelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdGroupAdLabelServiceGrpcTransport +from .transports.grpc_asyncio import AdGroupAdLabelServiceGrpcAsyncIOTransport + + +class AdGroupAdLabelServiceClientMeta(type): + """Metaclass for the AdGroupAdLabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupAdLabelServiceTransport]] + _transport_registry["grpc"] = AdGroupAdLabelServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AdGroupAdLabelServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdGroupAdLabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupAdLabelServiceClient(metaclass=AdGroupAdLabelServiceClientMeta): + """Service to manage labels on ad group ads.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupAdLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAdLabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_ad_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad string.""" + return ( + "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + ) + ) + + @staticmethod + def parse_ad_group_ad_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_label_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_label string.""" + return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path( + customer_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, + label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AdGroupAdLabelServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AdGroupAdLabelServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AdGroupAdLabelServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdGroupAdLabelServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AdGroupAdLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdGroupAdLabelServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupAdLabelServiceTransport, + Callable[..., AdGroupAdLabelServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group ad label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupAdLabelServiceTransport,Callable[..., AdGroupAdLabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupAdLabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdGroupAdLabelServiceClient._read_environment_variables() + self._client_cert_source = ( + AdGroupAdLabelServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AdGroupAdLabelServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AdGroupAdLabelServiceTransport + ) + if transport_provided: + # transport is a AdGroupAdLabelServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AdGroupAdLabelServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdGroupAdLabelServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdGroupAdLabelServiceTransport], + Callable[..., AdGroupAdLabelServiceTransport], + ] = ( + AdGroupAdLabelServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AdGroupAdLabelServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdGroupAdLabelServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupAdLabelService", + "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.ads.googleads.v23.services.AdGroupAdLabelService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_group_ad_labels( + self, + request: Optional[ + Union[ad_group_ad_label_service.MutateAdGroupAdLabelsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_ad_label_service.AdGroupAdLabelOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_ad_label_service.MutateAdGroupAdLabelsResponse: + r"""Creates and removes ad group ad labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdGroupAdLabelsRequest, dict]): + The request object. Request message for + [AdGroupAdLabelService.MutateAdGroupAdLabels][google.ads.googleads.v23.services.AdGroupAdLabelService.MutateAdGroupAdLabels]. + customer_id (str): + Required. ID of the customer whose ad + group ad labels are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupAdLabelOperation]): + Required. The list of operations to + perform on ad group ad labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupAdLabelsResponse: + Response message for an ad group ad + labels mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_ad_label_service.MutateAdGroupAdLabelsRequest + ): + request = ad_group_ad_label_service.MutateAdGroupAdLabelsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_ad_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdGroupAdLabelServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdGroupAdLabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_ad_label_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/base.py new file mode 100644 index 000000000..478d75573 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ad_group_ad_label_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdGroupAdLabelServiceTransport(abc.ABC): + """Abstract transport class for AdGroupAdLabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_ad_labels: gapic_v1.method.wrap_method( + self.mutate_ad_group_ad_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_ad_labels( + self, + ) -> Callable[ + [ad_group_ad_label_service.MutateAdGroupAdLabelsRequest], + Union[ + ad_group_ad_label_service.MutateAdGroupAdLabelsResponse, + Awaitable[ad_group_ad_label_service.MutateAdGroupAdLabelsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdGroupAdLabelServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/grpc.py new file mode 100644 index 000000000..112e16435 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/grpc.py @@ -0,0 +1,390 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ad_group_ad_label_service +from .base import AdGroupAdLabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdGroupAdLabelService", + "rpcName": str(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.ads.googleads.v23.services.AdGroupAdLabelService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupAdLabelServiceGrpcTransport(AdGroupAdLabelServiceTransport): + """gRPC backend transport for AdGroupAdLabelService. + + Service to manage labels on ad group ads. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_group_ad_labels( + self, + ) -> Callable[ + [ad_group_ad_label_service.MutateAdGroupAdLabelsRequest], + ad_group_ad_label_service.MutateAdGroupAdLabelsResponse, + ]: + r"""Return a callable for the mutate ad group ad labels method over gRPC. + + Creates and removes ad group ad labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupAdLabelsRequest], + ~.MutateAdGroupAdLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_ad_labels" not in self._stubs: + self._stubs["mutate_ad_group_ad_labels"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupAdLabelService/MutateAdGroupAdLabels", + request_serializer=ad_group_ad_label_service.MutateAdGroupAdLabelsRequest.serialize, + response_deserializer=ad_group_ad_label_service.MutateAdGroupAdLabelsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_ad_labels"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdGroupAdLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..6445ae4e1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_ad_label_service/transports/grpc_asyncio.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_ad_label_service +from .base import AdGroupAdLabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdGroupAdLabelService", + "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.ads.googleads.v23.services.AdGroupAdLabelService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupAdLabelServiceGrpcAsyncIOTransport(AdGroupAdLabelServiceTransport): + """gRPC AsyncIO backend transport for AdGroupAdLabelService. + + Service to manage labels on ad group ads. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_group_ad_labels( + self, + ) -> Callable[ + [ad_group_ad_label_service.MutateAdGroupAdLabelsRequest], + Awaitable[ad_group_ad_label_service.MutateAdGroupAdLabelsResponse], + ]: + r"""Return a callable for the mutate ad group ad labels method over gRPC. + + Creates and removes ad group ad labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupAdLabelsRequest], + Awaitable[~.MutateAdGroupAdLabelsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_ad_labels" not in self._stubs: + self._stubs["mutate_ad_group_ad_labels"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupAdLabelService/MutateAdGroupAdLabels", + request_serializer=ad_group_ad_label_service.MutateAdGroupAdLabelsRequest.serialize, + response_deserializer=ad_group_ad_label_service.MutateAdGroupAdLabelsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_ad_labels"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_group_ad_labels: self._wrap_method( + self.mutate_ad_group_ad_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdGroupAdLabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_service/__init__.py b/google/ads/googleads/v23/services/services/ad_group_ad_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_ad_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_ad_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_ad_service/async_client.py b/google/ads/googleads/v23/services/services/ad_group_ad_service/async_client.py new file mode 100644 index 000000000..7853f3ddb --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_ad_service/async_client.py @@ -0,0 +1,554 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_ad_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupAdServiceTransport, DEFAULT_CLIENT_INFO +from .client import AdGroupAdServiceClient + +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 AdGroupAdServiceAsyncClient: + """Service to manage ads in an ad group.""" + + _client: AdGroupAdServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdGroupAdServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AdGroupAdServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AdGroupAdServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AdGroupAdServiceClient._DEFAULT_UNIVERSE + + ad_path = staticmethod(AdGroupAdServiceClient.ad_path) + parse_ad_path = staticmethod(AdGroupAdServiceClient.parse_ad_path) + ad_group_path = staticmethod(AdGroupAdServiceClient.ad_group_path) + parse_ad_group_path = staticmethod( + AdGroupAdServiceClient.parse_ad_group_path + ) + ad_group_ad_path = staticmethod(AdGroupAdServiceClient.ad_group_ad_path) + parse_ad_group_ad_path = staticmethod( + AdGroupAdServiceClient.parse_ad_group_ad_path + ) + ad_group_ad_label_path = staticmethod( + AdGroupAdServiceClient.ad_group_ad_label_path + ) + parse_ad_group_ad_label_path = staticmethod( + AdGroupAdServiceClient.parse_ad_group_ad_label_path + ) + asset_path = staticmethod(AdGroupAdServiceClient.asset_path) + parse_asset_path = staticmethod(AdGroupAdServiceClient.parse_asset_path) + common_billing_account_path = staticmethod( + AdGroupAdServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdGroupAdServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(AdGroupAdServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + AdGroupAdServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdGroupAdServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdGroupAdServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AdGroupAdServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AdGroupAdServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdGroupAdServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdGroupAdServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdServiceAsyncClient: The constructed client. + """ + return AdGroupAdServiceClient.from_service_account_info.__func__(AdGroupAdServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdServiceAsyncClient: The constructed client. + """ + return AdGroupAdServiceClient.from_service_account_file.__func__(AdGroupAdServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdGroupAdServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdGroupAdServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAdServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdGroupAdServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupAdServiceTransport, + Callable[..., AdGroupAdServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group ad service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupAdServiceTransport,Callable[..., AdGroupAdServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupAdServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdGroupAdServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdGroupAdServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupAdService", + "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.ads.googleads.v23.services.AdGroupAdService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_group_ads( + self, + request: Optional[ + Union[ad_group_ad_service.MutateAdGroupAdsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_ad_service.AdGroupAdOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_ad_service.MutateAdGroupAdsResponse: + r"""Creates, updates, or removes ads. Operation statuses are + returned. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdSharingError <>`__ `AdxError <>`__ + `AssetError <>`__ `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `ContextError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyValidationParameterError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdGroupAdsRequest, dict]]): + The request object. Request message for + [AdGroupAdService.MutateAdGroupAds][google.ads.googleads.v23.services.AdGroupAdService.MutateAdGroupAds]. + customer_id (:class:`str`): + Required. The ID of the customer + whose ads are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdGroupAdOperation]`): + Required. The list of operations to + perform on individual ads. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupAdsResponse: + Response message for an ad group ad + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, ad_group_ad_service.MutateAdGroupAdsRequest): + request = ad_group_ad_service.MutateAdGroupAdsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_group_ads + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def remove_automatically_created_assets( + self, + request: Optional[ + Union[ + ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest, + dict, + ] + ] = None, + *, + ad_group_ad: Optional[str] = None, + assets_with_field_type: Optional[ + MutableSequence[ad_group_ad_service.AssetsWithFieldType] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Remove automatically created assets from an ad. + + List of thrown errors: `AdError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ + `AutomaticallyCreatedAssetRemovalError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.RemoveAutomaticallyCreatedAssetsRequest, dict]]): + The request object. Request message for + [AdGroupAdService.RemoveAutomaticallyCreatedAssets][google.ads.googleads.v23.services.AdGroupAdService.RemoveAutomaticallyCreatedAssets]. + ad_group_ad (:class:`str`): + Required. The resource name of the + AdGroupAd from which to remove + automatically created assets. + + This corresponds to the ``ad_group_ad`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + assets_with_field_type (:class:`MutableSequence[google.ads.googleads.v23.services.types.AssetsWithFieldType]`): + Required. List of assets with field + type to be removed from the AdGroupAd. + + This corresponds to the ``assets_with_field_type`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 + # gotten any keyword arguments that map to the request. + flattened_params = [ad_group_ad, assets_with_field_type] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest + ): + request = ( + ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if ad_group_ad is not None: + request.ad_group_ad = ad_group_ad + if assets_with_field_type: + request.assets_with_field_type.extend(assets_with_field_type) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.remove_automatically_created_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("ad_group_ad", request.ad_group_ad),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def __aenter__(self) -> "AdGroupAdServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdGroupAdServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_group_ad_service/client.py b/google/ads/googleads/v23/services/services/ad_group_ad_service/client.py new file mode 100644 index 000000000..9f61b9ef9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_ad_service/client.py @@ -0,0 +1,1093 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ad_group_ad_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupAdServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdGroupAdServiceGrpcTransport +from .transports.grpc_asyncio import AdGroupAdServiceGrpcAsyncIOTransport + + +class AdGroupAdServiceClientMeta(type): + """Metaclass for the AdGroupAdService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupAdServiceTransport]] + _transport_registry["grpc"] = AdGroupAdServiceGrpcTransport + _transport_registry["grpc_asyncio"] = AdGroupAdServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdGroupAdServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupAdServiceClient(metaclass=AdGroupAdServiceClientMeta): + """Service to manage ads in an ad group.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAdServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupAdServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAdServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_path( + customer_id: str, + ad_id: str, + ) -> str: + """Returns a fully-qualified ad string.""" + return "customers/{customer_id}/ads/{ad_id}".format( + customer_id=customer_id, + ad_id=ad_id, + ) + + @staticmethod + def parse_ad_path(path: str) -> Dict[str, str]: + """Parses a ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ads/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_path( + customer_id: str, + ad_group_id: str, + ) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad string.""" + return ( + "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + ) + ) + + @staticmethod + def parse_ad_group_ad_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_label_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_label string.""" + return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_path( + customer_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AdGroupAdServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AdGroupAdServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AdGroupAdServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdGroupAdServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AdGroupAdServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdGroupAdServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupAdServiceTransport, + Callable[..., AdGroupAdServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group ad service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupAdServiceTransport,Callable[..., AdGroupAdServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupAdServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdGroupAdServiceClient._read_environment_variables() + self._client_cert_source = ( + AdGroupAdServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = AdGroupAdServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AdGroupAdServiceTransport) + if transport_provided: + # transport is a AdGroupAdServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AdGroupAdServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdGroupAdServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdGroupAdServiceTransport], + Callable[..., AdGroupAdServiceTransport], + ] = ( + AdGroupAdServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AdGroupAdServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdGroupAdServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupAdService", + "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.ads.googleads.v23.services.AdGroupAdService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_group_ads( + self, + request: Optional[ + Union[ad_group_ad_service.MutateAdGroupAdsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_ad_service.AdGroupAdOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_ad_service.MutateAdGroupAdsResponse: + r"""Creates, updates, or removes ads. Operation statuses are + returned. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdSharingError <>`__ `AdxError <>`__ + `AssetError <>`__ `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `ContextError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyValidationParameterError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdGroupAdsRequest, dict]): + The request object. Request message for + [AdGroupAdService.MutateAdGroupAds][google.ads.googleads.v23.services.AdGroupAdService.MutateAdGroupAds]. + customer_id (str): + Required. The ID of the customer + whose ads are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupAdOperation]): + Required. The list of operations to + perform on individual ads. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupAdsResponse: + Response message for an ad group ad + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, ad_group_ad_service.MutateAdGroupAdsRequest): + request = ad_group_ad_service.MutateAdGroupAdsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_ads + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def remove_automatically_created_assets( + self, + request: Optional[ + Union[ + ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest, + dict, + ] + ] = None, + *, + ad_group_ad: Optional[str] = None, + assets_with_field_type: Optional[ + MutableSequence[ad_group_ad_service.AssetsWithFieldType] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Remove automatically created assets from an ad. + + List of thrown errors: `AdError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ + `AutomaticallyCreatedAssetRemovalError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.RemoveAutomaticallyCreatedAssetsRequest, dict]): + The request object. Request message for + [AdGroupAdService.RemoveAutomaticallyCreatedAssets][google.ads.googleads.v23.services.AdGroupAdService.RemoveAutomaticallyCreatedAssets]. + ad_group_ad (str): + Required. The resource name of the + AdGroupAd from which to remove + automatically created assets. + + This corresponds to the ``ad_group_ad`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + assets_with_field_type (MutableSequence[google.ads.googleads.v23.services.types.AssetsWithFieldType]): + Required. List of assets with field + type to be removed from the AdGroupAd. + + This corresponds to the ``assets_with_field_type`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 + # gotten any keyword arguments that map to the request. + flattened_params = [ad_group_ad, assets_with_field_type] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest + ): + request = ( + ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if ad_group_ad is not None: + request.ad_group_ad = ad_group_ad + if assets_with_field_type is not None: + request.assets_with_field_type = assets_with_field_type + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.remove_automatically_created_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("ad_group_ad", request.ad_group_ad),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def __enter__(self) -> "AdGroupAdServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdGroupAdServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_group_ad_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_ad_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_group_ad_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_group_ad_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_group_ad_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_ad_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_ad_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_ad_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_group_ad_service/transports/base.py new file mode 100644 index 000000000..9c0a25498 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_ad_service/transports/base.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ad_group_ad_service +from google.protobuf import empty_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdGroupAdServiceTransport(abc.ABC): + """Abstract transport class for AdGroupAdService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_ads: gapic_v1.method.wrap_method( + self.mutate_ad_group_ads, + default_timeout=None, + client_info=client_info, + ), + self.remove_automatically_created_assets: gapic_v1.method.wrap_method( + self.remove_automatically_created_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_ads( + self, + ) -> Callable[ + [ad_group_ad_service.MutateAdGroupAdsRequest], + Union[ + ad_group_ad_service.MutateAdGroupAdsResponse, + Awaitable[ad_group_ad_service.MutateAdGroupAdsResponse], + ], + ]: + raise NotImplementedError() + + @property + def remove_automatically_created_assets( + self, + ) -> Callable[ + [ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdGroupAdServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_ad_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_group_ad_service/transports/grpc.py new file mode 100644 index 000000000..f22b39590 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_ad_service/transports/grpc.py @@ -0,0 +1,443 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ad_group_ad_service +from google.protobuf import empty_pb2 # type: ignore +from .base import AdGroupAdServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdGroupAdService", + "rpcName": str(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.ads.googleads.v23.services.AdGroupAdService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupAdServiceGrpcTransport(AdGroupAdServiceTransport): + """gRPC backend transport for AdGroupAdService. + + Service to manage ads in an ad group. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_group_ads( + self, + ) -> Callable[ + [ad_group_ad_service.MutateAdGroupAdsRequest], + ad_group_ad_service.MutateAdGroupAdsResponse, + ]: + r"""Return a callable for the mutate ad group ads method over gRPC. + + Creates, updates, or removes ads. Operation statuses are + returned. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdSharingError <>`__ `AdxError <>`__ + `AssetError <>`__ `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `ContextError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyValidationParameterError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdGroupAdsRequest], + ~.MutateAdGroupAdsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_ads" not in self._stubs: + self._stubs["mutate_ad_group_ads"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupAdService/MutateAdGroupAds", + request_serializer=ad_group_ad_service.MutateAdGroupAdsRequest.serialize, + response_deserializer=ad_group_ad_service.MutateAdGroupAdsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_ads"] + + @property + def remove_automatically_created_assets( + self, + ) -> Callable[ + [ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest], + empty_pb2.Empty, + ]: + r"""Return a callable for the remove automatically created + assets method over gRPC. + + Remove automatically created assets from an ad. + + List of thrown errors: `AdError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ + `AutomaticallyCreatedAssetRemovalError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.RemoveAutomaticallyCreatedAssetsRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "remove_automatically_created_assets" not in self._stubs: + self._stubs["remove_automatically_created_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupAdService/RemoveAutomaticallyCreatedAssets", + request_serializer=ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + ) + return self._stubs["remove_automatically_created_assets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdGroupAdServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_ad_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_group_ad_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..7b81409ec --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_ad_service/transports/grpc_asyncio.py @@ -0,0 +1,469 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_ad_service +from google.protobuf import empty_pb2 # type: ignore +from .base import AdGroupAdServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdGroupAdService", + "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.ads.googleads.v23.services.AdGroupAdService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupAdServiceGrpcAsyncIOTransport(AdGroupAdServiceTransport): + """gRPC AsyncIO backend transport for AdGroupAdService. + + Service to manage ads in an ad group. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_group_ads( + self, + ) -> Callable[ + [ad_group_ad_service.MutateAdGroupAdsRequest], + Awaitable[ad_group_ad_service.MutateAdGroupAdsResponse], + ]: + r"""Return a callable for the mutate ad group ads method over gRPC. + + Creates, updates, or removes ads. Operation statuses are + returned. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdSharingError <>`__ `AdxError <>`__ + `AssetError <>`__ `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `ContextError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyValidationParameterError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdGroupAdsRequest], + Awaitable[~.MutateAdGroupAdsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_ads" not in self._stubs: + self._stubs["mutate_ad_group_ads"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupAdService/MutateAdGroupAds", + request_serializer=ad_group_ad_service.MutateAdGroupAdsRequest.serialize, + response_deserializer=ad_group_ad_service.MutateAdGroupAdsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_ads"] + + @property + def remove_automatically_created_assets( + self, + ) -> Callable[ + [ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest], + Awaitable[empty_pb2.Empty], + ]: + r"""Return a callable for the remove automatically created + assets method over gRPC. + + Remove automatically created assets from an ad. + + List of thrown errors: `AdError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ + `AutomaticallyCreatedAssetRemovalError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.RemoveAutomaticallyCreatedAssetsRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "remove_automatically_created_assets" not in self._stubs: + self._stubs["remove_automatically_created_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupAdService/RemoveAutomaticallyCreatedAssets", + request_serializer=ad_group_ad_service.RemoveAutomaticallyCreatedAssetsRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + ) + return self._stubs["remove_automatically_created_assets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_group_ads: self._wrap_method( + self.mutate_ad_group_ads, + default_timeout=None, + client_info=client_info, + ), + self.remove_automatically_created_assets: self._wrap_method( + self.remove_automatically_created_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdGroupAdServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_service/__init__.py b/google/ads/googleads/v23/services/services/ad_group_asset_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_asset_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_asset_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_asset_service/async_client.py b/google/ads/googleads/v23/services/services/ad_group_asset_service/async_client.py new file mode 100644 index 000000000..a6ac46ffc --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_asset_service/async_client.py @@ -0,0 +1,431 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupAssetServiceTransport, DEFAULT_CLIENT_INFO +from .client import AdGroupAssetServiceClient + +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 AdGroupAssetServiceAsyncClient: + """Service to manage ad group assets.""" + + _client: AdGroupAssetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdGroupAssetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AdGroupAssetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AdGroupAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AdGroupAssetServiceClient._DEFAULT_UNIVERSE + + ad_group_path = staticmethod(AdGroupAssetServiceClient.ad_group_path) + parse_ad_group_path = staticmethod( + AdGroupAssetServiceClient.parse_ad_group_path + ) + ad_group_asset_path = staticmethod( + AdGroupAssetServiceClient.ad_group_asset_path + ) + parse_ad_group_asset_path = staticmethod( + AdGroupAssetServiceClient.parse_ad_group_asset_path + ) + asset_path = staticmethod(AdGroupAssetServiceClient.asset_path) + parse_asset_path = staticmethod(AdGroupAssetServiceClient.parse_asset_path) + common_billing_account_path = staticmethod( + AdGroupAssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdGroupAssetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AdGroupAssetServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AdGroupAssetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdGroupAssetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdGroupAssetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AdGroupAssetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AdGroupAssetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdGroupAssetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdGroupAssetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetServiceAsyncClient: The constructed client. + """ + return AdGroupAssetServiceClient.from_service_account_info.__func__(AdGroupAssetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetServiceAsyncClient: The constructed client. + """ + return AdGroupAssetServiceClient.from_service_account_file.__func__(AdGroupAssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdGroupAssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdGroupAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdGroupAssetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupAssetServiceTransport, + Callable[..., AdGroupAssetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group asset service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupAssetServiceTransport,Callable[..., AdGroupAssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupAssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdGroupAssetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdGroupAssetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupAssetService", + "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.ads.googleads.v23.services.AdGroupAssetService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_group_assets( + self, + request: Optional[ + Union[ad_group_asset_service.MutateAdGroupAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_asset_service.AdGroupAssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_asset_service.MutateAdGroupAssetsResponse: + r"""Creates, updates, or removes ad group assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdGroupAssetsRequest, dict]]): + The request object. Request message for + [AdGroupAssetService.MutateAdGroupAssets][google.ads.googleads.v23.services.AdGroupAssetService.MutateAdGroupAssets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose ad group assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdGroupAssetOperation]`): + Required. The list of operations to + perform on individual ad group assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupAssetsResponse: + Response message for an ad group + asset mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_asset_service.MutateAdGroupAssetsRequest + ): + request = ad_group_asset_service.MutateAdGroupAssetsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_group_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AdGroupAssetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdGroupAssetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_group_asset_service/client.py b/google/ads/googleads/v23/services/services/ad_group_asset_service/client.py new file mode 100644 index 000000000..8aacd4842 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_asset_service/client.py @@ -0,0 +1,936 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ad_group_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupAssetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdGroupAssetServiceGrpcTransport +from .transports.grpc_asyncio import AdGroupAssetServiceGrpcAsyncIOTransport + + +class AdGroupAssetServiceClientMeta(type): + """Metaclass for the AdGroupAssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupAssetServiceTransport]] + _transport_registry["grpc"] = AdGroupAssetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AdGroupAssetServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdGroupAssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupAssetServiceClient(metaclass=AdGroupAssetServiceClientMeta): + """Service to manage ad group assets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_path( + customer_id: str, + ad_group_id: str, + ) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_asset_path( + customer_id: str, + ad_group_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified ad_group_asset string.""" + return "customers/{customer_id}/adGroupAssets/{ad_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_ad_group_asset_path(path: str) -> Dict[str, str]: + """Parses a ad_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_path( + customer_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AdGroupAssetServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AdGroupAssetServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AdGroupAssetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdGroupAssetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AdGroupAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdGroupAssetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupAssetServiceTransport, + Callable[..., AdGroupAssetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupAssetServiceTransport,Callable[..., AdGroupAssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupAssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdGroupAssetServiceClient._read_environment_variables() + self._client_cert_source = ( + AdGroupAssetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = AdGroupAssetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AdGroupAssetServiceTransport) + if transport_provided: + # transport is a AdGroupAssetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AdGroupAssetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdGroupAssetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdGroupAssetServiceTransport], + Callable[..., AdGroupAssetServiceTransport], + ] = ( + AdGroupAssetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AdGroupAssetServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdGroupAssetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupAssetService", + "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.ads.googleads.v23.services.AdGroupAssetService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_group_assets( + self, + request: Optional[ + Union[ad_group_asset_service.MutateAdGroupAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_asset_service.AdGroupAssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_asset_service.MutateAdGroupAssetsResponse: + r"""Creates, updates, or removes ad group assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdGroupAssetsRequest, dict]): + The request object. Request message for + [AdGroupAssetService.MutateAdGroupAssets][google.ads.googleads.v23.services.AdGroupAssetService.MutateAdGroupAssets]. + customer_id (str): + Required. The ID of the customer + whose ad group assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupAssetOperation]): + Required. The list of operations to + perform on individual ad group assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupAssetsResponse: + Response message for an ad group + asset mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_asset_service.MutateAdGroupAssetsRequest + ): + request = ad_group_asset_service.MutateAdGroupAssetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdGroupAssetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdGroupAssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_group_asset_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_asset_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_group_asset_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_group_asset_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_asset_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_asset_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_asset_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_group_asset_service/transports/base.py new file mode 100644 index 000000000..30493702c --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_asset_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ad_group_asset_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdGroupAssetServiceTransport(abc.ABC): + """Abstract transport class for AdGroupAssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_assets: gapic_v1.method.wrap_method( + self.mutate_ad_group_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_assets( + self, + ) -> Callable[ + [ad_group_asset_service.MutateAdGroupAssetsRequest], + Union[ + ad_group_asset_service.MutateAdGroupAssetsResponse, + Awaitable[ad_group_asset_service.MutateAdGroupAssetsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdGroupAssetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_asset_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_group_asset_service/transports/grpc.py new file mode 100644 index 000000000..296850d76 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_asset_service/transports/grpc.py @@ -0,0 +1,390 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ad_group_asset_service +from .base import AdGroupAssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdGroupAssetService", + "rpcName": str(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.ads.googleads.v23.services.AdGroupAssetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupAssetServiceGrpcTransport(AdGroupAssetServiceTransport): + """gRPC backend transport for AdGroupAssetService. + + Service to manage ad group assets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_group_assets( + self, + ) -> Callable[ + [ad_group_asset_service.MutateAdGroupAssetsRequest], + ad_group_asset_service.MutateAdGroupAssetsResponse, + ]: + r"""Return a callable for the mutate ad group assets method over gRPC. + + Creates, updates, or removes ad group assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupAssetsRequest], + ~.MutateAdGroupAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_assets" not in self._stubs: + self._stubs["mutate_ad_group_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupAssetService/MutateAdGroupAssets", + request_serializer=ad_group_asset_service.MutateAdGroupAssetsRequest.serialize, + response_deserializer=ad_group_asset_service.MutateAdGroupAssetsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_assets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdGroupAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_group_asset_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..c5fd46db7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_asset_service/transports/grpc_asyncio.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_asset_service +from .base import AdGroupAssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdGroupAssetService", + "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.ads.googleads.v23.services.AdGroupAssetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupAssetServiceGrpcAsyncIOTransport(AdGroupAssetServiceTransport): + """gRPC AsyncIO backend transport for AdGroupAssetService. + + Service to manage ad group assets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_group_assets( + self, + ) -> Callable[ + [ad_group_asset_service.MutateAdGroupAssetsRequest], + Awaitable[ad_group_asset_service.MutateAdGroupAssetsResponse], + ]: + r"""Return a callable for the mutate ad group assets method over gRPC. + + Creates, updates, or removes ad group assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupAssetsRequest], + Awaitable[~.MutateAdGroupAssetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_assets" not in self._stubs: + self._stubs["mutate_ad_group_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupAssetService/MutateAdGroupAssets", + request_serializer=ad_group_asset_service.MutateAdGroupAssetsRequest.serialize, + response_deserializer=ad_group_asset_service.MutateAdGroupAssetsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_assets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_group_assets: self._wrap_method( + self.mutate_ad_group_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdGroupAssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/__init__.py b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_asset_set_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_asset_set_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_asset_set_service/async_client.py b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/async_client.py new file mode 100644 index 000000000..10fd662e2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/async_client.py @@ -0,0 +1,435 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupAssetSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AdGroupAssetSetServiceClient + +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 AdGroupAssetSetServiceAsyncClient: + """Service to manage ad group asset set""" + + _client: AdGroupAssetSetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdGroupAssetSetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AdGroupAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AdGroupAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AdGroupAssetSetServiceClient._DEFAULT_UNIVERSE + + ad_group_path = staticmethod(AdGroupAssetSetServiceClient.ad_group_path) + parse_ad_group_path = staticmethod( + AdGroupAssetSetServiceClient.parse_ad_group_path + ) + ad_group_asset_set_path = staticmethod( + AdGroupAssetSetServiceClient.ad_group_asset_set_path + ) + parse_ad_group_asset_set_path = staticmethod( + AdGroupAssetSetServiceClient.parse_ad_group_asset_set_path + ) + asset_set_path = staticmethod(AdGroupAssetSetServiceClient.asset_set_path) + parse_asset_set_path = staticmethod( + AdGroupAssetSetServiceClient.parse_asset_set_path + ) + common_billing_account_path = staticmethod( + AdGroupAssetSetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdGroupAssetSetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AdGroupAssetSetServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AdGroupAssetSetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdGroupAssetSetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdGroupAssetSetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AdGroupAssetSetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AdGroupAssetSetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdGroupAssetSetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdGroupAssetSetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetSetServiceAsyncClient: The constructed client. + """ + return AdGroupAssetSetServiceClient.from_service_account_info.__func__(AdGroupAssetSetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetSetServiceAsyncClient: The constructed client. + """ + return AdGroupAssetSetServiceClient.from_service_account_file.__func__(AdGroupAssetSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdGroupAssetSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdGroupAssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAssetSetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdGroupAssetSetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupAssetSetServiceTransport, + Callable[..., AdGroupAssetSetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group asset set service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupAssetSetServiceTransport,Callable[..., AdGroupAssetSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupAssetSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdGroupAssetSetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdGroupAssetSetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupAssetSetService", + "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.ads.googleads.v23.services.AdGroupAssetSetService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_group_asset_sets( + self, + request: Optional[ + Union[ + ad_group_asset_set_service.MutateAdGroupAssetSetsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_asset_set_service.AdGroupAssetSetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_asset_set_service.MutateAdGroupAssetSetsResponse: + r"""Creates, or removes ad group asset sets. Operation + statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdGroupAssetSetsRequest, dict]]): + The request object. Request message for + [AdGroupAssetSetService.MutateAdGroupAssetSets][google.ads.googleads.v23.services.AdGroupAssetSetService.MutateAdGroupAssetSets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose ad group asset sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdGroupAssetSetOperation]`): + Required. The list of operations to + perform on individual ad group asset + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupAssetSetsResponse: + Response message for an ad group + asset set mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_asset_set_service.MutateAdGroupAssetSetsRequest + ): + request = ad_group_asset_set_service.MutateAdGroupAssetSetsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_group_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AdGroupAssetSetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdGroupAssetSetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_group_asset_set_service/client.py b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/client.py new file mode 100644 index 000000000..5976f253e --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/client.py @@ -0,0 +1,945 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ad_group_asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupAssetSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupAssetSetServiceGrpcTransport +from .transports.grpc_asyncio import AdGroupAssetSetServiceGrpcAsyncIOTransport + + +class AdGroupAssetSetServiceClientMeta(type): + """Metaclass for the AdGroupAssetSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupAssetSetServiceTransport]] + _transport_registry["grpc"] = AdGroupAssetSetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AdGroupAssetSetServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdGroupAssetSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupAssetSetServiceClient(metaclass=AdGroupAssetSetServiceClientMeta): + """Service to manage ad group asset set""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupAssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupAssetSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_path( + customer_id: str, + ad_group_id: str, + ) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_asset_set_path( + customer_id: str, + ad_group_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified ad_group_asset_set string.""" + return "customers/{customer_id}/adGroupAssetSets/{ad_group_id}~{asset_set_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_ad_group_asset_set_path(path: str) -> Dict[str, str]: + """Parses a ad_group_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAssetSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_path( + customer_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AdGroupAssetSetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AdGroupAssetSetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AdGroupAssetSetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdGroupAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AdGroupAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdGroupAssetSetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupAssetSetServiceTransport, + Callable[..., AdGroupAssetSetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group asset set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupAssetSetServiceTransport,Callable[..., AdGroupAssetSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupAssetSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdGroupAssetSetServiceClient._read_environment_variables() + self._client_cert_source = ( + AdGroupAssetSetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AdGroupAssetSetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AdGroupAssetSetServiceTransport + ) + if transport_provided: + # transport is a AdGroupAssetSetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AdGroupAssetSetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdGroupAssetSetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdGroupAssetSetServiceTransport], + Callable[..., AdGroupAssetSetServiceTransport], + ] = ( + AdGroupAssetSetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AdGroupAssetSetServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdGroupAssetSetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupAssetSetService", + "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.ads.googleads.v23.services.AdGroupAssetSetService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_group_asset_sets( + self, + request: Optional[ + Union[ + ad_group_asset_set_service.MutateAdGroupAssetSetsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_asset_set_service.AdGroupAssetSetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_asset_set_service.MutateAdGroupAssetSetsResponse: + r"""Creates, or removes ad group asset sets. Operation + statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdGroupAssetSetsRequest, dict]): + The request object. Request message for + [AdGroupAssetSetService.MutateAdGroupAssetSets][google.ads.googleads.v23.services.AdGroupAssetSetService.MutateAdGroupAssetSets]. + customer_id (str): + Required. The ID of the customer + whose ad group asset sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupAssetSetOperation]): + Required. The list of operations to + perform on individual ad group asset + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupAssetSetsResponse: + Response message for an ad group + asset set mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_asset_set_service.MutateAdGroupAssetSetsRequest + ): + request = ad_group_asset_set_service.MutateAdGroupAssetSetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdGroupAssetSetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdGroupAssetSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_asset_set_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/base.py new file mode 100644 index 000000000..1363b026f --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ad_group_asset_set_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdGroupAssetSetServiceTransport(abc.ABC): + """Abstract transport class for AdGroupAssetSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_asset_sets: gapic_v1.method.wrap_method( + self.mutate_ad_group_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_asset_sets( + self, + ) -> Callable[ + [ad_group_asset_set_service.MutateAdGroupAssetSetsRequest], + Union[ + ad_group_asset_set_service.MutateAdGroupAssetSetsResponse, + Awaitable[ + ad_group_asset_set_service.MutateAdGroupAssetSetsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdGroupAssetSetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/grpc.py new file mode 100644 index 000000000..9ddf02818 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/grpc.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ad_group_asset_set_service +from .base import AdGroupAssetSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdGroupAssetSetService", + "rpcName": str(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.ads.googleads.v23.services.AdGroupAssetSetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupAssetSetServiceGrpcTransport(AdGroupAssetSetServiceTransport): + """gRPC backend transport for AdGroupAssetSetService. + + Service to manage ad group asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_group_asset_sets( + self, + ) -> Callable[ + [ad_group_asset_set_service.MutateAdGroupAssetSetsRequest], + ad_group_asset_set_service.MutateAdGroupAssetSetsResponse, + ]: + r"""Return a callable for the mutate ad group asset sets method over gRPC. + + Creates, or removes ad group asset sets. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAdGroupAssetSetsRequest], + ~.MutateAdGroupAssetSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_asset_sets" not in self._stubs: + self._stubs["mutate_ad_group_asset_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupAssetSetService/MutateAdGroupAssetSets", + request_serializer=ad_group_asset_set_service.MutateAdGroupAssetSetsRequest.serialize, + response_deserializer=ad_group_asset_set_service.MutateAdGroupAssetSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_asset_sets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdGroupAssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..66c61ca38 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_asset_set_service/transports/grpc_asyncio.py @@ -0,0 +1,407 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_asset_set_service +from .base import AdGroupAssetSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdGroupAssetSetService", + "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.ads.googleads.v23.services.AdGroupAssetSetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupAssetSetServiceGrpcAsyncIOTransport( + AdGroupAssetSetServiceTransport +): + """gRPC AsyncIO backend transport for AdGroupAssetSetService. + + Service to manage ad group asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_group_asset_sets( + self, + ) -> Callable[ + [ad_group_asset_set_service.MutateAdGroupAssetSetsRequest], + Awaitable[ad_group_asset_set_service.MutateAdGroupAssetSetsResponse], + ]: + r"""Return a callable for the mutate ad group asset sets method over gRPC. + + Creates, or removes ad group asset sets. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAdGroupAssetSetsRequest], + Awaitable[~.MutateAdGroupAssetSetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_asset_sets" not in self._stubs: + self._stubs["mutate_ad_group_asset_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupAssetSetService/MutateAdGroupAssetSets", + request_serializer=ad_group_asset_set_service.MutateAdGroupAssetSetsRequest.serialize, + response_deserializer=ad_group_asset_set_service.MutateAdGroupAssetSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_asset_sets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_group_asset_sets: self._wrap_method( + self.mutate_ad_group_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdGroupAssetSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/__init__.py b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/async_client.py b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/async_client.py new file mode 100644 index 000000000..7e225b987 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/async_client.py @@ -0,0 +1,451 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + ad_group_bid_modifier_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupBidModifierServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AdGroupBidModifierServiceClient + +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 AdGroupBidModifierServiceAsyncClient: + """Service to manage ad group bid modifiers.""" + + _client: AdGroupBidModifierServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdGroupBidModifierServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + AdGroupBidModifierServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + AdGroupBidModifierServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AdGroupBidModifierServiceClient._DEFAULT_UNIVERSE + + ad_group_path = staticmethod(AdGroupBidModifierServiceClient.ad_group_path) + parse_ad_group_path = staticmethod( + AdGroupBidModifierServiceClient.parse_ad_group_path + ) + ad_group_bid_modifier_path = staticmethod( + AdGroupBidModifierServiceClient.ad_group_bid_modifier_path + ) + parse_ad_group_bid_modifier_path = staticmethod( + AdGroupBidModifierServiceClient.parse_ad_group_bid_modifier_path + ) + common_billing_account_path = staticmethod( + AdGroupBidModifierServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdGroupBidModifierServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AdGroupBidModifierServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AdGroupBidModifierServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdGroupBidModifierServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdGroupBidModifierServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AdGroupBidModifierServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AdGroupBidModifierServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdGroupBidModifierServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdGroupBidModifierServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupBidModifierServiceAsyncClient: The constructed client. + """ + return AdGroupBidModifierServiceClient.from_service_account_info.__func__(AdGroupBidModifierServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupBidModifierServiceAsyncClient: The constructed client. + """ + return AdGroupBidModifierServiceClient.from_service_account_file.__func__(AdGroupBidModifierServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdGroupBidModifierServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdGroupBidModifierServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupBidModifierServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdGroupBidModifierServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupBidModifierServiceTransport, + Callable[..., AdGroupBidModifierServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group bid modifier service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupBidModifierServiceTransport,Callable[..., AdGroupBidModifierServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupBidModifierServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdGroupBidModifierServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdGroupBidModifierServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupBidModifierService", + "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.ads.googleads.v23.services.AdGroupBidModifierService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_group_bid_modifiers( + self, + request: Optional[ + Union[ + ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + ad_group_bid_modifier_service.AdGroupBidModifierOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse: + r"""Creates, updates, or removes ad group bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AdGroupBidModifierError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdGroupBidModifiersRequest, dict]]): + The request object. Request message for + [AdGroupBidModifierService.MutateAdGroupBidModifiers][google.ads.googleads.v23.services.AdGroupBidModifierService.MutateAdGroupBidModifiers]. + customer_id (:class:`str`): + Required. ID of the customer whose ad + group bid modifiers are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdGroupBidModifierOperation]`): + Required. The list of operations to + perform on individual ad group bid + modifiers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupBidModifiersResponse: + Response message for ad group bid + modifiers mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest, + ): + request = ( + ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_group_bid_modifiers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AdGroupBidModifierServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdGroupBidModifierServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/client.py b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/client.py new file mode 100644 index 000000000..5e19e61f4 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/client.py @@ -0,0 +1,949 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + ad_group_bid_modifier_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupBidModifierServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupBidModifierServiceGrpcTransport +from .transports.grpc_asyncio import ( + AdGroupBidModifierServiceGrpcAsyncIOTransport, +) + + +class AdGroupBidModifierServiceClientMeta(type): + """Metaclass for the AdGroupBidModifierService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupBidModifierServiceTransport]] + _transport_registry["grpc"] = AdGroupBidModifierServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AdGroupBidModifierServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdGroupBidModifierServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupBidModifierServiceClient( + metaclass=AdGroupBidModifierServiceClientMeta +): + """Service to manage ad group bid modifiers.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupBidModifierServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupBidModifierServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupBidModifierServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupBidModifierServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_path( + customer_id: str, + ad_group_id: str, + ) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_bid_modifier_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_bid_modifier string.""" + return "customers/{customer_id}/adGroupBidModifiers/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a ad_group_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AdGroupBidModifierServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AdGroupBidModifierServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + AdGroupBidModifierServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdGroupBidModifierServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = AdGroupBidModifierServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdGroupBidModifierServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupBidModifierServiceTransport, + Callable[..., AdGroupBidModifierServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group bid modifier service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupBidModifierServiceTransport,Callable[..., AdGroupBidModifierServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupBidModifierServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdGroupBidModifierServiceClient._read_environment_variables() + self._client_cert_source = ( + AdGroupBidModifierServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AdGroupBidModifierServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AdGroupBidModifierServiceTransport + ) + if transport_provided: + # transport is a AdGroupBidModifierServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + AdGroupBidModifierServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdGroupBidModifierServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdGroupBidModifierServiceTransport], + Callable[..., AdGroupBidModifierServiceTransport], + ] = ( + AdGroupBidModifierServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AdGroupBidModifierServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdGroupBidModifierServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupBidModifierService", + "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.ads.googleads.v23.services.AdGroupBidModifierService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_group_bid_modifiers( + self, + request: Optional[ + Union[ + ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + ad_group_bid_modifier_service.AdGroupBidModifierOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse: + r"""Creates, updates, or removes ad group bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AdGroupBidModifierError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdGroupBidModifiersRequest, dict]): + The request object. Request message for + [AdGroupBidModifierService.MutateAdGroupBidModifiers][google.ads.googleads.v23.services.AdGroupBidModifierService.MutateAdGroupBidModifiers]. + customer_id (str): + Required. ID of the customer whose ad + group bid modifiers are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupBidModifierOperation]): + Required. The list of operations to + perform on individual ad group bid + modifiers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupBidModifiersResponse: + Response message for ad group bid + modifiers mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest, + ): + request = ( + ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_bid_modifiers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdGroupBidModifierServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdGroupBidModifierServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_bid_modifier_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/base.py new file mode 100644 index 000000000..efe88d021 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + ad_group_bid_modifier_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdGroupBidModifierServiceTransport(abc.ABC): + """Abstract transport class for AdGroupBidModifierService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_bid_modifiers: gapic_v1.method.wrap_method( + self.mutate_ad_group_bid_modifiers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_bid_modifiers( + self, + ) -> Callable[ + [ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest], + Union[ + ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse, + Awaitable[ + ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdGroupBidModifierServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/grpc.py new file mode 100644 index 000000000..d0bc86f67 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/grpc.py @@ -0,0 +1,399 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + ad_group_bid_modifier_service, +) +from .base import AdGroupBidModifierServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdGroupBidModifierService", + "rpcName": str(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.ads.googleads.v23.services.AdGroupBidModifierService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupBidModifierServiceGrpcTransport( + AdGroupBidModifierServiceTransport +): + """gRPC backend transport for AdGroupBidModifierService. + + Service to manage ad group bid modifiers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_group_bid_modifiers( + self, + ) -> Callable[ + [ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest], + ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse, + ]: + r"""Return a callable for the mutate ad group bid modifiers method over gRPC. + + Creates, updates, or removes ad group bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AdGroupBidModifierError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateAdGroupBidModifiersRequest], + ~.MutateAdGroupBidModifiersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_bid_modifiers" not in self._stubs: + self._stubs["mutate_ad_group_bid_modifiers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupBidModifierService/MutateAdGroupBidModifiers", + request_serializer=ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest.serialize, + response_deserializer=ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_bid_modifiers"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdGroupBidModifierServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..2e49a032f --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_bid_modifier_service/transports/grpc_asyncio.py @@ -0,0 +1,422 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + ad_group_bid_modifier_service, +) +from .base import AdGroupBidModifierServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdGroupBidModifierService", + "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.ads.googleads.v23.services.AdGroupBidModifierService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupBidModifierServiceGrpcAsyncIOTransport( + AdGroupBidModifierServiceTransport +): + """gRPC AsyncIO backend transport for AdGroupBidModifierService. + + Service to manage ad group bid modifiers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_group_bid_modifiers( + self, + ) -> Callable[ + [ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest], + Awaitable[ + ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse + ], + ]: + r"""Return a callable for the mutate ad group bid modifiers method over gRPC. + + Creates, updates, or removes ad group bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AdGroupBidModifierError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateAdGroupBidModifiersRequest], + Awaitable[~.MutateAdGroupBidModifiersResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_bid_modifiers" not in self._stubs: + self._stubs["mutate_ad_group_bid_modifiers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupBidModifierService/MutateAdGroupBidModifiers", + request_serializer=ad_group_bid_modifier_service.MutateAdGroupBidModifiersRequest.serialize, + response_deserializer=ad_group_bid_modifier_service.MutateAdGroupBidModifiersResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_bid_modifiers"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_group_bid_modifiers: self._wrap_method( + self.mutate_ad_group_bid_modifiers, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdGroupBidModifierServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/__init__.py b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/async_client.py b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/async_client.py new file mode 100644 index 000000000..156a374aa --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/async_client.py @@ -0,0 +1,455 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + ad_group_criterion_customizer_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCriterionCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AdGroupCriterionCustomizerServiceClient + +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 AdGroupCriterionCustomizerServiceAsyncClient: + """Service to manage ad group criterion customizer""" + + _client: AdGroupCriterionCustomizerServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdGroupCriterionCustomizerServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + AdGroupCriterionCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + AdGroupCriterionCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ( + AdGroupCriterionCustomizerServiceClient._DEFAULT_UNIVERSE + ) + + ad_group_criterion_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.ad_group_criterion_path + ) + parse_ad_group_criterion_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.parse_ad_group_criterion_path + ) + ad_group_criterion_customizer_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.ad_group_criterion_customizer_path + ) + parse_ad_group_criterion_customizer_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.parse_ad_group_criterion_customizer_path + ) + customizer_attribute_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.customizer_attribute_path + ) + parse_customizer_attribute_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.parse_customizer_attribute_path + ) + common_billing_account_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdGroupCriterionCustomizerServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionCustomizerServiceAsyncClient: The constructed client. + """ + return AdGroupCriterionCustomizerServiceClient.from_service_account_info.__func__(AdGroupCriterionCustomizerServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionCustomizerServiceAsyncClient: The constructed client. + """ + return AdGroupCriterionCustomizerServiceClient.from_service_account_file.__func__(AdGroupCriterionCustomizerServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdGroupCriterionCustomizerServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdGroupCriterionCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCriterionCustomizerServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + AdGroupCriterionCustomizerServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupCriterionCustomizerServiceTransport, + Callable[..., AdGroupCriterionCustomizerServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group criterion customizer service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupCriterionCustomizerServiceTransport,Callable[..., AdGroupCriterionCustomizerServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupCriterionCustomizerServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdGroupCriterionCustomizerServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdGroupCriterionCustomizerServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupCriterionCustomizerService", + "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.ads.googleads.v23.services.AdGroupCriterionCustomizerService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_group_criterion_customizers( + self, + request: Optional[ + Union[ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + ad_group_criterion_customizer_service.AdGroupCriterionCustomizerOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse + ): + r"""Creates, updates or removes ad group criterion + customizers. Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdGroupCriterionCustomizersRequest, dict]]): + The request object. Request message for + [AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers][google.ads.googleads.v23.services.AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers]. + customer_id (:class:`str`): + Required. The ID of the customer + whose ad group criterion customizers are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdGroupCriterionCustomizerOperation]`): + Required. The list of operations to + perform on individual ad group criterion + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupCriterionCustomizersResponse: + Response message for an ad group + criterion customizer mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest, + ): + request = ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_group_criterion_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__( + self, + ) -> "AdGroupCriterionCustomizerServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdGroupCriterionCustomizerServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/client.py b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/client.py new file mode 100644 index 000000000..df3a50bbe --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/client.py @@ -0,0 +1,972 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + ad_group_criterion_customizer_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCriterionCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupCriterionCustomizerServiceGrpcTransport +from .transports.grpc_asyncio import ( + AdGroupCriterionCustomizerServiceGrpcAsyncIOTransport, +) + + +class AdGroupCriterionCustomizerServiceClientMeta(type): + """Metaclass for the AdGroupCriterionCustomizerService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupCriterionCustomizerServiceTransport]] + _transport_registry["grpc"] = AdGroupCriterionCustomizerServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AdGroupCriterionCustomizerServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdGroupCriterionCustomizerServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupCriterionCustomizerServiceClient( + metaclass=AdGroupCriterionCustomizerServiceClientMeta +): + """Service to manage ad group criterion customizer""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupCriterionCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCriterionCustomizerServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_criterion_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_customizer_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_customizer string.""" + return "customers/{customer_id}/adGroupCriterionCustomizers/{ad_group_id}~{criterion_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_criterion_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionCustomizers/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AdGroupCriterionCustomizerServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AdGroupCriterionCustomizerServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + AdGroupCriterionCustomizerServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + AdGroupCriterionCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = AdGroupCriterionCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + AdGroupCriterionCustomizerServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupCriterionCustomizerServiceTransport, + Callable[..., AdGroupCriterionCustomizerServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group criterion customizer service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupCriterionCustomizerServiceTransport,Callable[..., AdGroupCriterionCustomizerServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupCriterionCustomizerServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ( + AdGroupCriterionCustomizerServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + AdGroupCriterionCustomizerServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AdGroupCriterionCustomizerServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AdGroupCriterionCustomizerServiceTransport + ) + if transport_provided: + # transport is a AdGroupCriterionCustomizerServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + AdGroupCriterionCustomizerServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdGroupCriterionCustomizerServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdGroupCriterionCustomizerServiceTransport], + Callable[..., AdGroupCriterionCustomizerServiceTransport], + ] = ( + AdGroupCriterionCustomizerServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AdGroupCriterionCustomizerServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdGroupCriterionCustomizerServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupCriterionCustomizerService", + "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.ads.googleads.v23.services.AdGroupCriterionCustomizerService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_group_criterion_customizers( + self, + request: Optional[ + Union[ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + ad_group_criterion_customizer_service.AdGroupCriterionCustomizerOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse + ): + r"""Creates, updates or removes ad group criterion + customizers. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdGroupCriterionCustomizersRequest, dict]): + The request object. Request message for + [AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers][google.ads.googleads.v23.services.AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers]. + customer_id (str): + Required. The ID of the customer + whose ad group criterion customizers are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupCriterionCustomizerOperation]): + Required. The list of operations to + perform on individual ad group criterion + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupCriterionCustomizersResponse: + Response message for an ad group + criterion customizer mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest, + ): + request = ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_criterion_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdGroupCriterionCustomizerServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdGroupCriterionCustomizerServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_criterion_customizer_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/base.py new file mode 100644 index 000000000..a5258cf02 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + ad_group_criterion_customizer_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdGroupCriterionCustomizerServiceTransport(abc.ABC): + """Abstract transport class for AdGroupCriterionCustomizerService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_criterion_customizers: gapic_v1.method.wrap_method( + self.mutate_ad_group_criterion_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_criterion_customizers( + self, + ) -> Callable[ + [ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest + ], + Union[ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse, + Awaitable[ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdGroupCriterionCustomizerServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/grpc.py new file mode 100644 index 000000000..2833fc035 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/grpc.py @@ -0,0 +1,394 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + ad_group_criterion_customizer_service, +) +from .base import ( + AdGroupCriterionCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdGroupCriterionCustomizerService", + "rpcName": str(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.ads.googleads.v23.services.AdGroupCriterionCustomizerService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupCriterionCustomizerServiceGrpcTransport( + AdGroupCriterionCustomizerServiceTransport +): + """gRPC backend transport for AdGroupCriterionCustomizerService. + + Service to manage ad group criterion customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_group_criterion_customizers( + self, + ) -> Callable[ + [ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest + ], + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse, + ]: + r"""Return a callable for the mutate ad group criterion + customizers method over gRPC. + + Creates, updates or removes ad group criterion + customizers. Operation statuses are returned. + + Returns: + Callable[[~.MutateAdGroupCriterionCustomizersRequest], + ~.MutateAdGroupCriterionCustomizersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_criterion_customizers" not in self._stubs: + self._stubs["mutate_ad_group_criterion_customizers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupCriterionCustomizerService/MutateAdGroupCriterionCustomizers", + request_serializer=ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest.serialize, + response_deserializer=ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_criterion_customizers"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdGroupCriterionCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..e80ea1b20 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_customizer_service/transports/grpc_asyncio.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + ad_group_criterion_customizer_service, +) +from .base import ( + AdGroupCriterionCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdGroupCriterionCustomizerService", + "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.ads.googleads.v23.services.AdGroupCriterionCustomizerService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupCriterionCustomizerServiceGrpcAsyncIOTransport( + AdGroupCriterionCustomizerServiceTransport +): + """gRPC AsyncIO backend transport for AdGroupCriterionCustomizerService. + + Service to manage ad group criterion customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_group_criterion_customizers( + self, + ) -> Callable[ + [ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest + ], + Awaitable[ + ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse + ], + ]: + r"""Return a callable for the mutate ad group criterion + customizers method over gRPC. + + Creates, updates or removes ad group criterion + customizers. Operation statuses are returned. + + Returns: + Callable[[~.MutateAdGroupCriterionCustomizersRequest], + Awaitable[~.MutateAdGroupCriterionCustomizersResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_criterion_customizers" not in self._stubs: + self._stubs["mutate_ad_group_criterion_customizers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupCriterionCustomizerService/MutateAdGroupCriterionCustomizers", + request_serializer=ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersRequest.serialize, + response_deserializer=ad_group_criterion_customizer_service.MutateAdGroupCriterionCustomizersResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_criterion_customizers"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_group_criterion_customizers: self._wrap_method( + self.mutate_ad_group_criterion_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdGroupCriterionCustomizerServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/__init__.py b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_criterion_label_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_criterion_label_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/async_client.py b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/async_client.py new file mode 100644 index 000000000..fb298e718 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/async_client.py @@ -0,0 +1,449 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + ad_group_criterion_label_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCriterionLabelServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AdGroupCriterionLabelServiceClient + +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 AdGroupCriterionLabelServiceAsyncClient: + """Service to manage labels on ad group criteria.""" + + _client: AdGroupCriterionLabelServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdGroupCriterionLabelServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + AdGroupCriterionLabelServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + AdGroupCriterionLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AdGroupCriterionLabelServiceClient._DEFAULT_UNIVERSE + + ad_group_criterion_path = staticmethod( + AdGroupCriterionLabelServiceClient.ad_group_criterion_path + ) + parse_ad_group_criterion_path = staticmethod( + AdGroupCriterionLabelServiceClient.parse_ad_group_criterion_path + ) + ad_group_criterion_label_path = staticmethod( + AdGroupCriterionLabelServiceClient.ad_group_criterion_label_path + ) + parse_ad_group_criterion_label_path = staticmethod( + AdGroupCriterionLabelServiceClient.parse_ad_group_criterion_label_path + ) + label_path = staticmethod(AdGroupCriterionLabelServiceClient.label_path) + parse_label_path = staticmethod( + AdGroupCriterionLabelServiceClient.parse_label_path + ) + common_billing_account_path = staticmethod( + AdGroupCriterionLabelServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdGroupCriterionLabelServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AdGroupCriterionLabelServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AdGroupCriterionLabelServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdGroupCriterionLabelServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdGroupCriterionLabelServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AdGroupCriterionLabelServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AdGroupCriterionLabelServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdGroupCriterionLabelServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdGroupCriterionLabelServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionLabelServiceAsyncClient: The constructed client. + """ + return AdGroupCriterionLabelServiceClient.from_service_account_info.__func__(AdGroupCriterionLabelServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionLabelServiceAsyncClient: The constructed client. + """ + return AdGroupCriterionLabelServiceClient.from_service_account_file.__func__(AdGroupCriterionLabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdGroupCriterionLabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdGroupCriterionLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCriterionLabelServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdGroupCriterionLabelServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupCriterionLabelServiceTransport, + Callable[..., AdGroupCriterionLabelServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group criterion label service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupCriterionLabelServiceTransport,Callable[..., AdGroupCriterionLabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupCriterionLabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdGroupCriterionLabelServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdGroupCriterionLabelServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupCriterionLabelService", + "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.ads.googleads.v23.services.AdGroupCriterionLabelService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_group_criterion_labels( + self, + request: Optional[ + Union[ + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + ad_group_criterion_label_service.AdGroupCriterionLabelOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse: + r"""Creates and removes ad group criterion labels. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdGroupCriterionLabelsRequest, dict]]): + The request object. Request message for + [AdGroupCriterionLabelService.MutateAdGroupCriterionLabels][google.ads.googleads.v23.services.AdGroupCriterionLabelService.MutateAdGroupCriterionLabels]. + customer_id (:class:`str`): + Required. ID of the customer whose ad + group criterion labels are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdGroupCriterionLabelOperation]`): + Required. The list of operations to + perform on ad group criterion labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupCriterionLabelsResponse: + Response message for an ad group + criterion labels mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest, + ): + request = ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_group_criterion_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AdGroupCriterionLabelServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdGroupCriterionLabelServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/client.py b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/client.py new file mode 100644 index 000000000..0175f4aa3 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/client.py @@ -0,0 +1,969 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + ad_group_criterion_label_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCriterionLabelServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupCriterionLabelServiceGrpcTransport +from .transports.grpc_asyncio import ( + AdGroupCriterionLabelServiceGrpcAsyncIOTransport, +) + + +class AdGroupCriterionLabelServiceClientMeta(type): + """Metaclass for the AdGroupCriterionLabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupCriterionLabelServiceTransport]] + _transport_registry["grpc"] = AdGroupCriterionLabelServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AdGroupCriterionLabelServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdGroupCriterionLabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupCriterionLabelServiceClient( + metaclass=AdGroupCriterionLabelServiceClientMeta +): + """Service to manage labels on ad group criteria.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupCriterionLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCriterionLabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_criterion_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_label_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_label string.""" + return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path( + customer_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, + label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AdGroupCriterionLabelServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AdGroupCriterionLabelServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + AdGroupCriterionLabelServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + AdGroupCriterionLabelServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = AdGroupCriterionLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdGroupCriterionLabelServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupCriterionLabelServiceTransport, + Callable[..., AdGroupCriterionLabelServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group criterion label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupCriterionLabelServiceTransport,Callable[..., AdGroupCriterionLabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupCriterionLabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdGroupCriterionLabelServiceClient._read_environment_variables() + self._client_cert_source = ( + AdGroupCriterionLabelServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AdGroupCriterionLabelServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AdGroupCriterionLabelServiceTransport + ) + if transport_provided: + # transport is a AdGroupCriterionLabelServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + AdGroupCriterionLabelServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdGroupCriterionLabelServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdGroupCriterionLabelServiceTransport], + Callable[..., AdGroupCriterionLabelServiceTransport], + ] = ( + AdGroupCriterionLabelServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AdGroupCriterionLabelServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdGroupCriterionLabelServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupCriterionLabelService", + "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.ads.googleads.v23.services.AdGroupCriterionLabelService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_group_criterion_labels( + self, + request: Optional[ + Union[ + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + ad_group_criterion_label_service.AdGroupCriterionLabelOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse: + r"""Creates and removes ad group criterion labels. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdGroupCriterionLabelsRequest, dict]): + The request object. Request message for + [AdGroupCriterionLabelService.MutateAdGroupCriterionLabels][google.ads.googleads.v23.services.AdGroupCriterionLabelService.MutateAdGroupCriterionLabels]. + customer_id (str): + Required. ID of the customer whose ad + group criterion labels are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupCriterionLabelOperation]): + Required. The list of operations to + perform on ad group criterion labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupCriterionLabelsResponse: + Response message for an ad group + criterion labels mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest, + ): + request = ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_criterion_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdGroupCriterionLabelServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdGroupCriterionLabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_criterion_label_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/base.py new file mode 100644 index 000000000..49fccf796 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + ad_group_criterion_label_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdGroupCriterionLabelServiceTransport(abc.ABC): + """Abstract transport class for AdGroupCriterionLabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_criterion_labels: gapic_v1.method.wrap_method( + self.mutate_ad_group_criterion_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_criterion_labels( + self, + ) -> Callable[ + [ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest], + Union[ + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse, + Awaitable[ + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdGroupCriterionLabelServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/grpc.py new file mode 100644 index 000000000..eac50e18f --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/grpc.py @@ -0,0 +1,394 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + ad_group_criterion_label_service, +) +from .base import AdGroupCriterionLabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdGroupCriterionLabelService", + "rpcName": str(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.ads.googleads.v23.services.AdGroupCriterionLabelService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupCriterionLabelServiceGrpcTransport( + AdGroupCriterionLabelServiceTransport +): + """gRPC backend transport for AdGroupCriterionLabelService. + + Service to manage labels on ad group criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_group_criterion_labels( + self, + ) -> Callable[ + [ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest], + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse, + ]: + r"""Return a callable for the mutate ad group criterion + labels method over gRPC. + + Creates and removes ad group criterion labels. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupCriterionLabelsRequest], + ~.MutateAdGroupCriterionLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_criterion_labels" not in self._stubs: + self._stubs["mutate_ad_group_criterion_labels"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupCriterionLabelService/MutateAdGroupCriterionLabels", + request_serializer=ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest.serialize, + response_deserializer=ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_criterion_labels"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdGroupCriterionLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..326ea5508 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_label_service/transports/grpc_asyncio.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + ad_group_criterion_label_service, +) +from .base import AdGroupCriterionLabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdGroupCriterionLabelService", + "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.ads.googleads.v23.services.AdGroupCriterionLabelService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupCriterionLabelServiceGrpcAsyncIOTransport( + AdGroupCriterionLabelServiceTransport +): + """gRPC AsyncIO backend transport for AdGroupCriterionLabelService. + + Service to manage labels on ad group criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_group_criterion_labels( + self, + ) -> Callable[ + [ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest], + Awaitable[ + ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse + ], + ]: + r"""Return a callable for the mutate ad group criterion + labels method over gRPC. + + Creates and removes ad group criterion labels. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupCriterionLabelsRequest], + Awaitable[~.MutateAdGroupCriterionLabelsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_criterion_labels" not in self._stubs: + self._stubs["mutate_ad_group_criterion_labels"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupCriterionLabelService/MutateAdGroupCriterionLabels", + request_serializer=ad_group_criterion_label_service.MutateAdGroupCriterionLabelsRequest.serialize, + response_deserializer=ad_group_criterion_label_service.MutateAdGroupCriterionLabelsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_criterion_labels"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_group_criterion_labels: self._wrap_method( + self.mutate_ad_group_criterion_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdGroupCriterionLabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_service/__init__.py b/google/ads/googleads/v23/services/services/ad_group_criterion_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_criterion_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_criterion_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_service/async_client.py b/google/ads/googleads/v23/services/services/ad_group_criterion_service/async_client.py new file mode 100644 index 000000000..bd179c637 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_service/async_client.py @@ -0,0 +1,469 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_criterion_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AdGroupCriterionServiceClient + +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 AdGroupCriterionServiceAsyncClient: + """Service to manage ad group criteria.""" + + _client: AdGroupCriterionServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdGroupCriterionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AdGroupCriterionServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AdGroupCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AdGroupCriterionServiceClient._DEFAULT_UNIVERSE + + ad_group_path = staticmethod(AdGroupCriterionServiceClient.ad_group_path) + parse_ad_group_path = staticmethod( + AdGroupCriterionServiceClient.parse_ad_group_path + ) + ad_group_criterion_path = staticmethod( + AdGroupCriterionServiceClient.ad_group_criterion_path + ) + parse_ad_group_criterion_path = staticmethod( + AdGroupCriterionServiceClient.parse_ad_group_criterion_path + ) + ad_group_criterion_label_path = staticmethod( + AdGroupCriterionServiceClient.ad_group_criterion_label_path + ) + parse_ad_group_criterion_label_path = staticmethod( + AdGroupCriterionServiceClient.parse_ad_group_criterion_label_path + ) + combined_audience_path = staticmethod( + AdGroupCriterionServiceClient.combined_audience_path + ) + parse_combined_audience_path = staticmethod( + AdGroupCriterionServiceClient.parse_combined_audience_path + ) + mobile_app_category_constant_path = staticmethod( + AdGroupCriterionServiceClient.mobile_app_category_constant_path + ) + parse_mobile_app_category_constant_path = staticmethod( + AdGroupCriterionServiceClient.parse_mobile_app_category_constant_path + ) + topic_constant_path = staticmethod( + AdGroupCriterionServiceClient.topic_constant_path + ) + parse_topic_constant_path = staticmethod( + AdGroupCriterionServiceClient.parse_topic_constant_path + ) + common_billing_account_path = staticmethod( + AdGroupCriterionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdGroupCriterionServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AdGroupCriterionServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AdGroupCriterionServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdGroupCriterionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdGroupCriterionServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AdGroupCriterionServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AdGroupCriterionServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdGroupCriterionServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdGroupCriterionServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionServiceAsyncClient: The constructed client. + """ + return AdGroupCriterionServiceClient.from_service_account_info.__func__(AdGroupCriterionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionServiceAsyncClient: The constructed client. + """ + return AdGroupCriterionServiceClient.from_service_account_file.__func__(AdGroupCriterionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdGroupCriterionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdGroupCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCriterionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdGroupCriterionServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupCriterionServiceTransport, + Callable[..., AdGroupCriterionServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group criterion service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupCriterionServiceTransport,Callable[..., AdGroupCriterionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupCriterionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdGroupCriterionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdGroupCriterionServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupCriterionService", + "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.ads.googleads.v23.services.AdGroupCriterionService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_group_criteria( + self, + request: Optional[ + Union[ad_group_criterion_service.MutateAdGroupCriteriaRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + ad_group_criterion_service.AdGroupCriterionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_criterion_service.MutateAdGroupCriteriaResponse: + r"""Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdGroupCriterionError <>`__ + `AdxError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `BiddingStrategyError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DateError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyViolationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdGroupCriteriaRequest, dict]]): + The request object. Request message for + [AdGroupCriterionService.MutateAdGroupCriteria][google.ads.googleads.v23.services.AdGroupCriterionService.MutateAdGroupCriteria]. + customer_id (:class:`str`): + Required. ID of the customer whose + criteria are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdGroupCriterionOperation]`): + Required. The list of operations to + perform on individual criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupCriteriaResponse: + Response message for an ad group + criterion mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_criterion_service.MutateAdGroupCriteriaRequest + ): + request = ad_group_criterion_service.MutateAdGroupCriteriaRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_group_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AdGroupCriterionServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdGroupCriterionServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_service/client.py b/google/ads/googleads/v23/services/services/ad_group_criterion_service/client.py new file mode 100644 index 000000000..f0168ef6f --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_service/client.py @@ -0,0 +1,1018 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ad_group_criterion_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupCriterionServiceGrpcTransport +from .transports.grpc_asyncio import AdGroupCriterionServiceGrpcAsyncIOTransport + + +class AdGroupCriterionServiceClientMeta(type): + """Metaclass for the AdGroupCriterionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupCriterionServiceTransport]] + _transport_registry["grpc"] = AdGroupCriterionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AdGroupCriterionServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdGroupCriterionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupCriterionServiceClient( + metaclass=AdGroupCriterionServiceClientMeta +): + """Service to manage ad group criteria.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCriterionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_path( + customer_id: str, + ad_group_id: str, + ) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_label_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_label string.""" + return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def combined_audience_path( + customer_id: str, + combined_audience_id: str, + ) -> str: + """Returns a fully-qualified combined_audience string.""" + return "customers/{customer_id}/combinedAudiences/{combined_audience_id}".format( + customer_id=customer_id, + combined_audience_id=combined_audience_id, + ) + + @staticmethod + def parse_combined_audience_path(path: str) -> Dict[str, str]: + """Parses a combined_audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/combinedAudiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_app_category_constant_path( + mobile_app_category_id: str, + ) -> str: + """Returns a fully-qualified mobile_app_category_constant string.""" + return "mobileAppCategoryConstants/{mobile_app_category_id}".format( + mobile_app_category_id=mobile_app_category_id, + ) + + @staticmethod + def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: + """Parses a mobile_app_category_constant path into its component segments.""" + m = re.match( + r"^mobileAppCategoryConstants/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def topic_constant_path( + topic_id: str, + ) -> str: + """Returns a fully-qualified topic_constant string.""" + return "topicConstants/{topic_id}".format( + topic_id=topic_id, + ) + + @staticmethod + def parse_topic_constant_path(path: str) -> Dict[str, str]: + """Parses a topic_constant path into its component segments.""" + m = re.match(r"^topicConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AdGroupCriterionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AdGroupCriterionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AdGroupCriterionServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdGroupCriterionServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AdGroupCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdGroupCriterionServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupCriterionServiceTransport, + Callable[..., AdGroupCriterionServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group criterion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupCriterionServiceTransport,Callable[..., AdGroupCriterionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupCriterionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdGroupCriterionServiceClient._read_environment_variables() + self._client_cert_source = ( + AdGroupCriterionServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AdGroupCriterionServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AdGroupCriterionServiceTransport + ) + if transport_provided: + # transport is a AdGroupCriterionServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AdGroupCriterionServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdGroupCriterionServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdGroupCriterionServiceTransport], + Callable[..., AdGroupCriterionServiceTransport], + ] = ( + AdGroupCriterionServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AdGroupCriterionServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdGroupCriterionServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupCriterionService", + "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.ads.googleads.v23.services.AdGroupCriterionService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_group_criteria( + self, + request: Optional[ + Union[ad_group_criterion_service.MutateAdGroupCriteriaRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + ad_group_criterion_service.AdGroupCriterionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_criterion_service.MutateAdGroupCriteriaResponse: + r"""Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdGroupCriterionError <>`__ + `AdxError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `BiddingStrategyError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DateError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyViolationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdGroupCriteriaRequest, dict]): + The request object. Request message for + [AdGroupCriterionService.MutateAdGroupCriteria][google.ads.googleads.v23.services.AdGroupCriterionService.MutateAdGroupCriteria]. + customer_id (str): + Required. ID of the customer whose + criteria are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupCriterionOperation]): + Required. The list of operations to + perform on individual criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupCriteriaResponse: + Response message for an ad group + criterion mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_criterion_service.MutateAdGroupCriteriaRequest + ): + request = ad_group_criterion_service.MutateAdGroupCriteriaRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdGroupCriterionServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdGroupCriterionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_criterion_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/base.py new file mode 100644 index 000000000..f304f61b3 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ad_group_criterion_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdGroupCriterionServiceTransport(abc.ABC): + """Abstract transport class for AdGroupCriterionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_criteria: gapic_v1.method.wrap_method( + self.mutate_ad_group_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_criteria( + self, + ) -> Callable[ + [ad_group_criterion_service.MutateAdGroupCriteriaRequest], + Union[ + ad_group_criterion_service.MutateAdGroupCriteriaResponse, + Awaitable[ad_group_criterion_service.MutateAdGroupCriteriaResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdGroupCriterionServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/grpc.py new file mode 100644 index 000000000..236361488 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/grpc.py @@ -0,0 +1,400 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ad_group_criterion_service +from .base import AdGroupCriterionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdGroupCriterionService", + "rpcName": str(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.ads.googleads.v23.services.AdGroupCriterionService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupCriterionServiceGrpcTransport(AdGroupCriterionServiceTransport): + """gRPC backend transport for AdGroupCriterionService. + + Service to manage ad group criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_group_criteria( + self, + ) -> Callable[ + [ad_group_criterion_service.MutateAdGroupCriteriaRequest], + ad_group_criterion_service.MutateAdGroupCriteriaResponse, + ]: + r"""Return a callable for the mutate ad group criteria method over gRPC. + + Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdGroupCriterionError <>`__ + `AdxError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `BiddingStrategyError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DateError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyViolationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdGroupCriteriaRequest], + ~.MutateAdGroupCriteriaResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_criteria" not in self._stubs: + self._stubs["mutate_ad_group_criteria"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupCriterionService/MutateAdGroupCriteria", + request_serializer=ad_group_criterion_service.MutateAdGroupCriteriaRequest.serialize, + response_deserializer=ad_group_criterion_service.MutateAdGroupCriteriaResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_criteria"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdGroupCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..d5b254aa7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_criterion_service/transports/grpc_asyncio.py @@ -0,0 +1,423 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_criterion_service +from .base import AdGroupCriterionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdGroupCriterionService", + "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.ads.googleads.v23.services.AdGroupCriterionService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupCriterionServiceGrpcAsyncIOTransport( + AdGroupCriterionServiceTransport +): + """gRPC AsyncIO backend transport for AdGroupCriterionService. + + Service to manage ad group criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_group_criteria( + self, + ) -> Callable[ + [ad_group_criterion_service.MutateAdGroupCriteriaRequest], + Awaitable[ad_group_criterion_service.MutateAdGroupCriteriaResponse], + ]: + r"""Return a callable for the mutate ad group criteria method over gRPC. + + Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdGroupCriterionError <>`__ + `AdxError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `BiddingStrategyError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DateError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `PolicyViolationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdGroupCriteriaRequest], + Awaitable[~.MutateAdGroupCriteriaResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_criteria" not in self._stubs: + self._stubs["mutate_ad_group_criteria"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupCriterionService/MutateAdGroupCriteria", + request_serializer=ad_group_criterion_service.MutateAdGroupCriteriaRequest.serialize, + response_deserializer=ad_group_criterion_service.MutateAdGroupCriteriaResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_criteria"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_group_criteria: self._wrap_method( + self.mutate_ad_group_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdGroupCriterionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_customizer_service/__init__.py b/google/ads/googleads/v23/services/services/ad_group_customizer_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_customizer_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_customizer_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_customizer_service/async_client.py b/google/ads/googleads/v23/services/services/ad_group_customizer_service/async_client.py new file mode 100644 index 000000000..83a67cc7d --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_customizer_service/async_client.py @@ -0,0 +1,442 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_customizer_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AdGroupCustomizerServiceClient + +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 AdGroupCustomizerServiceAsyncClient: + """Service to manage ad group customizer""" + + _client: AdGroupCustomizerServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdGroupCustomizerServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AdGroupCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AdGroupCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AdGroupCustomizerServiceClient._DEFAULT_UNIVERSE + + ad_group_path = staticmethod(AdGroupCustomizerServiceClient.ad_group_path) + parse_ad_group_path = staticmethod( + AdGroupCustomizerServiceClient.parse_ad_group_path + ) + ad_group_customizer_path = staticmethod( + AdGroupCustomizerServiceClient.ad_group_customizer_path + ) + parse_ad_group_customizer_path = staticmethod( + AdGroupCustomizerServiceClient.parse_ad_group_customizer_path + ) + customizer_attribute_path = staticmethod( + AdGroupCustomizerServiceClient.customizer_attribute_path + ) + parse_customizer_attribute_path = staticmethod( + AdGroupCustomizerServiceClient.parse_customizer_attribute_path + ) + common_billing_account_path = staticmethod( + AdGroupCustomizerServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdGroupCustomizerServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AdGroupCustomizerServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AdGroupCustomizerServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdGroupCustomizerServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdGroupCustomizerServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AdGroupCustomizerServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AdGroupCustomizerServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdGroupCustomizerServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdGroupCustomizerServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCustomizerServiceAsyncClient: The constructed client. + """ + return AdGroupCustomizerServiceClient.from_service_account_info.__func__(AdGroupCustomizerServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCustomizerServiceAsyncClient: The constructed client. + """ + return AdGroupCustomizerServiceClient.from_service_account_file.__func__(AdGroupCustomizerServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdGroupCustomizerServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdGroupCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCustomizerServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdGroupCustomizerServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupCustomizerServiceTransport, + Callable[..., AdGroupCustomizerServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group customizer service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupCustomizerServiceTransport,Callable[..., AdGroupCustomizerServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupCustomizerServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdGroupCustomizerServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdGroupCustomizerServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupCustomizerService", + "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.ads.googleads.v23.services.AdGroupCustomizerService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_group_customizers( + self, + request: Optional[ + Union[ + ad_group_customizer_service.MutateAdGroupCustomizersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + ad_group_customizer_service.AdGroupCustomizerOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_customizer_service.MutateAdGroupCustomizersResponse: + r"""Creates, updates or removes ad group customizers. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdGroupCustomizersRequest, dict]]): + The request object. Request message for + [AdGroupCustomizerService.MutateAdGroupCustomizers][google.ads.googleads.v23.services.AdGroupCustomizerService.MutateAdGroupCustomizers]. + customer_id (:class:`str`): + Required. The ID of the customer + whose ad group customizers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdGroupCustomizerOperation]`): + Required. The list of operations to + perform on individual ad group + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupCustomizersResponse: + Response message for an ad group + customizer mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_customizer_service.MutateAdGroupCustomizersRequest + ): + request = ( + ad_group_customizer_service.MutateAdGroupCustomizersRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_group_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AdGroupCustomizerServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdGroupCustomizerServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_group_customizer_service/client.py b/google/ads/googleads/v23/services/services/ad_group_customizer_service/client.py new file mode 100644 index 000000000..bc69b5445 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_customizer_service/client.py @@ -0,0 +1,952 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ad_group_customizer_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AdGroupCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AdGroupCustomizerServiceGrpcTransport +from .transports.grpc_asyncio import ( + AdGroupCustomizerServiceGrpcAsyncIOTransport, +) + + +class AdGroupCustomizerServiceClientMeta(type): + """Metaclass for the AdGroupCustomizerService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupCustomizerServiceTransport]] + _transport_registry["grpc"] = AdGroupCustomizerServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AdGroupCustomizerServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdGroupCustomizerServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupCustomizerServiceClient( + metaclass=AdGroupCustomizerServiceClientMeta +): + """Service to manage ad group customizer""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupCustomizerServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_path( + customer_id: str, + ad_group_id: str, + ) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_customizer_path( + customer_id: str, + ad_group_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_customizer string.""" + return "customers/{customer_id}/adGroupCustomizers/{ad_group_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AdGroupCustomizerServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AdGroupCustomizerServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AdGroupCustomizerServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdGroupCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = AdGroupCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdGroupCustomizerServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupCustomizerServiceTransport, + Callable[..., AdGroupCustomizerServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group customizer service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupCustomizerServiceTransport,Callable[..., AdGroupCustomizerServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupCustomizerServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdGroupCustomizerServiceClient._read_environment_variables() + self._client_cert_source = ( + AdGroupCustomizerServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AdGroupCustomizerServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AdGroupCustomizerServiceTransport + ) + if transport_provided: + # transport is a AdGroupCustomizerServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AdGroupCustomizerServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdGroupCustomizerServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdGroupCustomizerServiceTransport], + Callable[..., AdGroupCustomizerServiceTransport], + ] = ( + AdGroupCustomizerServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AdGroupCustomizerServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdGroupCustomizerServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupCustomizerService", + "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.ads.googleads.v23.services.AdGroupCustomizerService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_group_customizers( + self, + request: Optional[ + Union[ + ad_group_customizer_service.MutateAdGroupCustomizersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + ad_group_customizer_service.AdGroupCustomizerOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_customizer_service.MutateAdGroupCustomizersResponse: + r"""Creates, updates or removes ad group customizers. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdGroupCustomizersRequest, dict]): + The request object. Request message for + [AdGroupCustomizerService.MutateAdGroupCustomizers][google.ads.googleads.v23.services.AdGroupCustomizerService.MutateAdGroupCustomizers]. + customer_id (str): + Required. The ID of the customer + whose ad group customizers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupCustomizerOperation]): + Required. The list of operations to + perform on individual ad group + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupCustomizersResponse: + Response message for an ad group + customizer mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_customizer_service.MutateAdGroupCustomizersRequest + ): + request = ( + ad_group_customizer_service.MutateAdGroupCustomizersRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdGroupCustomizerServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdGroupCustomizerServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_customizer_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/base.py new file mode 100644 index 000000000..50f5ceee7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ad_group_customizer_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdGroupCustomizerServiceTransport(abc.ABC): + """Abstract transport class for AdGroupCustomizerService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_customizers: gapic_v1.method.wrap_method( + self.mutate_ad_group_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_customizers( + self, + ) -> Callable[ + [ad_group_customizer_service.MutateAdGroupCustomizersRequest], + Union[ + ad_group_customizer_service.MutateAdGroupCustomizersResponse, + Awaitable[ + ad_group_customizer_service.MutateAdGroupCustomizersResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdGroupCustomizerServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/grpc.py new file mode 100644 index 000000000..4cf1b06e5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/grpc.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ad_group_customizer_service +from .base import AdGroupCustomizerServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdGroupCustomizerService", + "rpcName": str(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.ads.googleads.v23.services.AdGroupCustomizerService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupCustomizerServiceGrpcTransport(AdGroupCustomizerServiceTransport): + """gRPC backend transport for AdGroupCustomizerService. + + Service to manage ad group customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_group_customizers( + self, + ) -> Callable[ + [ad_group_customizer_service.MutateAdGroupCustomizersRequest], + ad_group_customizer_service.MutateAdGroupCustomizersResponse, + ]: + r"""Return a callable for the mutate ad group customizers method over gRPC. + + Creates, updates or removes ad group customizers. + Operation statuses are returned. + + Returns: + Callable[[~.MutateAdGroupCustomizersRequest], + ~.MutateAdGroupCustomizersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_customizers" not in self._stubs: + self._stubs["mutate_ad_group_customizers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupCustomizerService/MutateAdGroupCustomizers", + request_serializer=ad_group_customizer_service.MutateAdGroupCustomizersRequest.serialize, + response_deserializer=ad_group_customizer_service.MutateAdGroupCustomizersResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_customizers"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdGroupCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..53e8a4656 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_customizer_service/transports/grpc_asyncio.py @@ -0,0 +1,407 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_customizer_service +from .base import AdGroupCustomizerServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdGroupCustomizerService", + "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.ads.googleads.v23.services.AdGroupCustomizerService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupCustomizerServiceGrpcAsyncIOTransport( + AdGroupCustomizerServiceTransport +): + """gRPC AsyncIO backend transport for AdGroupCustomizerService. + + Service to manage ad group customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_group_customizers( + self, + ) -> Callable[ + [ad_group_customizer_service.MutateAdGroupCustomizersRequest], + Awaitable[ad_group_customizer_service.MutateAdGroupCustomizersResponse], + ]: + r"""Return a callable for the mutate ad group customizers method over gRPC. + + Creates, updates or removes ad group customizers. + Operation statuses are returned. + + Returns: + Callable[[~.MutateAdGroupCustomizersRequest], + Awaitable[~.MutateAdGroupCustomizersResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_customizers" not in self._stubs: + self._stubs["mutate_ad_group_customizers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupCustomizerService/MutateAdGroupCustomizers", + request_serializer=ad_group_customizer_service.MutateAdGroupCustomizersRequest.serialize, + response_deserializer=ad_group_customizer_service.MutateAdGroupCustomizersResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_customizers"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_group_customizers: self._wrap_method( + self.mutate_ad_group_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdGroupCustomizerServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_label_service/__init__.py b/google/ads/googleads/v23/services/services/ad_group_label_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_label_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_label_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_label_service/async_client.py b/google/ads/googleads/v23/services/services/ad_group_label_service/async_client.py new file mode 100644 index 000000000..5a9bd8d43 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_label_service/async_client.py @@ -0,0 +1,430 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupLabelServiceTransport, DEFAULT_CLIENT_INFO +from .client import AdGroupLabelServiceClient + +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 AdGroupLabelServiceAsyncClient: + """Service to manage labels on ad groups.""" + + _client: AdGroupLabelServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdGroupLabelServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AdGroupLabelServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AdGroupLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AdGroupLabelServiceClient._DEFAULT_UNIVERSE + + ad_group_path = staticmethod(AdGroupLabelServiceClient.ad_group_path) + parse_ad_group_path = staticmethod( + AdGroupLabelServiceClient.parse_ad_group_path + ) + ad_group_label_path = staticmethod( + AdGroupLabelServiceClient.ad_group_label_path + ) + parse_ad_group_label_path = staticmethod( + AdGroupLabelServiceClient.parse_ad_group_label_path + ) + label_path = staticmethod(AdGroupLabelServiceClient.label_path) + parse_label_path = staticmethod(AdGroupLabelServiceClient.parse_label_path) + common_billing_account_path = staticmethod( + AdGroupLabelServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdGroupLabelServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AdGroupLabelServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AdGroupLabelServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdGroupLabelServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdGroupLabelServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AdGroupLabelServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AdGroupLabelServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdGroupLabelServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdGroupLabelServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupLabelServiceAsyncClient: The constructed client. + """ + return AdGroupLabelServiceClient.from_service_account_info.__func__(AdGroupLabelServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupLabelServiceAsyncClient: The constructed client. + """ + return AdGroupLabelServiceClient.from_service_account_file.__func__(AdGroupLabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdGroupLabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdGroupLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupLabelServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdGroupLabelServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupLabelServiceTransport, + Callable[..., AdGroupLabelServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group label service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupLabelServiceTransport,Callable[..., AdGroupLabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupLabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdGroupLabelServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdGroupLabelServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupLabelService", + "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.ads.googleads.v23.services.AdGroupLabelService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_group_labels( + self, + request: Optional[ + Union[ad_group_label_service.MutateAdGroupLabelsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_label_service.AdGroupLabelOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_label_service.MutateAdGroupLabelsResponse: + r"""Creates and removes ad group labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdGroupLabelsRequest, dict]]): + The request object. Request message for + [AdGroupLabelService.MutateAdGroupLabels][google.ads.googleads.v23.services.AdGroupLabelService.MutateAdGroupLabels]. + customer_id (:class:`str`): + Required. ID of the customer whose ad + group labels are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdGroupLabelOperation]`): + Required. The list of operations to + perform on ad group labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupLabelsResponse: + Response message for an ad group + labels mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_label_service.MutateAdGroupLabelsRequest + ): + request = ad_group_label_service.MutateAdGroupLabelsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_group_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AdGroupLabelServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdGroupLabelServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_group_label_service/client.py b/google/ads/googleads/v23/services/services/ad_group_label_service/client.py new file mode 100644 index 000000000..f636032df --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_label_service/client.py @@ -0,0 +1,933 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ad_group_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupLabelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdGroupLabelServiceGrpcTransport +from .transports.grpc_asyncio import AdGroupLabelServiceGrpcAsyncIOTransport + + +class AdGroupLabelServiceClientMeta(type): + """Metaclass for the AdGroupLabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupLabelServiceTransport]] + _transport_registry["grpc"] = AdGroupLabelServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AdGroupLabelServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdGroupLabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupLabelServiceClient(metaclass=AdGroupLabelServiceClientMeta): + """Service to manage labels on ad groups.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupLabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_path( + customer_id: str, + ad_group_id: str, + ) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_label_path( + customer_id: str, + ad_group_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_label string.""" + return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path( + customer_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, + label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AdGroupLabelServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AdGroupLabelServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AdGroupLabelServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdGroupLabelServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AdGroupLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdGroupLabelServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupLabelServiceTransport, + Callable[..., AdGroupLabelServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupLabelServiceTransport,Callable[..., AdGroupLabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupLabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdGroupLabelServiceClient._read_environment_variables() + self._client_cert_source = ( + AdGroupLabelServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = AdGroupLabelServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AdGroupLabelServiceTransport) + if transport_provided: + # transport is a AdGroupLabelServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AdGroupLabelServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdGroupLabelServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdGroupLabelServiceTransport], + Callable[..., AdGroupLabelServiceTransport], + ] = ( + AdGroupLabelServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AdGroupLabelServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdGroupLabelServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupLabelService", + "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.ads.googleads.v23.services.AdGroupLabelService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_group_labels( + self, + request: Optional[ + Union[ad_group_label_service.MutateAdGroupLabelsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_label_service.AdGroupLabelOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_label_service.MutateAdGroupLabelsResponse: + r"""Creates and removes ad group labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdGroupLabelsRequest, dict]): + The request object. Request message for + [AdGroupLabelService.MutateAdGroupLabels][google.ads.googleads.v23.services.AdGroupLabelService.MutateAdGroupLabels]. + customer_id (str): + Required. ID of the customer whose ad + group labels are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupLabelOperation]): + Required. The list of operations to + perform on ad group labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupLabelsResponse: + Response message for an ad group + labels mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_group_label_service.MutateAdGroupLabelsRequest + ): + request = ad_group_label_service.MutateAdGroupLabelsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_group_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdGroupLabelServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdGroupLabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_label_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_group_label_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_label_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_group_label_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_group_label_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_group_label_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_label_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_label_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_label_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_group_label_service/transports/base.py new file mode 100644 index 000000000..68da89b3d --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_label_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ad_group_label_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdGroupLabelServiceTransport(abc.ABC): + """Abstract transport class for AdGroupLabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_group_labels: gapic_v1.method.wrap_method( + self.mutate_ad_group_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_group_labels( + self, + ) -> Callable[ + [ad_group_label_service.MutateAdGroupLabelsRequest], + Union[ + ad_group_label_service.MutateAdGroupLabelsResponse, + Awaitable[ad_group_label_service.MutateAdGroupLabelsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdGroupLabelServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_label_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_group_label_service/transports/grpc.py new file mode 100644 index 000000000..328a25cd0 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_label_service/transports/grpc.py @@ -0,0 +1,390 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ad_group_label_service +from .base import AdGroupLabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdGroupLabelService", + "rpcName": str(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.ads.googleads.v23.services.AdGroupLabelService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupLabelServiceGrpcTransport(AdGroupLabelServiceTransport): + """gRPC backend transport for AdGroupLabelService. + + Service to manage labels on ad groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_group_labels( + self, + ) -> Callable[ + [ad_group_label_service.MutateAdGroupLabelsRequest], + ad_group_label_service.MutateAdGroupLabelsResponse, + ]: + r"""Return a callable for the mutate ad group labels method over gRPC. + + Creates and removes ad group labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupLabelsRequest], + ~.MutateAdGroupLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_labels" not in self._stubs: + self._stubs["mutate_ad_group_labels"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupLabelService/MutateAdGroupLabels", + request_serializer=ad_group_label_service.MutateAdGroupLabelsRequest.serialize, + response_deserializer=ad_group_label_service.MutateAdGroupLabelsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_labels"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdGroupLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_label_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_group_label_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..18046a561 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_label_service/transports/grpc_asyncio.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_label_service +from .base import AdGroupLabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdGroupLabelService", + "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.ads.googleads.v23.services.AdGroupLabelService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupLabelServiceGrpcAsyncIOTransport(AdGroupLabelServiceTransport): + """gRPC AsyncIO backend transport for AdGroupLabelService. + + Service to manage labels on ad groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_group_labels( + self, + ) -> Callable[ + [ad_group_label_service.MutateAdGroupLabelsRequest], + Awaitable[ad_group_label_service.MutateAdGroupLabelsResponse], + ]: + r"""Return a callable for the mutate ad group labels method over gRPC. + + Creates and removes ad group labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdGroupLabelsRequest], + Awaitable[~.MutateAdGroupLabelsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_group_labels" not in self._stubs: + self._stubs["mutate_ad_group_labels"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupLabelService/MutateAdGroupLabels", + request_serializer=ad_group_label_service.MutateAdGroupLabelsRequest.serialize, + response_deserializer=ad_group_label_service.MutateAdGroupLabelsResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_group_labels"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_group_labels: self._wrap_method( + self.mutate_ad_group_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdGroupLabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_group_service/__init__.py b/google/ads/googleads/v23/services/services/ad_group_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_service/async_client.py b/google/ads/googleads/v23/services/services/ad_group_service/async_client.py new file mode 100644 index 000000000..587ae8dbb --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_service/async_client.py @@ -0,0 +1,427 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupServiceTransport, DEFAULT_CLIENT_INFO +from .client import AdGroupServiceClient + +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 AdGroupServiceAsyncClient: + """Service to manage ad groups.""" + + _client: AdGroupServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdGroupServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AdGroupServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = AdGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = AdGroupServiceClient._DEFAULT_UNIVERSE + + ad_group_path = staticmethod(AdGroupServiceClient.ad_group_path) + parse_ad_group_path = staticmethod(AdGroupServiceClient.parse_ad_group_path) + ad_group_label_path = staticmethod(AdGroupServiceClient.ad_group_label_path) + parse_ad_group_label_path = staticmethod( + AdGroupServiceClient.parse_ad_group_label_path + ) + campaign_path = staticmethod(AdGroupServiceClient.campaign_path) + parse_campaign_path = staticmethod(AdGroupServiceClient.parse_campaign_path) + common_billing_account_path = staticmethod( + AdGroupServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdGroupServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(AdGroupServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + AdGroupServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdGroupServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdGroupServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(AdGroupServiceClient.common_project_path) + parse_common_project_path = staticmethod( + AdGroupServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdGroupServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdGroupServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupServiceAsyncClient: The constructed client. + """ + return AdGroupServiceClient.from_service_account_info.__func__(AdGroupServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupServiceAsyncClient: The constructed client. + """ + return AdGroupServiceClient.from_service_account_file.__func__(AdGroupServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdGroupServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdGroupServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupServiceTransport, + Callable[..., AdGroupServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupServiceTransport,Callable[..., AdGroupServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdGroupServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdGroupServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupService", + "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.ads.googleads.v23.services.AdGroupService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_groups( + self, + request: Optional[ + Union[ad_group_service.MutateAdGroupsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_service.AdGroupOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_service.MutateAdGroupsResponse: + r"""Creates, updates, or removes ad groups. Operation statuses are + returned. + + List of thrown errors: `AdGroupError <>`__ `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdGroupsRequest, dict]]): + The request object. Request message for + [AdGroupService.MutateAdGroups][google.ads.googleads.v23.services.AdGroupService.MutateAdGroups]. + customer_id (:class:`str`): + Required. The ID of the customer + whose ad groups are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdGroupOperation]`): + Required. The list of operations to + perform on individual ad groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupsResponse: + Response message for an ad group + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, ad_group_service.MutateAdGroupsRequest): + request = ad_group_service.MutateAdGroupsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_groups + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AdGroupServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdGroupServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_group_service/client.py b/google/ads/googleads/v23/services/services/ad_group_service/client.py new file mode 100644 index 000000000..18dfaff42 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_service/client.py @@ -0,0 +1,933 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ad_group_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdGroupServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdGroupServiceGrpcTransport +from .transports.grpc_asyncio import AdGroupServiceGrpcAsyncIOTransport + + +class AdGroupServiceClientMeta(type): + """Metaclass for the AdGroupService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdGroupServiceTransport]] + _transport_registry["grpc"] = AdGroupServiceGrpcTransport + _transport_registry["grpc_asyncio"] = AdGroupServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdGroupServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdGroupServiceClient(metaclass=AdGroupServiceClientMeta): + """Service to manage ad groups.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdGroupServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_path( + customer_id: str, + ad_group_id: str, + ) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_label_path( + customer_id: str, + ad_group_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_label string.""" + return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AdGroupServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AdGroupServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AdGroupServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdGroupServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AdGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdGroupServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdGroupServiceTransport, + Callable[..., AdGroupServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad group service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdGroupServiceTransport,Callable[..., AdGroupServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdGroupServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdGroupServiceClient._read_environment_variables() + self._client_cert_source = AdGroupServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = AdGroupServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AdGroupServiceTransport) + if transport_provided: + # transport is a AdGroupServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AdGroupServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdGroupServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdGroupServiceTransport], + Callable[..., AdGroupServiceTransport], + ] = ( + AdGroupServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AdGroupServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdGroupServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdGroupService", + "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.ads.googleads.v23.services.AdGroupService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_groups( + self, + request: Optional[ + Union[ad_group_service.MutateAdGroupsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_group_service.AdGroupOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_group_service.MutateAdGroupsResponse: + r"""Creates, updates, or removes ad groups. Operation statuses are + returned. + + List of thrown errors: `AdGroupError <>`__ `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdGroupsRequest, dict]): + The request object. Request message for + [AdGroupService.MutateAdGroups][google.ads.googleads.v23.services.AdGroupService.MutateAdGroups]. + customer_id (str): + Required. The ID of the customer + whose ad groups are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupOperation]): + Required. The list of operations to + perform on individual ad groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdGroupsResponse: + Response message for an ad group + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, ad_group_service.MutateAdGroupsRequest): + request = ad_group_service.MutateAdGroupsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_ad_groups] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdGroupServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdGroupServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_group_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_group_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_group_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_group_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_group_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_group_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_group_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_group_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_group_service/transports/base.py new file mode 100644 index 000000000..fd3b481cb --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ad_group_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdGroupServiceTransport(abc.ABC): + """Abstract transport class for AdGroupService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_groups: gapic_v1.method.wrap_method( + self.mutate_ad_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_groups( + self, + ) -> Callable[ + [ad_group_service.MutateAdGroupsRequest], + Union[ + ad_group_service.MutateAdGroupsResponse, + Awaitable[ad_group_service.MutateAdGroupsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdGroupServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_group_service/transports/grpc.py new file mode 100644 index 000000000..0f82b0ee8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_service/transports/grpc.py @@ -0,0 +1,397 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ad_group_service +from .base import AdGroupServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdGroupService", + "rpcName": str(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.ads.googleads.v23.services.AdGroupService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupServiceGrpcTransport(AdGroupServiceTransport): + """gRPC backend transport for AdGroupService. + + Service to manage ad groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_groups( + self, + ) -> Callable[ + [ad_group_service.MutateAdGroupsRequest], + ad_group_service.MutateAdGroupsResponse, + ]: + r"""Return a callable for the mutate ad groups method over gRPC. + + Creates, updates, or removes ad groups. Operation statuses are + returned. + + List of thrown errors: `AdGroupError <>`__ `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdGroupsRequest], + ~.MutateAdGroupsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_groups" not in self._stubs: + self._stubs["mutate_ad_groups"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupService/MutateAdGroups", + request_serializer=ad_group_service.MutateAdGroupsRequest.serialize, + response_deserializer=ad_group_service.MutateAdGroupsResponse.deserialize, + ) + return self._stubs["mutate_ad_groups"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_group_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_group_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..77728cb2b --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_group_service/transports/grpc_asyncio.py @@ -0,0 +1,418 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ad_group_service +from .base import AdGroupServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdGroupService", + "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.ads.googleads.v23.services.AdGroupService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdGroupServiceGrpcAsyncIOTransport(AdGroupServiceTransport): + """gRPC AsyncIO backend transport for AdGroupService. + + Service to manage ad groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_groups( + self, + ) -> Callable[ + [ad_group_service.MutateAdGroupsRequest], + Awaitable[ad_group_service.MutateAdGroupsResponse], + ]: + r"""Return a callable for the mutate ad groups method over gRPC. + + Creates, updates, or removes ad groups. Operation statuses are + returned. + + List of thrown errors: `AdGroupError <>`__ `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MultiplierError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdGroupsRequest], + Awaitable[~.MutateAdGroupsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_groups" not in self._stubs: + self._stubs["mutate_ad_groups"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdGroupService/MutateAdGroups", + request_serializer=ad_group_service.MutateAdGroupsRequest.serialize, + response_deserializer=ad_group_service.MutateAdGroupsResponse.deserialize, + ) + return self._stubs["mutate_ad_groups"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_groups: self._wrap_method( + self.mutate_ad_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdGroupServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_parameter_service/__init__.py b/google/ads/googleads/v23/services/services/ad_parameter_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_parameter_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_parameter_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_parameter_service/async_client.py b/google/ads/googleads/v23/services/services/ad_parameter_service/async_client.py new file mode 100644 index 000000000..e7fc8d62b --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_parameter_service/async_client.py @@ -0,0 +1,428 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ad_parameter_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdParameterServiceTransport, DEFAULT_CLIENT_INFO +from .client import AdParameterServiceClient + +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 AdParameterServiceAsyncClient: + """Service to manage ad parameters.""" + + _client: AdParameterServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdParameterServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AdParameterServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AdParameterServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AdParameterServiceClient._DEFAULT_UNIVERSE + + ad_group_criterion_path = staticmethod( + AdParameterServiceClient.ad_group_criterion_path + ) + parse_ad_group_criterion_path = staticmethod( + AdParameterServiceClient.parse_ad_group_criterion_path + ) + ad_parameter_path = staticmethod(AdParameterServiceClient.ad_parameter_path) + parse_ad_parameter_path = staticmethod( + AdParameterServiceClient.parse_ad_parameter_path + ) + common_billing_account_path = staticmethod( + AdParameterServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdParameterServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AdParameterServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AdParameterServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdParameterServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdParameterServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AdParameterServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AdParameterServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AdParameterServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AdParameterServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdParameterServiceAsyncClient: The constructed client. + """ + return AdParameterServiceClient.from_service_account_info.__func__(AdParameterServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdParameterServiceAsyncClient: The constructed client. + """ + return AdParameterServiceClient.from_service_account_file.__func__(AdParameterServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdParameterServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdParameterServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdParameterServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdParameterServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdParameterServiceTransport, + Callable[..., AdParameterServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad parameter service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdParameterServiceTransport,Callable[..., AdParameterServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdParameterServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdParameterServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdParameterServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdParameterService", + "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.ads.googleads.v23.services.AdParameterService", + "credentialsType": None, + } + ), + ) + + async def mutate_ad_parameters( + self, + request: Optional[ + Union[ad_parameter_service.MutateAdParametersRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_parameter_service.AdParameterOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_parameter_service.MutateAdParametersResponse: + r"""Creates, updates, or removes ad parameters. Operation statuses + are returned. + + List of thrown errors: `AdParameterError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdParametersRequest, dict]]): + The request object. Request message for + [AdParameterService.MutateAdParameters][google.ads.googleads.v23.services.AdParameterService.MutateAdParameters] + customer_id (:class:`str`): + Required. The ID of the customer + whose ad parameters are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdParameterOperation]`): + Required. The list of operations to + perform on individual ad parameters. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdParametersResponse: + Response message for an ad parameter + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_parameter_service.MutateAdParametersRequest + ): + request = ad_parameter_service.MutateAdParametersRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ad_parameters + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AdParameterServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdParameterServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_parameter_service/client.py b/google/ads/googleads/v23/services/services/ad_parameter_service/client.py new file mode 100644 index 000000000..0c32cf3d9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_parameter_service/client.py @@ -0,0 +1,914 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ad_parameter_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdParameterServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdParameterServiceGrpcTransport +from .transports.grpc_asyncio import AdParameterServiceGrpcAsyncIOTransport + + +class AdParameterServiceClientMeta(type): + """Metaclass for the AdParameterService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdParameterServiceTransport]] + _transport_registry["grpc"] = AdParameterServiceGrpcTransport + _transport_registry["grpc_asyncio"] = AdParameterServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdParameterServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdParameterServiceClient(metaclass=AdParameterServiceClientMeta): + """Service to manage ad parameters.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdParameterServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdParameterServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdParameterServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdParameterServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_criterion_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_parameter_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + parameter_index: str, + ) -> str: + """Returns a fully-qualified ad_parameter string.""" + return "customers/{customer_id}/adParameters/{ad_group_id}~{criterion_id}~{parameter_index}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + parameter_index=parameter_index, + ) + + @staticmethod + def parse_ad_parameter_path(path: str) -> Dict[str, str]: + """Parses a ad_parameter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adParameters/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AdParameterServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AdParameterServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AdParameterServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdParameterServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AdParameterServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdParameterServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AdParameterServiceTransport, + Callable[..., AdParameterServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad parameter service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdParameterServiceTransport,Callable[..., AdParameterServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdParameterServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdParameterServiceClient._read_environment_variables() + self._client_cert_source = ( + AdParameterServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = AdParameterServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AdParameterServiceTransport) + if transport_provided: + # transport is a AdParameterServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AdParameterServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdParameterServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdParameterServiceTransport], + Callable[..., AdParameterServiceTransport], + ] = ( + AdParameterServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AdParameterServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdParameterServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdParameterService", + "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.ads.googleads.v23.services.AdParameterService", + "credentialsType": None, + } + ), + ) + + def mutate_ad_parameters( + self, + request: Optional[ + Union[ad_parameter_service.MutateAdParametersRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ad_parameter_service.AdParameterOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_parameter_service.MutateAdParametersResponse: + r"""Creates, updates, or removes ad parameters. Operation statuses + are returned. + + List of thrown errors: `AdParameterError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdParametersRequest, dict]): + The request object. Request message for + [AdParameterService.MutateAdParameters][google.ads.googleads.v23.services.AdParameterService.MutateAdParameters] + customer_id (str): + Required. The ID of the customer + whose ad parameters are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdParameterOperation]): + Required. The list of operations to + perform on individual ad parameters. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdParametersResponse: + Response message for an ad parameter + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, ad_parameter_service.MutateAdParametersRequest + ): + request = ad_parameter_service.MutateAdParametersRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_ad_parameters + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdParameterServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdParameterServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_parameter_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_parameter_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_parameter_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_parameter_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_parameter_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_parameter_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_parameter_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_parameter_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_parameter_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_parameter_service/transports/base.py new file mode 100644 index 000000000..27f942295 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_parameter_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ad_parameter_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdParameterServiceTransport(abc.ABC): + """Abstract transport class for AdParameterService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ad_parameters: gapic_v1.method.wrap_method( + self.mutate_ad_parameters, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ad_parameters( + self, + ) -> Callable[ + [ad_parameter_service.MutateAdParametersRequest], + Union[ + ad_parameter_service.MutateAdParametersResponse, + Awaitable[ad_parameter_service.MutateAdParametersResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdParameterServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_parameter_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_parameter_service/transports/grpc.py new file mode 100644 index 000000000..86a744600 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_parameter_service/transports/grpc.py @@ -0,0 +1,390 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ad_parameter_service +from .base import AdParameterServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdParameterService", + "rpcName": str(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.ads.googleads.v23.services.AdParameterService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdParameterServiceGrpcTransport(AdParameterServiceTransport): + """gRPC backend transport for AdParameterService. + + Service to manage ad parameters. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ad_parameters( + self, + ) -> Callable[ + [ad_parameter_service.MutateAdParametersRequest], + ad_parameter_service.MutateAdParametersResponse, + ]: + r"""Return a callable for the mutate ad parameters method over gRPC. + + Creates, updates, or removes ad parameters. Operation statuses + are returned. + + List of thrown errors: `AdParameterError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdParametersRequest], + ~.MutateAdParametersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_parameters" not in self._stubs: + self._stubs["mutate_ad_parameters"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdParameterService/MutateAdParameters", + request_serializer=ad_parameter_service.MutateAdParametersRequest.serialize, + response_deserializer=ad_parameter_service.MutateAdParametersResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_parameters"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdParameterServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_parameter_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_parameter_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..ffbb9ab26 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_parameter_service/transports/grpc_asyncio.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ad_parameter_service +from .base import AdParameterServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdParameterService", + "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.ads.googleads.v23.services.AdParameterService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdParameterServiceGrpcAsyncIOTransport(AdParameterServiceTransport): + """gRPC AsyncIO backend transport for AdParameterService. + + Service to manage ad parameters. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ad_parameters( + self, + ) -> Callable[ + [ad_parameter_service.MutateAdParametersRequest], + Awaitable[ad_parameter_service.MutateAdParametersResponse], + ]: + r"""Return a callable for the mutate ad parameters method over gRPC. + + Creates, updates, or removes ad parameters. Operation statuses + are returned. + + List of thrown errors: `AdParameterError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateAdParametersRequest], + Awaitable[~.MutateAdParametersResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ad_parameters" not in self._stubs: + self._stubs["mutate_ad_parameters"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdParameterService/MutateAdParameters", + request_serializer=ad_parameter_service.MutateAdParametersRequest.serialize, + response_deserializer=ad_parameter_service.MutateAdParametersResponse.deserialize, + ) + ) + return self._stubs["mutate_ad_parameters"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ad_parameters: self._wrap_method( + self.mutate_ad_parameters, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdParameterServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/ad_service/__init__.py b/google/ads/googleads/v23/services/services/ad_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_service/__init__.py rename to google/ads/googleads/v23/services/services/ad_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_service/async_client.py b/google/ads/googleads/v23/services/services/ad_service/async_client.py new file mode 100644 index 000000000..28e86293f --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_service/async_client.py @@ -0,0 +1,412 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ad_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdServiceTransport, DEFAULT_CLIENT_INFO +from .client import AdServiceClient + +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 AdServiceAsyncClient: + """Service to manage ads.""" + + _client: AdServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AdServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AdServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = AdServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = AdServiceClient._DEFAULT_UNIVERSE + + ad_path = staticmethod(AdServiceClient.ad_path) + parse_ad_path = staticmethod(AdServiceClient.parse_ad_path) + common_billing_account_path = staticmethod( + AdServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AdServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(AdServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + AdServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AdServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AdServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(AdServiceClient.common_project_path) + parse_common_project_path = staticmethod( + AdServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(AdServiceClient.common_location_path) + parse_common_location_path = staticmethod( + AdServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdServiceAsyncClient: The constructed client. + """ + return AdServiceClient.from_service_account_info.__func__(AdServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdServiceAsyncClient: The constructed client. + """ + return AdServiceClient.from_service_account_file.__func__(AdServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AdServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AdServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AdServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[str, AdServiceTransport, Callable[..., AdServiceTransport]] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdServiceTransport,Callable[..., AdServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AdServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AdServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdService", + "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.ads.googleads.v23.services.AdService", + "credentialsType": None, + } + ), + ) + + async def mutate_ads( + self, + request: Optional[Union[ad_service.MutateAdsRequest, dict]] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[MutableSequence[ad_service.AdOperation]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_service.MutateAdsResponse: + r"""Updates ads. Operation statuses are returned. Updating ads is + not supported for TextAd, ExpandedDynamicSearchAd, GmailAd and + ImageAd. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdSharingError <>`__ `AdxError <>`__ `AssetError <>`__ + `AssetLinkError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAdsRequest, dict]]): + The request object. Request message for + [AdService.MutateAds][google.ads.googleads.v23.services.AdService.MutateAds]. + customer_id (:class:`str`): + Required. The ID of the customer + whose ads are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AdOperation]`): + Required. The list of operations to + perform on individual ads. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdsResponse: + Response message for an ad mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, ad_service.MutateAdsRequest): + request = ad_service.MutateAdsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_ads + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AdServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AdServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/ad_service/client.py b/google/ads/googleads/v23/services/services/ad_service/client.py new file mode 100644 index 000000000..21ae40c0f --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_service/client.py @@ -0,0 +1,880 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ad_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AdServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AdServiceGrpcTransport +from .transports.grpc_asyncio import AdServiceGrpcAsyncIOTransport + + +class AdServiceClientMeta(type): + """Metaclass for the AdService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AdServiceTransport]] + _transport_registry["grpc"] = AdServiceGrpcTransport + _transport_registry["grpc_asyncio"] = AdServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AdServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AdServiceClient(metaclass=AdServiceClientMeta): + """Service to manage ads.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AdServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AdServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AdServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_path( + customer_id: str, + ad_id: str, + ) -> str: + """Returns a fully-qualified ad string.""" + return "customers/{customer_id}/ads/{ad_id}".format( + customer_id=customer_id, + ad_id=ad_id, + ) + + @staticmethod + def parse_ad_path(path: str) -> Dict[str, str]: + """Parses a ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ads/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AdServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AdServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AdServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AdServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = AdServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AdServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[str, AdServiceTransport, Callable[..., AdServiceTransport]] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the ad service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AdServiceTransport,Callable[..., AdServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AdServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AdServiceClient._read_environment_variables() + self._client_cert_source = AdServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = AdServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AdServiceTransport) + if transport_provided: + # transport is a AdServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AdServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AdServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AdServiceTransport], Callable[..., AdServiceTransport] + ] = ( + AdServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AdServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AdServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AdService", + "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.ads.googleads.v23.services.AdService", + "credentialsType": None, + } + ), + ) + + def mutate_ads( + self, + request: Optional[Union[ad_service.MutateAdsRequest, dict]] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[MutableSequence[ad_service.AdOperation]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ad_service.MutateAdsResponse: + r"""Updates ads. Operation statuses are returned. Updating ads is + not supported for TextAd, ExpandedDynamicSearchAd, GmailAd and + ImageAd. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdSharingError <>`__ `AdxError <>`__ `AssetError <>`__ + `AssetLinkError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAdsRequest, dict]): + The request object. Request message for + [AdService.MutateAds][google.ads.googleads.v23.services.AdService.MutateAds]. + customer_id (str): + Required. The ID of the customer + whose ads are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AdOperation]): + Required. The list of operations to + perform on individual ads. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAdsResponse: + Response message for an ad mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, ad_service.MutateAdsRequest): + request = ad_service.MutateAdsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_ads] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AdServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AdServiceClient",) diff --git a/google/ads/googleads/v19/services/services/ad_service/transports/README.rst b/google/ads/googleads/v23/services/services/ad_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/ad_service/transports/README.rst rename to google/ads/googleads/v23/services/services/ad_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/ad_service/transports/__init__.py b/google/ads/googleads/v23/services/services/ad_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/ad_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/ad_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/ad_service/transports/base.py b/google/ads/googleads/v23/services/services/ad_service/transports/base.py new file mode 100644 index 000000000..9f2cfe69e --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ad_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AdServiceTransport(abc.ABC): + """Abstract transport class for AdService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_ads: gapic_v1.method.wrap_method( + self.mutate_ads, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_ads( + self, + ) -> Callable[ + [ad_service.MutateAdsRequest], + Union[ + ad_service.MutateAdsResponse, + Awaitable[ad_service.MutateAdsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AdServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_service/transports/grpc.py b/google/ads/googleads/v23/services/services/ad_service/transports/grpc.py new file mode 100644 index 000000000..7e1d2b6c8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_service/transports/grpc.py @@ -0,0 +1,397 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ad_service +from .base import AdServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AdService", + "rpcName": str(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.ads.googleads.v23.services.AdService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdServiceGrpcTransport(AdServiceTransport): + """gRPC backend transport for AdService. + + Service to manage ads. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_ads( + self, + ) -> Callable[[ad_service.MutateAdsRequest], ad_service.MutateAdsResponse]: + r"""Return a callable for the mutate ads method over gRPC. + + Updates ads. Operation statuses are returned. Updating ads is + not supported for TextAd, ExpandedDynamicSearchAd, GmailAd and + ImageAd. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdSharingError <>`__ `AdxError <>`__ `AssetError <>`__ + `AssetLinkError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdsRequest], + ~.MutateAdsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ads" not in self._stubs: + self._stubs["mutate_ads"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdService/MutateAds", + request_serializer=ad_service.MutateAdsRequest.serialize, + response_deserializer=ad_service.MutateAdsResponse.deserialize, + ) + return self._stubs["mutate_ads"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AdServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/ad_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/ad_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..8ce805159 --- /dev/null +++ b/google/ads/googleads/v23/services/services/ad_service/transports/grpc_asyncio.py @@ -0,0 +1,420 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ad_service +from .base import AdServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AdService", + "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.ads.googleads.v23.services.AdService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AdServiceGrpcAsyncIOTransport(AdServiceTransport): + """gRPC AsyncIO backend transport for AdService. + + Service to manage ads. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_ads( + self, + ) -> Callable[ + [ad_service.MutateAdsRequest], Awaitable[ad_service.MutateAdsResponse] + ]: + r"""Return a callable for the mutate ads method over gRPC. + + Updates ads. Operation statuses are returned. Updating ads is + not supported for TextAd, ExpandedDynamicSearchAd, GmailAd and + ImageAd. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdSharingError <>`__ `AdxError <>`__ `AssetError <>`__ + `AssetLinkError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FeedAttributeReferenceError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `FunctionError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `IdError <>`__ + `ImageError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaBundleError <>`__ `MediaFileError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateAdsRequest], + Awaitable[~.MutateAdsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_ads" not in self._stubs: + self._stubs["mutate_ads"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AdService/MutateAds", + request_serializer=ad_service.MutateAdsRequest.serialize, + response_deserializer=ad_service.MutateAdsResponse.deserialize, + ) + return self._stubs["mutate_ads"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_ads: self._wrap_method( + self.mutate_ads, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AdServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_generation_service/__init__.py b/google/ads/googleads/v23/services/services/asset_generation_service/__init__.py new file mode 100644 index 000000000..f9f403217 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_generation_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import AssetGenerationServiceClient +from .async_client import AssetGenerationServiceAsyncClient + +__all__ = ( + "AssetGenerationServiceClient", + "AssetGenerationServiceAsyncClient", +) diff --git a/google/ads/googleads/v23/services/services/asset_generation_service/async_client.py b/google/ads/googleads/v23/services/services/asset_generation_service/async_client.py new file mode 100644 index 000000000..227efc961 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_generation_service/async_client.py @@ -0,0 +1,466 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import asset_generation_service +from .transports.base import ( + AssetGenerationServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AssetGenerationServiceClient + +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 AssetGenerationServiceAsyncClient: + """Service for generating new assets with generative AI.""" + + _client: AssetGenerationServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AssetGenerationServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AssetGenerationServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AssetGenerationServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AssetGenerationServiceClient._DEFAULT_UNIVERSE + + ad_group_ad_path = staticmethod( + AssetGenerationServiceClient.ad_group_ad_path + ) + parse_ad_group_ad_path = staticmethod( + AssetGenerationServiceClient.parse_ad_group_ad_path + ) + asset_group_path = staticmethod( + AssetGenerationServiceClient.asset_group_path + ) + parse_asset_group_path = staticmethod( + AssetGenerationServiceClient.parse_asset_group_path + ) + common_billing_account_path = staticmethod( + AssetGenerationServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetGenerationServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AssetGenerationServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AssetGenerationServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AssetGenerationServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AssetGenerationServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AssetGenerationServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AssetGenerationServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AssetGenerationServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AssetGenerationServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGenerationServiceAsyncClient: The constructed client. + """ + return AssetGenerationServiceClient.from_service_account_info.__func__(AssetGenerationServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGenerationServiceAsyncClient: The constructed client. + """ + return AssetGenerationServiceClient.from_service_account_file.__func__(AssetGenerationServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AssetGenerationServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AssetGenerationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGenerationServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AssetGenerationServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetGenerationServiceTransport, + Callable[..., AssetGenerationServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset generation service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetGenerationServiceTransport,Callable[..., AssetGenerationServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetGenerationServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AssetGenerationServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AssetGenerationServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetGenerationService", + "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.ads.googleads.v23.services.AssetGenerationService", + "credentialsType": None, + } + ), + ) + + async def generate_text( + self, + request: Optional[ + Union[asset_generation_service.GenerateTextRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_generation_service.GenerateTextResponse: + r"""Uses generative AI to generate text that can be used as assets + in a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `AssetGenerationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateTextRequest, dict]]): + The request object. Request message for + [AssetGenerationService.GenerateText][google.ads.googleads.v23.services.AssetGenerationService.GenerateText] + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateTextResponse: + Response message for + [AssetGenerationService.GenerateText][google.ads.googleads.v23.services.AssetGenerationService.GenerateText] + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_generation_service.GenerateTextRequest + ): + request = asset_generation_service.GenerateTextRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_text + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_images( + self, + request: Optional[ + Union[asset_generation_service.GenerateImagesRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_generation_service.GenerateImagesResponse: + r"""Uses generative AI to generate images that can be used as assets + in a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `AssetGenerationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateImagesRequest, dict]]): + The request object. Request message for + [AssetGenerationService.GenerateImages][google.ads.googleads.v23.services.AssetGenerationService.GenerateImages] + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateImagesResponse: + Response message for + [AssetGenerationService.GenerateImages][google.ads.googleads.v23.services.AssetGenerationService.GenerateImages] + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_generation_service.GenerateImagesRequest + ): + request = asset_generation_service.GenerateImagesRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_images + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AssetGenerationServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AssetGenerationServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/asset_generation_service/client.py b/google/ads/googleads/v23/services/services/asset_generation_service/client.py new file mode 100644 index 000000000..adeb030a2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_generation_service/client.py @@ -0,0 +1,947 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import asset_generation_service +from .transports.base import ( + AssetGenerationServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AssetGenerationServiceGrpcTransport +from .transports.grpc_asyncio import AssetGenerationServiceGrpcAsyncIOTransport + + +class AssetGenerationServiceClientMeta(type): + """Metaclass for the AssetGenerationService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetGenerationServiceTransport]] + _transport_registry["grpc"] = AssetGenerationServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AssetGenerationServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AssetGenerationServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetGenerationServiceClient(metaclass=AssetGenerationServiceClientMeta): + """Service for generating new assets with generative AI.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGenerationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGenerationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetGenerationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGenerationServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_group_ad_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad string.""" + return ( + "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + ) + ) + + @staticmethod + def parse_ad_group_ad_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_path( + customer_id: str, + asset_group_id: str, + ) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AssetGenerationServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AssetGenerationServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AssetGenerationServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AssetGenerationServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AssetGenerationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AssetGenerationServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetGenerationServiceTransport, + Callable[..., AssetGenerationServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset generation service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetGenerationServiceTransport,Callable[..., AssetGenerationServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetGenerationServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AssetGenerationServiceClient._read_environment_variables() + self._client_cert_source = ( + AssetGenerationServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AssetGenerationServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AssetGenerationServiceTransport + ) + if transport_provided: + # transport is a AssetGenerationServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AssetGenerationServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AssetGenerationServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AssetGenerationServiceTransport], + Callable[..., AssetGenerationServiceTransport], + ] = ( + AssetGenerationServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AssetGenerationServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AssetGenerationServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetGenerationService", + "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.ads.googleads.v23.services.AssetGenerationService", + "credentialsType": None, + } + ), + ) + + def generate_text( + self, + request: Optional[ + Union[asset_generation_service.GenerateTextRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_generation_service.GenerateTextResponse: + r"""Uses generative AI to generate text that can be used as assets + in a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `AssetGenerationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateTextRequest, dict]): + The request object. Request message for + [AssetGenerationService.GenerateText][google.ads.googleads.v23.services.AssetGenerationService.GenerateText] + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateTextResponse: + Response message for + [AssetGenerationService.GenerateText][google.ads.googleads.v23.services.AssetGenerationService.GenerateText] + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_generation_service.GenerateTextRequest + ): + request = asset_generation_service.GenerateTextRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.generate_text] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_images( + self, + request: Optional[ + Union[asset_generation_service.GenerateImagesRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_generation_service.GenerateImagesResponse: + r"""Uses generative AI to generate images that can be used as assets + in a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `AssetGenerationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateImagesRequest, dict]): + The request object. Request message for + [AssetGenerationService.GenerateImages][google.ads.googleads.v23.services.AssetGenerationService.GenerateImages] + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateImagesResponse: + Response message for + [AssetGenerationService.GenerateImages][google.ads.googleads.v23.services.AssetGenerationService.GenerateImages] + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_generation_service.GenerateImagesRequest + ): + request = asset_generation_service.GenerateImagesRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.generate_images] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AssetGenerationServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AssetGenerationServiceClient",) diff --git a/google/ads/googleads/v23/services/services/asset_generation_service/transports/README.rst b/google/ads/googleads/v23/services/services/asset_generation_service/transports/README.rst new file mode 100644 index 000000000..7802b04f7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_generation_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`AssetGenerationServiceTransport` is the ABC for all transports. +- public child `AssetGenerationServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `AssetGenerationServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseAssetGenerationServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `AssetGenerationServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/google/ads/googleads/v23/services/services/asset_generation_service/transports/__init__.py b/google/ads/googleads/v23/services/services/asset_generation_service/transports/__init__.py new file mode 100644 index 000000000..51a5edebd --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_generation_service/transports/__init__.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict + +from .base import AssetGenerationServiceTransport +from .grpc import AssetGenerationServiceGrpcTransport +from .grpc_asyncio import AssetGenerationServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AssetGenerationServiceTransport]] +_transport_registry["grpc"] = AssetGenerationServiceGrpcTransport +_transport_registry["grpc_asyncio"] = AssetGenerationServiceGrpcAsyncIOTransport + +__all__ = ( + "AssetGenerationServiceTransport", + "AssetGenerationServiceGrpcTransport", + "AssetGenerationServiceGrpcAsyncIOTransport", +) diff --git a/google/ads/googleads/v23/services/services/asset_generation_service/transports/base.py b/google/ads/googleads/v23/services/services/asset_generation_service/transports/base.py new file mode 100644 index 000000000..9652038c6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_generation_service/transports/base.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import asset_generation_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AssetGenerationServiceTransport(abc.ABC): + """Abstract transport class for AssetGenerationService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.generate_text: gapic_v1.method.wrap_method( + self.generate_text, + default_timeout=None, + client_info=client_info, + ), + self.generate_images: gapic_v1.method.wrap_method( + self.generate_images, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def generate_text( + self, + ) -> Callable[ + [asset_generation_service.GenerateTextRequest], + Union[ + asset_generation_service.GenerateTextResponse, + Awaitable[asset_generation_service.GenerateTextResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_images( + self, + ) -> Callable[ + [asset_generation_service.GenerateImagesRequest], + Union[ + asset_generation_service.GenerateImagesResponse, + Awaitable[asset_generation_service.GenerateImagesResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AssetGenerationServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_generation_service/transports/grpc.py b/google/ads/googleads/v23/services/services/asset_generation_service/transports/grpc.py new file mode 100644 index 000000000..27424e00a --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_generation_service/transports/grpc.py @@ -0,0 +1,422 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import asset_generation_service +from .base import AssetGenerationServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AssetGenerationService", + "rpcName": str(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.ads.googleads.v23.services.AssetGenerationService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetGenerationServiceGrpcTransport(AssetGenerationServiceTransport): + """gRPC backend transport for AssetGenerationService. + + Service for generating new assets with generative AI. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def generate_text( + self, + ) -> Callable[ + [asset_generation_service.GenerateTextRequest], + asset_generation_service.GenerateTextResponse, + ]: + r"""Return a callable for the generate text method over gRPC. + + Uses generative AI to generate text that can be used as assets + in a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `AssetGenerationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateTextRequest], + ~.GenerateTextResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_text" not in self._stubs: + self._stubs["generate_text"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGenerationService/GenerateText", + request_serializer=asset_generation_service.GenerateTextRequest.serialize, + response_deserializer=asset_generation_service.GenerateTextResponse.deserialize, + ) + return self._stubs["generate_text"] + + @property + def generate_images( + self, + ) -> Callable[ + [asset_generation_service.GenerateImagesRequest], + asset_generation_service.GenerateImagesResponse, + ]: + r"""Return a callable for the generate images method over gRPC. + + Uses generative AI to generate images that can be used as assets + in a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `AssetGenerationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateImagesRequest], + ~.GenerateImagesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_images" not in self._stubs: + self._stubs["generate_images"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGenerationService/GenerateImages", + request_serializer=asset_generation_service.GenerateImagesRequest.serialize, + response_deserializer=asset_generation_service.GenerateImagesResponse.deserialize, + ) + return self._stubs["generate_images"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AssetGenerationServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_generation_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/asset_generation_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..de079f9cf --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_generation_service/transports/grpc_asyncio.py @@ -0,0 +1,450 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import asset_generation_service +from .base import AssetGenerationServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AssetGenerationService", + "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.ads.googleads.v23.services.AssetGenerationService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetGenerationServiceGrpcAsyncIOTransport( + AssetGenerationServiceTransport +): + """gRPC AsyncIO backend transport for AssetGenerationService. + + Service for generating new assets with generative AI. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def generate_text( + self, + ) -> Callable[ + [asset_generation_service.GenerateTextRequest], + Awaitable[asset_generation_service.GenerateTextResponse], + ]: + r"""Return a callable for the generate text method over gRPC. + + Uses generative AI to generate text that can be used as assets + in a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `AssetGenerationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateTextRequest], + Awaitable[~.GenerateTextResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_text" not in self._stubs: + self._stubs["generate_text"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGenerationService/GenerateText", + request_serializer=asset_generation_service.GenerateTextRequest.serialize, + response_deserializer=asset_generation_service.GenerateTextResponse.deserialize, + ) + return self._stubs["generate_text"] + + @property + def generate_images( + self, + ) -> Callable[ + [asset_generation_service.GenerateImagesRequest], + Awaitable[asset_generation_service.GenerateImagesResponse], + ]: + r"""Return a callable for the generate images method over gRPC. + + Uses generative AI to generate images that can be used as assets + in a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `AssetGenerationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateImagesRequest], + Awaitable[~.GenerateImagesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_images" not in self._stubs: + self._stubs["generate_images"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGenerationService/GenerateImages", + request_serializer=asset_generation_service.GenerateImagesRequest.serialize, + response_deserializer=asset_generation_service.GenerateImagesResponse.deserialize, + ) + return self._stubs["generate_images"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.generate_text: self._wrap_method( + self.generate_text, + default_timeout=None, + client_info=client_info, + ), + self.generate_images: self._wrap_method( + self.generate_images, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AssetGenerationServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_asset_service/__init__.py b/google/ads/googleads/v23/services/services/asset_group_asset_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_asset_service/__init__.py rename to google/ads/googleads/v23/services/services/asset_group_asset_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_group_asset_service/async_client.py b/google/ads/googleads/v23/services/services/asset_group_asset_service/async_client.py new file mode 100644 index 000000000..74c9905c1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_asset_service/async_client.py @@ -0,0 +1,435 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import asset_group_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AssetGroupAssetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AssetGroupAssetServiceClient + +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 AssetGroupAssetServiceAsyncClient: + """Service to manage asset group asset.""" + + _client: AssetGroupAssetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AssetGroupAssetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AssetGroupAssetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AssetGroupAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AssetGroupAssetServiceClient._DEFAULT_UNIVERSE + + asset_path = staticmethod(AssetGroupAssetServiceClient.asset_path) + parse_asset_path = staticmethod( + AssetGroupAssetServiceClient.parse_asset_path + ) + asset_group_path = staticmethod( + AssetGroupAssetServiceClient.asset_group_path + ) + parse_asset_group_path = staticmethod( + AssetGroupAssetServiceClient.parse_asset_group_path + ) + asset_group_asset_path = staticmethod( + AssetGroupAssetServiceClient.asset_group_asset_path + ) + parse_asset_group_asset_path = staticmethod( + AssetGroupAssetServiceClient.parse_asset_group_asset_path + ) + common_billing_account_path = staticmethod( + AssetGroupAssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetGroupAssetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AssetGroupAssetServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AssetGroupAssetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AssetGroupAssetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AssetGroupAssetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AssetGroupAssetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AssetGroupAssetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AssetGroupAssetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AssetGroupAssetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupAssetServiceAsyncClient: The constructed client. + """ + return AssetGroupAssetServiceClient.from_service_account_info.__func__(AssetGroupAssetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupAssetServiceAsyncClient: The constructed client. + """ + return AssetGroupAssetServiceClient.from_service_account_file.__func__(AssetGroupAssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AssetGroupAssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AssetGroupAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupAssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AssetGroupAssetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetGroupAssetServiceTransport, + Callable[..., AssetGroupAssetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group asset service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetGroupAssetServiceTransport,Callable[..., AssetGroupAssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetGroupAssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AssetGroupAssetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AssetGroupAssetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetGroupAssetService", + "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.ads.googleads.v23.services.AssetGroupAssetService", + "credentialsType": None, + } + ), + ) + + async def mutate_asset_group_assets( + self, + request: Optional[ + Union[asset_group_asset_service.MutateAssetGroupAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[asset_group_asset_service.AssetGroupAssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_group_asset_service.MutateAssetGroupAssetsResponse: + r"""Creates, updates or removes asset group assets. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAssetGroupAssetsRequest, dict]]): + The request object. Request message for + [AssetGroupAssetService.MutateAssetGroupAssets][google.ads.googleads.v23.services.AssetGroupAssetService.MutateAssetGroupAssets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose asset group assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AssetGroupAssetOperation]`): + Required. The list of operations to + perform on individual asset group + assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetGroupAssetsResponse: + Response message for an asset group + asset mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_group_asset_service.MutateAssetGroupAssetsRequest + ): + request = asset_group_asset_service.MutateAssetGroupAssetsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_asset_group_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AssetGroupAssetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AssetGroupAssetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/asset_group_asset_service/client.py b/google/ads/googleads/v23/services/services/asset_group_asset_service/client.py new file mode 100644 index 000000000..f544cf6f0 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_asset_service/client.py @@ -0,0 +1,944 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import asset_group_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AssetGroupAssetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AssetGroupAssetServiceGrpcTransport +from .transports.grpc_asyncio import AssetGroupAssetServiceGrpcAsyncIOTransport + + +class AssetGroupAssetServiceClientMeta(type): + """Metaclass for the AssetGroupAssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetGroupAssetServiceTransport]] + _transport_registry["grpc"] = AssetGroupAssetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AssetGroupAssetServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AssetGroupAssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetGroupAssetServiceClient(metaclass=AssetGroupAssetServiceClientMeta): + """Service to manage asset group asset.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetGroupAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupAssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_path( + customer_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_path( + customer_id: str, + asset_group_id: str, + ) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_asset_path( + customer_id: str, + asset_group_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified asset_group_asset string.""" + return "customers/{customer_id}/assetGroupAssets/{asset_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_asset_group_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AssetGroupAssetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AssetGroupAssetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AssetGroupAssetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AssetGroupAssetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AssetGroupAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AssetGroupAssetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetGroupAssetServiceTransport, + Callable[..., AssetGroupAssetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetGroupAssetServiceTransport,Callable[..., AssetGroupAssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetGroupAssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AssetGroupAssetServiceClient._read_environment_variables() + self._client_cert_source = ( + AssetGroupAssetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AssetGroupAssetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AssetGroupAssetServiceTransport + ) + if transport_provided: + # transport is a AssetGroupAssetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AssetGroupAssetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AssetGroupAssetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AssetGroupAssetServiceTransport], + Callable[..., AssetGroupAssetServiceTransport], + ] = ( + AssetGroupAssetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AssetGroupAssetServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AssetGroupAssetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetGroupAssetService", + "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.ads.googleads.v23.services.AssetGroupAssetService", + "credentialsType": None, + } + ), + ) + + def mutate_asset_group_assets( + self, + request: Optional[ + Union[asset_group_asset_service.MutateAssetGroupAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[asset_group_asset_service.AssetGroupAssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_group_asset_service.MutateAssetGroupAssetsResponse: + r"""Creates, updates or removes asset group assets. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAssetGroupAssetsRequest, dict]): + The request object. Request message for + [AssetGroupAssetService.MutateAssetGroupAssets][google.ads.googleads.v23.services.AssetGroupAssetService.MutateAssetGroupAssets]. + customer_id (str): + Required. The ID of the customer + whose asset group assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetGroupAssetOperation]): + Required. The list of operations to + perform on individual asset group + assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetGroupAssetsResponse: + Response message for an asset group + asset mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_group_asset_service.MutateAssetGroupAssetsRequest + ): + request = asset_group_asset_service.MutateAssetGroupAssetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_group_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AssetGroupAssetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AssetGroupAssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_asset_service/transports/README.rst b/google/ads/googleads/v23/services/services/asset_group_asset_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_asset_service/transports/README.rst rename to google/ads/googleads/v23/services/services/asset_group_asset_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/asset_group_asset_service/transports/__init__.py b/google/ads/googleads/v23/services/services/asset_group_asset_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_asset_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/asset_group_asset_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_group_asset_service/transports/base.py b/google/ads/googleads/v23/services/services/asset_group_asset_service/transports/base.py new file mode 100644 index 000000000..d7b1e6229 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_asset_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import asset_group_asset_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AssetGroupAssetServiceTransport(abc.ABC): + """Abstract transport class for AssetGroupAssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_group_assets: gapic_v1.method.wrap_method( + self.mutate_asset_group_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_group_assets( + self, + ) -> Callable[ + [asset_group_asset_service.MutateAssetGroupAssetsRequest], + Union[ + asset_group_asset_service.MutateAssetGroupAssetsResponse, + Awaitable[asset_group_asset_service.MutateAssetGroupAssetsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AssetGroupAssetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_group_asset_service/transports/grpc.py b/google/ads/googleads/v23/services/services/asset_group_asset_service/transports/grpc.py new file mode 100644 index 000000000..44a01e7e9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_asset_service/transports/grpc.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import asset_group_asset_service +from .base import AssetGroupAssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AssetGroupAssetService", + "rpcName": str(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.ads.googleads.v23.services.AssetGroupAssetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetGroupAssetServiceGrpcTransport(AssetGroupAssetServiceTransport): + """gRPC backend transport for AssetGroupAssetService. + + Service to manage asset group asset. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_asset_group_assets( + self, + ) -> Callable[ + [asset_group_asset_service.MutateAssetGroupAssetsRequest], + asset_group_asset_service.MutateAssetGroupAssetsResponse, + ]: + r"""Return a callable for the mutate asset group assets method over gRPC. + + Creates, updates or removes asset group assets. + Operation statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupAssetsRequest], + ~.MutateAssetGroupAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_group_assets" not in self._stubs: + self._stubs["mutate_asset_group_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGroupAssetService/MutateAssetGroupAssets", + request_serializer=asset_group_asset_service.MutateAssetGroupAssetsRequest.serialize, + response_deserializer=asset_group_asset_service.MutateAssetGroupAssetsResponse.deserialize, + ) + ) + return self._stubs["mutate_asset_group_assets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AssetGroupAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_group_asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/asset_group_asset_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..31363bbfa --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_asset_service/transports/grpc_asyncio.py @@ -0,0 +1,407 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import asset_group_asset_service +from .base import AssetGroupAssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AssetGroupAssetService", + "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.ads.googleads.v23.services.AssetGroupAssetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetGroupAssetServiceGrpcAsyncIOTransport( + AssetGroupAssetServiceTransport +): + """gRPC AsyncIO backend transport for AssetGroupAssetService. + + Service to manage asset group asset. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_asset_group_assets( + self, + ) -> Callable[ + [asset_group_asset_service.MutateAssetGroupAssetsRequest], + Awaitable[asset_group_asset_service.MutateAssetGroupAssetsResponse], + ]: + r"""Return a callable for the mutate asset group assets method over gRPC. + + Creates, updates or removes asset group assets. + Operation statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupAssetsRequest], + Awaitable[~.MutateAssetGroupAssetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_group_assets" not in self._stubs: + self._stubs["mutate_asset_group_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGroupAssetService/MutateAssetGroupAssets", + request_serializer=asset_group_asset_service.MutateAssetGroupAssetsRequest.serialize, + response_deserializer=asset_group_asset_service.MutateAssetGroupAssetsResponse.deserialize, + ) + ) + return self._stubs["mutate_asset_group_assets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_asset_group_assets: self._wrap_method( + self.mutate_asset_group_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AssetGroupAssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/__init__.py b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/__init__.py rename to google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/async_client.py b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/async_client.py new file mode 100644 index 000000000..737b03e8e --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/async_client.py @@ -0,0 +1,452 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + asset_group_listing_group_filter_service, +) +from .transports.base import ( + AssetGroupListingGroupFilterServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AssetGroupListingGroupFilterServiceClient + +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 AssetGroupListingGroupFilterServiceAsyncClient: + """Service to manage asset group listing group filter.""" + + _client: AssetGroupListingGroupFilterServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ( + AssetGroupListingGroupFilterServiceClient.DEFAULT_ENDPOINT + ) + DEFAULT_MTLS_ENDPOINT = ( + AssetGroupListingGroupFilterServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + AssetGroupListingGroupFilterServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ( + AssetGroupListingGroupFilterServiceClient._DEFAULT_UNIVERSE + ) + + asset_group_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.asset_group_path + ) + parse_asset_group_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.parse_asset_group_path + ) + asset_group_listing_group_filter_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.asset_group_listing_group_filter_path + ) + parse_asset_group_listing_group_filter_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.parse_asset_group_listing_group_filter_path + ) + common_billing_account_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AssetGroupListingGroupFilterServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupListingGroupFilterServiceAsyncClient: The constructed client. + """ + return AssetGroupListingGroupFilterServiceClient.from_service_account_info.__func__(AssetGroupListingGroupFilterServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupListingGroupFilterServiceAsyncClient: The constructed client. + """ + return AssetGroupListingGroupFilterServiceClient.from_service_account_file.__func__(AssetGroupListingGroupFilterServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AssetGroupListingGroupFilterServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AssetGroupListingGroupFilterServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupListingGroupFilterServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + AssetGroupListingGroupFilterServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetGroupListingGroupFilterServiceTransport, + Callable[..., AssetGroupListingGroupFilterServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group listing group filter service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetGroupListingGroupFilterServiceTransport,Callable[..., AssetGroupListingGroupFilterServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetGroupListingGroupFilterServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AssetGroupListingGroupFilterServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AssetGroupListingGroupFilterServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetGroupListingGroupFilterService", + "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.ads.googleads.v23.services.AssetGroupListingGroupFilterService", + "credentialsType": None, + } + ), + ) + + async def mutate_asset_group_listing_group_filters( + self, + request: Optional[ + Union[ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + asset_group_listing_group_filter_service.AssetGroupListingGroupFilterOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse + ): + r"""Creates, updates or removes asset group listing group + filters. Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAssetGroupListingGroupFiltersRequest, dict]]): + The request object. Request message for + [AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters][google.ads.googleads.v23.services.AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters]. + partial_failure is not supported because the tree needs + to be validated together. + customer_id (:class:`str`): + Required. The ID of the customer + whose asset group listing group filters + are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AssetGroupListingGroupFilterOperation]`): + Required. The list of operations to + perform on individual asset group + listing group filters. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetGroupListingGroupFiltersResponse: + Response message for an asset group + listing group filter mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest, + ): + request = asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_asset_group_listing_group_filters + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__( + self, + ) -> "AssetGroupListingGroupFilterServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AssetGroupListingGroupFilterServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/client.py b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/client.py new file mode 100644 index 000000000..5a6505839 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/client.py @@ -0,0 +1,953 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + asset_group_listing_group_filter_service, +) +from .transports.base import ( + AssetGroupListingGroupFilterServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AssetGroupListingGroupFilterServiceGrpcTransport +from .transports.grpc_asyncio import ( + AssetGroupListingGroupFilterServiceGrpcAsyncIOTransport, +) + + +class AssetGroupListingGroupFilterServiceClientMeta(type): + """Metaclass for the AssetGroupListingGroupFilterService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetGroupListingGroupFilterServiceTransport]] + _transport_registry["grpc"] = ( + AssetGroupListingGroupFilterServiceGrpcTransport + ) + _transport_registry["grpc_asyncio"] = ( + AssetGroupListingGroupFilterServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AssetGroupListingGroupFilterServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetGroupListingGroupFilterServiceClient( + metaclass=AssetGroupListingGroupFilterServiceClientMeta +): + """Service to manage asset group listing group filter.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupListingGroupFilterServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupListingGroupFilterServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetGroupListingGroupFilterServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupListingGroupFilterServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_group_path( + customer_id: str, + asset_group_id: str, + ) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_listing_group_filter_path( + customer_id: str, + asset_group_id: str, + listing_group_filter_id: str, + ) -> str: + """Returns a fully-qualified asset_group_listing_group_filter string.""" + return "customers/{customer_id}/assetGroupListingGroupFilters/{asset_group_id}~{listing_group_filter_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + listing_group_filter_id=listing_group_filter_id, + ) + + @staticmethod + def parse_asset_group_listing_group_filter_path( + path: str, + ) -> Dict[str, str]: + """Parses a asset_group_listing_group_filter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupListingGroupFilters/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AssetGroupListingGroupFilterServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AssetGroupListingGroupFilterServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + AssetGroupListingGroupFilterServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + AssetGroupListingGroupFilterServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = AssetGroupListingGroupFilterServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + AssetGroupListingGroupFilterServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetGroupListingGroupFilterServiceTransport, + Callable[..., AssetGroupListingGroupFilterServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group listing group filter service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetGroupListingGroupFilterServiceTransport,Callable[..., AssetGroupListingGroupFilterServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetGroupListingGroupFilterServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ( + AssetGroupListingGroupFilterServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + AssetGroupListingGroupFilterServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AssetGroupListingGroupFilterServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AssetGroupListingGroupFilterServiceTransport + ) + if transport_provided: + # transport is a AssetGroupListingGroupFilterServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + AssetGroupListingGroupFilterServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AssetGroupListingGroupFilterServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AssetGroupListingGroupFilterServiceTransport], + Callable[..., AssetGroupListingGroupFilterServiceTransport], + ] = ( + AssetGroupListingGroupFilterServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AssetGroupListingGroupFilterServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AssetGroupListingGroupFilterServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetGroupListingGroupFilterService", + "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.ads.googleads.v23.services.AssetGroupListingGroupFilterService", + "credentialsType": None, + } + ), + ) + + def mutate_asset_group_listing_group_filters( + self, + request: Optional[ + Union[ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + asset_group_listing_group_filter_service.AssetGroupListingGroupFilterOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse + ): + r"""Creates, updates or removes asset group listing group + filters. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAssetGroupListingGroupFiltersRequest, dict]): + The request object. Request message for + [AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters][google.ads.googleads.v23.services.AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters]. + partial_failure is not supported because the tree needs + to be validated together. + customer_id (str): + Required. The ID of the customer + whose asset group listing group filters + are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetGroupListingGroupFilterOperation]): + Required. The list of operations to + perform on individual asset group + listing group filters. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetGroupListingGroupFiltersResponse: + Response message for an asset group + listing group filter mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest, + ): + request = asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_group_listing_group_filters + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AssetGroupListingGroupFilterServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AssetGroupListingGroupFilterServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/README.rst b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/README.rst rename to google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/__init__.py b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_listing_group_filter_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/base.py b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/base.py new file mode 100644 index 000000000..2590c2e8c --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + asset_group_listing_group_filter_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AssetGroupListingGroupFilterServiceTransport(abc.ABC): + """Abstract transport class for AssetGroupListingGroupFilterService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_group_listing_group_filters: gapic_v1.method.wrap_method( + self.mutate_asset_group_listing_group_filters, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_group_listing_group_filters( + self, + ) -> Callable[ + [ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest + ], + Union[ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse, + Awaitable[ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AssetGroupListingGroupFilterServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/grpc.py b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/grpc.py new file mode 100644 index 000000000..a2918f0a8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/grpc.py @@ -0,0 +1,394 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + asset_group_listing_group_filter_service, +) +from .base import ( + AssetGroupListingGroupFilterServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AssetGroupListingGroupFilterService", + "rpcName": str(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.ads.googleads.v23.services.AssetGroupListingGroupFilterService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetGroupListingGroupFilterServiceGrpcTransport( + AssetGroupListingGroupFilterServiceTransport +): + """gRPC backend transport for AssetGroupListingGroupFilterService. + + Service to manage asset group listing group filter. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_asset_group_listing_group_filters( + self, + ) -> Callable[ + [ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest + ], + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse, + ]: + r"""Return a callable for the mutate asset group listing + group filters method over gRPC. + + Creates, updates or removes asset group listing group + filters. Operation statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupListingGroupFiltersRequest], + ~.MutateAssetGroupListingGroupFiltersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_group_listing_group_filters" not in self._stubs: + self._stubs["mutate_asset_group_listing_group_filters"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGroupListingGroupFilterService/MutateAssetGroupListingGroupFilters", + request_serializer=asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest.serialize, + response_deserializer=asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse.deserialize, + ) + ) + return self._stubs["mutate_asset_group_listing_group_filters"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AssetGroupListingGroupFilterServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..8407b4e78 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_listing_group_filter_service/transports/grpc_asyncio.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + asset_group_listing_group_filter_service, +) +from .base import ( + AssetGroupListingGroupFilterServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AssetGroupListingGroupFilterService", + "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.ads.googleads.v23.services.AssetGroupListingGroupFilterService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetGroupListingGroupFilterServiceGrpcAsyncIOTransport( + AssetGroupListingGroupFilterServiceTransport +): + """gRPC AsyncIO backend transport for AssetGroupListingGroupFilterService. + + Service to manage asset group listing group filter. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_asset_group_listing_group_filters( + self, + ) -> Callable[ + [ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest + ], + Awaitable[ + asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse + ], + ]: + r"""Return a callable for the mutate asset group listing + group filters method over gRPC. + + Creates, updates or removes asset group listing group + filters. Operation statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupListingGroupFiltersRequest], + Awaitable[~.MutateAssetGroupListingGroupFiltersResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_group_listing_group_filters" not in self._stubs: + self._stubs["mutate_asset_group_listing_group_filters"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGroupListingGroupFilterService/MutateAssetGroupListingGroupFilters", + request_serializer=asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersRequest.serialize, + response_deserializer=asset_group_listing_group_filter_service.MutateAssetGroupListingGroupFiltersResponse.deserialize, + ) + ) + return self._stubs["mutate_asset_group_listing_group_filters"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_asset_group_listing_group_filters: self._wrap_method( + self.mutate_asset_group_listing_group_filters, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AssetGroupListingGroupFilterServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_service/__init__.py b/google/ads/googleads/v23/services/services/asset_group_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_service/__init__.py rename to google/ads/googleads/v23/services/services/asset_group_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_group_service/async_client.py b/google/ads/googleads/v23/services/services/asset_group_service/async_client.py new file mode 100644 index 000000000..8aa3cc81e --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_service/async_client.py @@ -0,0 +1,420 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import asset_group_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetGroupServiceTransport, DEFAULT_CLIENT_INFO +from .client import AssetGroupServiceClient + +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 AssetGroupServiceAsyncClient: + """Service to manage asset group""" + + _client: AssetGroupServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AssetGroupServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AssetGroupServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AssetGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AssetGroupServiceClient._DEFAULT_UNIVERSE + + asset_group_path = staticmethod(AssetGroupServiceClient.asset_group_path) + parse_asset_group_path = staticmethod( + AssetGroupServiceClient.parse_asset_group_path + ) + campaign_path = staticmethod(AssetGroupServiceClient.campaign_path) + parse_campaign_path = staticmethod( + AssetGroupServiceClient.parse_campaign_path + ) + common_billing_account_path = staticmethod( + AssetGroupServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetGroupServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AssetGroupServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AssetGroupServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AssetGroupServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AssetGroupServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AssetGroupServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AssetGroupServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AssetGroupServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AssetGroupServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupServiceAsyncClient: The constructed client. + """ + return AssetGroupServiceClient.from_service_account_info.__func__(AssetGroupServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupServiceAsyncClient: The constructed client. + """ + return AssetGroupServiceClient.from_service_account_file.__func__(AssetGroupServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AssetGroupServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AssetGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AssetGroupServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetGroupServiceTransport, + Callable[..., AssetGroupServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetGroupServiceTransport,Callable[..., AssetGroupServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetGroupServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AssetGroupServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AssetGroupServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetGroupService", + "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.ads.googleads.v23.services.AssetGroupService", + "credentialsType": None, + } + ), + ) + + async def mutate_asset_groups( + self, + request: Optional[ + Union[asset_group_service.MutateAssetGroupsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[asset_group_service.AssetGroupOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_group_service.MutateAssetGroupsResponse: + r"""Creates, updates or removes asset groups. Operation + statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAssetGroupsRequest, dict]]): + The request object. Request message for + [AssetGroupService.MutateAssetGroups][google.ads.googleads.v23.services.AssetGroupService.MutateAssetGroups]. + customer_id (:class:`str`): + Required. The ID of the customer + whose asset groups are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AssetGroupOperation]`): + Required. The list of operations to + perform on individual asset groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetGroupsResponse: + Response message for an asset group + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_group_service.MutateAssetGroupsRequest + ): + request = asset_group_service.MutateAssetGroupsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_asset_groups + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AssetGroupServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AssetGroupServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/asset_group_service/client.py b/google/ads/googleads/v23/services/services/asset_group_service/client.py new file mode 100644 index 000000000..007af4ebe --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_service/client.py @@ -0,0 +1,902 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import asset_group_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetGroupServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AssetGroupServiceGrpcTransport +from .transports.grpc_asyncio import AssetGroupServiceGrpcAsyncIOTransport + + +class AssetGroupServiceClientMeta(type): + """Metaclass for the AssetGroupService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetGroupServiceTransport]] + _transport_registry["grpc"] = AssetGroupServiceGrpcTransport + _transport_registry["grpc_asyncio"] = AssetGroupServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AssetGroupServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetGroupServiceClient(metaclass=AssetGroupServiceClientMeta): + """Service to manage asset group""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_group_path( + customer_id: str, + asset_group_id: str, + ) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AssetGroupServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AssetGroupServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AssetGroupServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AssetGroupServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AssetGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AssetGroupServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetGroupServiceTransport, + Callable[..., AssetGroupServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetGroupServiceTransport,Callable[..., AssetGroupServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetGroupServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AssetGroupServiceClient._read_environment_variables() + self._client_cert_source = ( + AssetGroupServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = AssetGroupServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AssetGroupServiceTransport) + if transport_provided: + # transport is a AssetGroupServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AssetGroupServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AssetGroupServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AssetGroupServiceTransport], + Callable[..., AssetGroupServiceTransport], + ] = ( + AssetGroupServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AssetGroupServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AssetGroupServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetGroupService", + "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.ads.googleads.v23.services.AssetGroupService", + "credentialsType": None, + } + ), + ) + + def mutate_asset_groups( + self, + request: Optional[ + Union[asset_group_service.MutateAssetGroupsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[asset_group_service.AssetGroupOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_group_service.MutateAssetGroupsResponse: + r"""Creates, updates or removes asset groups. Operation + statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAssetGroupsRequest, dict]): + The request object. Request message for + [AssetGroupService.MutateAssetGroups][google.ads.googleads.v23.services.AssetGroupService.MutateAssetGroups]. + customer_id (str): + Required. The ID of the customer + whose asset groups are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetGroupOperation]): + Required. The list of operations to + perform on individual asset groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetGroupsResponse: + Response message for an asset group + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_group_service.MutateAssetGroupsRequest + ): + request = asset_group_service.MutateAssetGroupsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_groups + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AssetGroupServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AssetGroupServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_service/transports/README.rst b/google/ads/googleads/v23/services/services/asset_group_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_service/transports/README.rst rename to google/ads/googleads/v23/services/services/asset_group_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/asset_group_service/transports/__init__.py b/google/ads/googleads/v23/services/services/asset_group_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/asset_group_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_group_service/transports/base.py b/google/ads/googleads/v23/services/services/asset_group_service/transports/base.py new file mode 100644 index 000000000..6395d4d30 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import asset_group_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AssetGroupServiceTransport(abc.ABC): + """Abstract transport class for AssetGroupService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_groups: gapic_v1.method.wrap_method( + self.mutate_asset_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_groups( + self, + ) -> Callable[ + [asset_group_service.MutateAssetGroupsRequest], + Union[ + asset_group_service.MutateAssetGroupsResponse, + Awaitable[asset_group_service.MutateAssetGroupsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AssetGroupServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_group_service/transports/grpc.py b/google/ads/googleads/v23/services/services/asset_group_service/transports/grpc.py new file mode 100644 index 000000000..fb0d53f1c --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_service/transports/grpc.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import asset_group_service +from .base import AssetGroupServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AssetGroupService", + "rpcName": str(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.ads.googleads.v23.services.AssetGroupService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetGroupServiceGrpcTransport(AssetGroupServiceTransport): + """gRPC backend transport for AssetGroupService. + + Service to manage asset group + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_asset_groups( + self, + ) -> Callable[ + [asset_group_service.MutateAssetGroupsRequest], + asset_group_service.MutateAssetGroupsResponse, + ]: + r"""Return a callable for the mutate asset groups method over gRPC. + + Creates, updates or removes asset groups. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupsRequest], + ~.MutateAssetGroupsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_groups" not in self._stubs: + self._stubs["mutate_asset_groups"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGroupService/MutateAssetGroups", + request_serializer=asset_group_service.MutateAssetGroupsRequest.serialize, + response_deserializer=asset_group_service.MutateAssetGroupsResponse.deserialize, + ) + ) + return self._stubs["mutate_asset_groups"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AssetGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_group_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/asset_group_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..2d1638cbe --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_service/transports/grpc_asyncio.py @@ -0,0 +1,405 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import asset_group_service +from .base import AssetGroupServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AssetGroupService", + "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.ads.googleads.v23.services.AssetGroupService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetGroupServiceGrpcAsyncIOTransport(AssetGroupServiceTransport): + """gRPC AsyncIO backend transport for AssetGroupService. + + Service to manage asset group + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_asset_groups( + self, + ) -> Callable[ + [asset_group_service.MutateAssetGroupsRequest], + Awaitable[asset_group_service.MutateAssetGroupsResponse], + ]: + r"""Return a callable for the mutate asset groups method over gRPC. + + Creates, updates or removes asset groups. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupsRequest], + Awaitable[~.MutateAssetGroupsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_groups" not in self._stubs: + self._stubs["mutate_asset_groups"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGroupService/MutateAssetGroups", + request_serializer=asset_group_service.MutateAssetGroupsRequest.serialize, + response_deserializer=asset_group_service.MutateAssetGroupsResponse.deserialize, + ) + ) + return self._stubs["mutate_asset_groups"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_asset_groups: self._wrap_method( + self.mutate_asset_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AssetGroupServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_group_signal_service/__init__.py b/google/ads/googleads/v23/services/services/asset_group_signal_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_signal_service/__init__.py rename to google/ads/googleads/v23/services/services/asset_group_signal_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_group_signal_service/async_client.py b/google/ads/googleads/v23/services/services/asset_group_signal_service/async_client.py new file mode 100644 index 000000000..729d287b9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_signal_service/async_client.py @@ -0,0 +1,435 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import asset_group_signal_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AssetGroupSignalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AssetGroupSignalServiceClient + +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 AssetGroupSignalServiceAsyncClient: + """Service to manage asset group signal.""" + + _client: AssetGroupSignalServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AssetGroupSignalServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AssetGroupSignalServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AssetGroupSignalServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AssetGroupSignalServiceClient._DEFAULT_UNIVERSE + + asset_group_path = staticmethod( + AssetGroupSignalServiceClient.asset_group_path + ) + parse_asset_group_path = staticmethod( + AssetGroupSignalServiceClient.parse_asset_group_path + ) + asset_group_signal_path = staticmethod( + AssetGroupSignalServiceClient.asset_group_signal_path + ) + parse_asset_group_signal_path = staticmethod( + AssetGroupSignalServiceClient.parse_asset_group_signal_path + ) + common_billing_account_path = staticmethod( + AssetGroupSignalServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetGroupSignalServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AssetGroupSignalServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AssetGroupSignalServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AssetGroupSignalServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AssetGroupSignalServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AssetGroupSignalServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AssetGroupSignalServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AssetGroupSignalServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AssetGroupSignalServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupSignalServiceAsyncClient: The constructed client. + """ + return AssetGroupSignalServiceClient.from_service_account_info.__func__(AssetGroupSignalServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupSignalServiceAsyncClient: The constructed client. + """ + return AssetGroupSignalServiceClient.from_service_account_file.__func__(AssetGroupSignalServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AssetGroupSignalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AssetGroupSignalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupSignalServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AssetGroupSignalServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetGroupSignalServiceTransport, + Callable[..., AssetGroupSignalServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group signal service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetGroupSignalServiceTransport,Callable[..., AssetGroupSignalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetGroupSignalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AssetGroupSignalServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AssetGroupSignalServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetGroupSignalService", + "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.ads.googleads.v23.services.AssetGroupSignalService", + "credentialsType": None, + } + ), + ) + + async def mutate_asset_group_signals( + self, + request: Optional[ + Union[ + asset_group_signal_service.MutateAssetGroupSignalsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + asset_group_signal_service.AssetGroupSignalOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_group_signal_service.MutateAssetGroupSignalsResponse: + r"""Creates or removes asset group signals. Operation + statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAssetGroupSignalsRequest, dict]]): + The request object. Request message for + [AssetGroupSignalService.MutateAssetGroupSignals][google.ads.googleads.v23.services.AssetGroupSignalService.MutateAssetGroupSignals]. + customer_id (:class:`str`): + Required. The ID of the customer + whose asset group signals are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AssetGroupSignalOperation]`): + Required. The list of operations to + perform on individual asset group + signals. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetGroupSignalsResponse: + Response message for an asset group + signal mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_group_signal_service.MutateAssetGroupSignalsRequest + ): + request = asset_group_signal_service.MutateAssetGroupSignalsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_asset_group_signals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AssetGroupSignalServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AssetGroupSignalServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/asset_group_signal_service/client.py b/google/ads/googleads/v23/services/services/asset_group_signal_service/client.py new file mode 100644 index 000000000..0bdd2073f --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_signal_service/client.py @@ -0,0 +1,929 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import asset_group_signal_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AssetGroupSignalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AssetGroupSignalServiceGrpcTransport +from .transports.grpc_asyncio import AssetGroupSignalServiceGrpcAsyncIOTransport + + +class AssetGroupSignalServiceClientMeta(type): + """Metaclass for the AssetGroupSignalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetGroupSignalServiceTransport]] + _transport_registry["grpc"] = AssetGroupSignalServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AssetGroupSignalServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AssetGroupSignalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetGroupSignalServiceClient( + metaclass=AssetGroupSignalServiceClientMeta +): + """Service to manage asset group signal.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupSignalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetGroupSignalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetGroupSignalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetGroupSignalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_group_path( + customer_id: str, + asset_group_id: str, + ) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_signal_path( + customer_id: str, + asset_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified asset_group_signal string.""" + return "customers/{customer_id}/assetGroupSignals/{asset_group_id}~{criterion_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_asset_group_signal_path(path: str) -> Dict[str, str]: + """Parses a asset_group_signal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupSignals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AssetGroupSignalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AssetGroupSignalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AssetGroupSignalServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AssetGroupSignalServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AssetGroupSignalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AssetGroupSignalServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetGroupSignalServiceTransport, + Callable[..., AssetGroupSignalServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset group signal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetGroupSignalServiceTransport,Callable[..., AssetGroupSignalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetGroupSignalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AssetGroupSignalServiceClient._read_environment_variables() + self._client_cert_source = ( + AssetGroupSignalServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AssetGroupSignalServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AssetGroupSignalServiceTransport + ) + if transport_provided: + # transport is a AssetGroupSignalServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AssetGroupSignalServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AssetGroupSignalServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AssetGroupSignalServiceTransport], + Callable[..., AssetGroupSignalServiceTransport], + ] = ( + AssetGroupSignalServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AssetGroupSignalServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AssetGroupSignalServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetGroupSignalService", + "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.ads.googleads.v23.services.AssetGroupSignalService", + "credentialsType": None, + } + ), + ) + + def mutate_asset_group_signals( + self, + request: Optional[ + Union[ + asset_group_signal_service.MutateAssetGroupSignalsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + asset_group_signal_service.AssetGroupSignalOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_group_signal_service.MutateAssetGroupSignalsResponse: + r"""Creates or removes asset group signals. Operation + statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAssetGroupSignalsRequest, dict]): + The request object. Request message for + [AssetGroupSignalService.MutateAssetGroupSignals][google.ads.googleads.v23.services.AssetGroupSignalService.MutateAssetGroupSignals]. + customer_id (str): + Required. The ID of the customer + whose asset group signals are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetGroupSignalOperation]): + Required. The list of operations to + perform on individual asset group + signals. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetGroupSignalsResponse: + Response message for an asset group + signal mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_group_signal_service.MutateAssetGroupSignalsRequest + ): + request = asset_group_signal_service.MutateAssetGroupSignalsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_group_signals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AssetGroupSignalServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AssetGroupSignalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_group_signal_service/transports/README.rst b/google/ads/googleads/v23/services/services/asset_group_signal_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_signal_service/transports/README.rst rename to google/ads/googleads/v23/services/services/asset_group_signal_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/asset_group_signal_service/transports/__init__.py b/google/ads/googleads/v23/services/services/asset_group_signal_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_group_signal_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/asset_group_signal_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_group_signal_service/transports/base.py b/google/ads/googleads/v23/services/services/asset_group_signal_service/transports/base.py new file mode 100644 index 000000000..c89f7a678 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_signal_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import asset_group_signal_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AssetGroupSignalServiceTransport(abc.ABC): + """Abstract transport class for AssetGroupSignalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_group_signals: gapic_v1.method.wrap_method( + self.mutate_asset_group_signals, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_group_signals( + self, + ) -> Callable[ + [asset_group_signal_service.MutateAssetGroupSignalsRequest], + Union[ + asset_group_signal_service.MutateAssetGroupSignalsResponse, + Awaitable[ + asset_group_signal_service.MutateAssetGroupSignalsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AssetGroupSignalServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_group_signal_service/transports/grpc.py b/google/ads/googleads/v23/services/services/asset_group_signal_service/transports/grpc.py new file mode 100644 index 000000000..3417f5d1f --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_signal_service/transports/grpc.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import asset_group_signal_service +from .base import AssetGroupSignalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AssetGroupSignalService", + "rpcName": str(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.ads.googleads.v23.services.AssetGroupSignalService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetGroupSignalServiceGrpcTransport(AssetGroupSignalServiceTransport): + """gRPC backend transport for AssetGroupSignalService. + + Service to manage asset group signal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_asset_group_signals( + self, + ) -> Callable[ + [asset_group_signal_service.MutateAssetGroupSignalsRequest], + asset_group_signal_service.MutateAssetGroupSignalsResponse, + ]: + r"""Return a callable for the mutate asset group signals method over gRPC. + + Creates or removes asset group signals. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupSignalsRequest], + ~.MutateAssetGroupSignalsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_group_signals" not in self._stubs: + self._stubs["mutate_asset_group_signals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGroupSignalService/MutateAssetGroupSignals", + request_serializer=asset_group_signal_service.MutateAssetGroupSignalsRequest.serialize, + response_deserializer=asset_group_signal_service.MutateAssetGroupSignalsResponse.deserialize, + ) + ) + return self._stubs["mutate_asset_group_signals"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AssetGroupSignalServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_group_signal_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/asset_group_signal_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..cfc5e8187 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_group_signal_service/transports/grpc_asyncio.py @@ -0,0 +1,407 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import asset_group_signal_service +from .base import AssetGroupSignalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AssetGroupSignalService", + "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.ads.googleads.v23.services.AssetGroupSignalService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetGroupSignalServiceGrpcAsyncIOTransport( + AssetGroupSignalServiceTransport +): + """gRPC AsyncIO backend transport for AssetGroupSignalService. + + Service to manage asset group signal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_asset_group_signals( + self, + ) -> Callable[ + [asset_group_signal_service.MutateAssetGroupSignalsRequest], + Awaitable[asset_group_signal_service.MutateAssetGroupSignalsResponse], + ]: + r"""Return a callable for the mutate asset group signals method over gRPC. + + Creates or removes asset group signals. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAssetGroupSignalsRequest], + Awaitable[~.MutateAssetGroupSignalsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_group_signals" not in self._stubs: + self._stubs["mutate_asset_group_signals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetGroupSignalService/MutateAssetGroupSignals", + request_serializer=asset_group_signal_service.MutateAssetGroupSignalsRequest.serialize, + response_deserializer=asset_group_signal_service.MutateAssetGroupSignalsResponse.deserialize, + ) + ) + return self._stubs["mutate_asset_group_signals"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_asset_group_signals: self._wrap_method( + self.mutate_asset_group_signals, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AssetGroupSignalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_service/__init__.py b/google/ads/googleads/v23/services/services/asset_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_service/__init__.py rename to google/ads/googleads/v23/services/services/asset_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_service/async_client.py b/google/ads/googleads/v23/services/services/asset_service/async_client.py new file mode 100644 index 000000000..7060797bc --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_service/async_client.py @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetServiceTransport, DEFAULT_CLIENT_INFO +from .client import AssetServiceClient + +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 AssetServiceAsyncClient: + """Service to manage assets. Asset types can be created with + AssetService are YoutubeVideoAsset, MediaBundleAsset and + ImageAsset. TextAsset should be created with Ad inline. + """ + + _client: AssetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AssetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AssetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = AssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = AssetServiceClient._DEFAULT_UNIVERSE + + asset_path = staticmethod(AssetServiceClient.asset_path) + parse_asset_path = staticmethod(AssetServiceClient.parse_asset_path) + conversion_action_path = staticmethod( + AssetServiceClient.conversion_action_path + ) + parse_conversion_action_path = staticmethod( + AssetServiceClient.parse_conversion_action_path + ) + common_billing_account_path = staticmethod( + AssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(AssetServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + AssetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AssetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AssetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(AssetServiceClient.common_project_path) + parse_common_project_path = staticmethod( + AssetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(AssetServiceClient.common_location_path) + parse_common_location_path = staticmethod( + AssetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetServiceAsyncClient: The constructed client. + """ + return AssetServiceClient.from_service_account_info.__func__(AssetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetServiceAsyncClient: The constructed client. + """ + return AssetServiceClient.from_service_account_file.__func__(AssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AssetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, AssetServiceTransport, Callable[..., AssetServiceTransport] + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetServiceTransport,Callable[..., AssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AssetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AssetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetService", + "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.ads.googleads.v23.services.AssetService", + "credentialsType": None, + } + ), + ) + + async def mutate_assets( + self, + request: Optional[ + Union[asset_service.MutateAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[asset_service.AssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_service.MutateAssetsResponse: + r"""Creates assets. Operation statuses are returned. + + List of thrown errors: `AssetError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `CurrencyCodeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `YoutubeVideoRegistrationError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAssetsRequest, dict]]): + The request object. Request message for + [AssetService.MutateAssets][google.ads.googleads.v23.services.AssetService.MutateAssets] + customer_id (:class:`str`): + Required. The ID of the customer + whose assets are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AssetOperation]`): + Required. The list of operations to + perform on individual assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetsResponse: + Response message for an asset mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, asset_service.MutateAssetsRequest): + request = asset_service.MutateAssetsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AssetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AssetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/asset_service/client.py b/google/ads/googleads/v23/services/services/asset_service/client.py new file mode 100644 index 000000000..169590b04 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_service/client.py @@ -0,0 +1,904 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AssetServiceGrpcTransport +from .transports.grpc_asyncio import AssetServiceGrpcAsyncIOTransport + + +class AssetServiceClientMeta(type): + """Metaclass for the AssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetServiceTransport]] + _transport_registry["grpc"] = AssetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = AssetServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetServiceClient(metaclass=AssetServiceClientMeta): + """Service to manage assets. Asset types can be created with + AssetService are YoutubeVideoAsset, MediaBundleAsset and + ImageAsset. TextAsset should be created with Ad inline. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_path( + customer_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_action_path( + customer_id: str, + conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, + conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AssetServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AssetServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AssetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AssetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = AssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AssetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, AssetServiceTransport, Callable[..., AssetServiceTransport] + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetServiceTransport,Callable[..., AssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AssetServiceClient._read_environment_variables() + self._client_cert_source = AssetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = AssetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AssetServiceTransport) + if transport_provided: + # transport is a AssetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AssetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AssetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AssetServiceTransport], + Callable[..., AssetServiceTransport], + ] = ( + AssetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AssetServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AssetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetService", + "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.ads.googleads.v23.services.AssetService", + "credentialsType": None, + } + ), + ) + + def mutate_assets( + self, + request: Optional[ + Union[asset_service.MutateAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[asset_service.AssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_service.MutateAssetsResponse: + r"""Creates assets. Operation statuses are returned. + + List of thrown errors: `AssetError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `CurrencyCodeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `YoutubeVideoRegistrationError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAssetsRequest, dict]): + The request object. Request message for + [AssetService.MutateAssets][google.ads.googleads.v23.services.AssetService.MutateAssets] + customer_id (str): + Required. The ID of the customer + whose assets are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetOperation]): + Required. The list of operations to + perform on individual assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetsResponse: + Response message for an asset mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, asset_service.MutateAssetsRequest): + request = asset_service.MutateAssetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_assets] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AssetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_service/transports/README.rst b/google/ads/googleads/v23/services/services/asset_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/asset_service/transports/README.rst rename to google/ads/googleads/v23/services/services/asset_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/asset_service/transports/__init__.py b/google/ads/googleads/v23/services/services/asset_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/asset_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_service/transports/base.py b/google/ads/googleads/v23/services/services/asset_service/transports/base.py new file mode 100644 index 000000000..ed0e89f36 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import asset_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AssetServiceTransport(abc.ABC): + """Abstract transport class for AssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_assets: gapic_v1.method.wrap_method( + self.mutate_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_assets( + self, + ) -> Callable[ + [asset_service.MutateAssetsRequest], + Union[ + asset_service.MutateAssetsResponse, + Awaitable[asset_service.MutateAssetsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AssetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_service/transports/grpc.py b/google/ads/googleads/v23/services/services/asset_service/transports/grpc.py new file mode 100644 index 000000000..d87fdd15b --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_service/transports/grpc.py @@ -0,0 +1,395 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import asset_service +from .base import AssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AssetService", + "rpcName": str(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.ads.googleads.v23.services.AssetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetServiceGrpcTransport(AssetServiceTransport): + """gRPC backend transport for AssetService. + + Service to manage assets. Asset types can be created with + AssetService are YoutubeVideoAsset, MediaBundleAsset and + ImageAsset. TextAsset should be created with Ad inline. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_assets( + self, + ) -> Callable[ + [asset_service.MutateAssetsRequest], asset_service.MutateAssetsResponse + ]: + r"""Return a callable for the mutate assets method over gRPC. + + Creates assets. Operation statuses are returned. + + List of thrown errors: `AssetError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `CurrencyCodeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `YoutubeVideoRegistrationError <>`__ + + Returns: + Callable[[~.MutateAssetsRequest], + ~.MutateAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_assets" not in self._stubs: + self._stubs["mutate_assets"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetService/MutateAssets", + request_serializer=asset_service.MutateAssetsRequest.serialize, + response_deserializer=asset_service.MutateAssetsResponse.deserialize, + ) + return self._stubs["mutate_assets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/asset_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..f71a0d3aa --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_service/transports/grpc_asyncio.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import asset_service +from .base import AssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AssetService", + "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.ads.googleads.v23.services.AssetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetServiceGrpcAsyncIOTransport(AssetServiceTransport): + """gRPC AsyncIO backend transport for AssetService. + + Service to manage assets. Asset types can be created with + AssetService are YoutubeVideoAsset, MediaBundleAsset and + ImageAsset. TextAsset should be created with Ad inline. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_assets( + self, + ) -> Callable[ + [asset_service.MutateAssetsRequest], + Awaitable[asset_service.MutateAssetsResponse], + ]: + r"""Return a callable for the mutate assets method over gRPC. + + Creates assets. Operation statuses are returned. + + List of thrown errors: `AssetError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CollectionSizeError <>`__ `CurrencyCodeError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DistinctError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `YoutubeVideoRegistrationError <>`__ + + Returns: + Callable[[~.MutateAssetsRequest], + Awaitable[~.MutateAssetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_assets" not in self._stubs: + self._stubs["mutate_assets"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetService/MutateAssets", + request_serializer=asset_service.MutateAssetsRequest.serialize, + response_deserializer=asset_service.MutateAssetsResponse.deserialize, + ) + return self._stubs["mutate_assets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_assets: self._wrap_method( + self.mutate_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_set_asset_service/__init__.py b/google/ads/googleads/v23/services/services/asset_set_asset_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_set_asset_service/__init__.py rename to google/ads/googleads/v23/services/services/asset_set_asset_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_set_asset_service/async_client.py b/google/ads/googleads/v23/services/services/asset_set_asset_service/async_client.py new file mode 100644 index 000000000..2c1f2a537 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_set_asset_service/async_client.py @@ -0,0 +1,427 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import asset_set_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetSetAssetServiceTransport, DEFAULT_CLIENT_INFO +from .client import AssetSetAssetServiceClient + +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 AssetSetAssetServiceAsyncClient: + """Service to manage asset set asset.""" + + _client: AssetSetAssetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AssetSetAssetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AssetSetAssetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AssetSetAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AssetSetAssetServiceClient._DEFAULT_UNIVERSE + + asset_path = staticmethod(AssetSetAssetServiceClient.asset_path) + parse_asset_path = staticmethod(AssetSetAssetServiceClient.parse_asset_path) + asset_set_path = staticmethod(AssetSetAssetServiceClient.asset_set_path) + parse_asset_set_path = staticmethod( + AssetSetAssetServiceClient.parse_asset_set_path + ) + asset_set_asset_path = staticmethod( + AssetSetAssetServiceClient.asset_set_asset_path + ) + parse_asset_set_asset_path = staticmethod( + AssetSetAssetServiceClient.parse_asset_set_asset_path + ) + common_billing_account_path = staticmethod( + AssetSetAssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetSetAssetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AssetSetAssetServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AssetSetAssetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AssetSetAssetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AssetSetAssetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AssetSetAssetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AssetSetAssetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AssetSetAssetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AssetSetAssetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetAssetServiceAsyncClient: The constructed client. + """ + return AssetSetAssetServiceClient.from_service_account_info.__func__(AssetSetAssetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetAssetServiceAsyncClient: The constructed client. + """ + return AssetSetAssetServiceClient.from_service_account_file.__func__(AssetSetAssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AssetSetAssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AssetSetAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetSetAssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AssetSetAssetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetSetAssetServiceTransport, + Callable[..., AssetSetAssetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset set asset service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetSetAssetServiceTransport,Callable[..., AssetSetAssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetSetAssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AssetSetAssetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AssetSetAssetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetSetAssetService", + "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.ads.googleads.v23.services.AssetSetAssetService", + "credentialsType": None, + } + ), + ) + + async def mutate_asset_set_assets( + self, + request: Optional[ + Union[asset_set_asset_service.MutateAssetSetAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[asset_set_asset_service.AssetSetAssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_set_asset_service.MutateAssetSetAssetsResponse: + r"""Creates, updates or removes asset set assets. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAssetSetAssetsRequest, dict]]): + The request object. Request message for + [AssetSetAssetService.MutateAssetSetAssets][google.ads.googleads.v23.services.AssetSetAssetService.MutateAssetSetAssets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose asset set assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AssetSetAssetOperation]`): + Required. The list of operations to + perform on individual asset set assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetSetAssetsResponse: + Response message for an asset set + asset mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_set_asset_service.MutateAssetSetAssetsRequest + ): + request = asset_set_asset_service.MutateAssetSetAssetsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_asset_set_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AssetSetAssetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AssetSetAssetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/asset_set_asset_service/client.py b/google/ads/googleads/v23/services/services/asset_set_asset_service/client.py new file mode 100644 index 000000000..487897ff8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_set_asset_service/client.py @@ -0,0 +1,936 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import asset_set_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetSetAssetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AssetSetAssetServiceGrpcTransport +from .transports.grpc_asyncio import AssetSetAssetServiceGrpcAsyncIOTransport + + +class AssetSetAssetServiceClientMeta(type): + """Metaclass for the AssetSetAssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetSetAssetServiceTransport]] + _transport_registry["grpc"] = AssetSetAssetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AssetSetAssetServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AssetSetAssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetSetAssetServiceClient(metaclass=AssetSetAssetServiceClientMeta): + """Service to manage asset set asset.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetSetAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetSetAssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_path( + customer_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_path( + customer_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_asset_path( + customer_id: str, + asset_set_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset_set_asset string.""" + return "customers/{customer_id}/assetSetAssets/{asset_set_id}~{asset_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_set_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_set_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSetAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AssetSetAssetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AssetSetAssetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AssetSetAssetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AssetSetAssetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AssetSetAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AssetSetAssetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetSetAssetServiceTransport, + Callable[..., AssetSetAssetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset set asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetSetAssetServiceTransport,Callable[..., AssetSetAssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetSetAssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AssetSetAssetServiceClient._read_environment_variables() + self._client_cert_source = ( + AssetSetAssetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = AssetSetAssetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AssetSetAssetServiceTransport + ) + if transport_provided: + # transport is a AssetSetAssetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AssetSetAssetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AssetSetAssetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AssetSetAssetServiceTransport], + Callable[..., AssetSetAssetServiceTransport], + ] = ( + AssetSetAssetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AssetSetAssetServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AssetSetAssetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetSetAssetService", + "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.ads.googleads.v23.services.AssetSetAssetService", + "credentialsType": None, + } + ), + ) + + def mutate_asset_set_assets( + self, + request: Optional[ + Union[asset_set_asset_service.MutateAssetSetAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[asset_set_asset_service.AssetSetAssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_set_asset_service.MutateAssetSetAssetsResponse: + r"""Creates, updates or removes asset set assets. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAssetSetAssetsRequest, dict]): + The request object. Request message for + [AssetSetAssetService.MutateAssetSetAssets][google.ads.googleads.v23.services.AssetSetAssetService.MutateAssetSetAssets]. + customer_id (str): + Required. The ID of the customer + whose asset set assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetSetAssetOperation]): + Required. The list of operations to + perform on individual asset set assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetSetAssetsResponse: + Response message for an asset set + asset mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, asset_set_asset_service.MutateAssetSetAssetsRequest + ): + request = asset_set_asset_service.MutateAssetSetAssetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_set_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AssetSetAssetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AssetSetAssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_set_asset_service/transports/README.rst b/google/ads/googleads/v23/services/services/asset_set_asset_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/asset_set_asset_service/transports/README.rst rename to google/ads/googleads/v23/services/services/asset_set_asset_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/asset_set_asset_service/transports/__init__.py b/google/ads/googleads/v23/services/services/asset_set_asset_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_set_asset_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/asset_set_asset_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_set_asset_service/transports/base.py b/google/ads/googleads/v23/services/services/asset_set_asset_service/transports/base.py new file mode 100644 index 000000000..252eda814 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_set_asset_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import asset_set_asset_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AssetSetAssetServiceTransport(abc.ABC): + """Abstract transport class for AssetSetAssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_set_assets: gapic_v1.method.wrap_method( + self.mutate_asset_set_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_set_assets( + self, + ) -> Callable[ + [asset_set_asset_service.MutateAssetSetAssetsRequest], + Union[ + asset_set_asset_service.MutateAssetSetAssetsResponse, + Awaitable[asset_set_asset_service.MutateAssetSetAssetsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AssetSetAssetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_set_asset_service/transports/grpc.py b/google/ads/googleads/v23/services/services/asset_set_asset_service/transports/grpc.py new file mode 100644 index 000000000..1a3723994 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_set_asset_service/transports/grpc.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import asset_set_asset_service +from .base import AssetSetAssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AssetSetAssetService", + "rpcName": str(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.ads.googleads.v23.services.AssetSetAssetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetSetAssetServiceGrpcTransport(AssetSetAssetServiceTransport): + """gRPC backend transport for AssetSetAssetService. + + Service to manage asset set asset. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_asset_set_assets( + self, + ) -> Callable[ + [asset_set_asset_service.MutateAssetSetAssetsRequest], + asset_set_asset_service.MutateAssetSetAssetsResponse, + ]: + r"""Return a callable for the mutate asset set assets method over gRPC. + + Creates, updates or removes asset set assets. + Operation statuses are returned. + + Returns: + Callable[[~.MutateAssetSetAssetsRequest], + ~.MutateAssetSetAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_set_assets" not in self._stubs: + self._stubs["mutate_asset_set_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetSetAssetService/MutateAssetSetAssets", + request_serializer=asset_set_asset_service.MutateAssetSetAssetsRequest.serialize, + response_deserializer=asset_set_asset_service.MutateAssetSetAssetsResponse.deserialize, + ) + ) + return self._stubs["mutate_asset_set_assets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AssetSetAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_set_asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/asset_set_asset_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..64e2d328d --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_set_asset_service/transports/grpc_asyncio.py @@ -0,0 +1,405 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import asset_set_asset_service +from .base import AssetSetAssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AssetSetAssetService", + "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.ads.googleads.v23.services.AssetSetAssetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetSetAssetServiceGrpcAsyncIOTransport(AssetSetAssetServiceTransport): + """gRPC AsyncIO backend transport for AssetSetAssetService. + + Service to manage asset set asset. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_asset_set_assets( + self, + ) -> Callable[ + [asset_set_asset_service.MutateAssetSetAssetsRequest], + Awaitable[asset_set_asset_service.MutateAssetSetAssetsResponse], + ]: + r"""Return a callable for the mutate asset set assets method over gRPC. + + Creates, updates or removes asset set assets. + Operation statuses are returned. + + Returns: + Callable[[~.MutateAssetSetAssetsRequest], + Awaitable[~.MutateAssetSetAssetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_set_assets" not in self._stubs: + self._stubs["mutate_asset_set_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetSetAssetService/MutateAssetSetAssets", + request_serializer=asset_set_asset_service.MutateAssetSetAssetsRequest.serialize, + response_deserializer=asset_set_asset_service.MutateAssetSetAssetsResponse.deserialize, + ) + ) + return self._stubs["mutate_asset_set_assets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_asset_set_assets: self._wrap_method( + self.mutate_asset_set_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AssetSetAssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/asset_set_service/__init__.py b/google/ads/googleads/v23/services/services/asset_set_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_set_service/__init__.py rename to google/ads/googleads/v23/services/services/asset_set_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_set_service/async_client.py b/google/ads/googleads/v23/services/services/asset_set_service/async_client.py new file mode 100644 index 000000000..aa5b67ea5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_set_service/async_client.py @@ -0,0 +1,412 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetSetServiceTransport, DEFAULT_CLIENT_INFO +from .client import AssetSetServiceClient + +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 AssetSetServiceAsyncClient: + """Service to manage asset set""" + + _client: AssetSetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AssetSetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AssetSetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AssetSetServiceClient._DEFAULT_UNIVERSE + + asset_set_path = staticmethod(AssetSetServiceClient.asset_set_path) + parse_asset_set_path = staticmethod( + AssetSetServiceClient.parse_asset_set_path + ) + common_billing_account_path = staticmethod( + AssetSetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AssetSetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(AssetSetServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + AssetSetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AssetSetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AssetSetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AssetSetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AssetSetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AssetSetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AssetSetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetServiceAsyncClient: The constructed client. + """ + return AssetSetServiceClient.from_service_account_info.__func__(AssetSetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetServiceAsyncClient: The constructed client. + """ + return AssetSetServiceClient.from_service_account_file.__func__(AssetSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AssetSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetSetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AssetSetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetSetServiceTransport, + Callable[..., AssetSetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset set service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetSetServiceTransport,Callable[..., AssetSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AssetSetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AssetSetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetSetService", + "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.ads.googleads.v23.services.AssetSetService", + "credentialsType": None, + } + ), + ) + + async def mutate_asset_sets( + self, + request: Optional[ + Union[asset_set_service.MutateAssetSetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[asset_set_service.AssetSetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_set_service.MutateAssetSetsResponse: + r"""Creates, updates or removes asset sets. Operation + statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAssetSetsRequest, dict]]): + The request object. Request message for + [AssetSetService.MutateAssetSets][google.ads.googleads.v23.services.AssetSetService.MutateAssetSets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose asset sets are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AssetSetOperation]`): + Required. The list of operations to + perform on individual asset sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetSetsResponse: + Response message for an asset set + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, asset_set_service.MutateAssetSetsRequest): + request = asset_set_service.MutateAssetSetsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AssetSetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AssetSetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/asset_set_service/client.py b/google/ads/googleads/v23/services/services/asset_set_service/client.py new file mode 100644 index 000000000..eb52b3b8b --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_set_service/client.py @@ -0,0 +1,880 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AssetSetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AssetSetServiceGrpcTransport +from .transports.grpc_asyncio import AssetSetServiceGrpcAsyncIOTransport + + +class AssetSetServiceClientMeta(type): + """Metaclass for the AssetSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AssetSetServiceTransport]] + _transport_registry["grpc"] = AssetSetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = AssetSetServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AssetSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AssetSetServiceClient(metaclass=AssetSetServiceClientMeta): + """Service to manage asset set""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AssetSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_set_path( + customer_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AssetSetServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AssetSetServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AssetSetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AssetSetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AssetSetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AssetSetServiceTransport, + Callable[..., AssetSetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the asset set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AssetSetServiceTransport,Callable[..., AssetSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AssetSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AssetSetServiceClient._read_environment_variables() + self._client_cert_source = ( + AssetSetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = AssetSetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AssetSetServiceTransport) + if transport_provided: + # transport is a AssetSetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AssetSetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AssetSetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AssetSetServiceTransport], + Callable[..., AssetSetServiceTransport], + ] = ( + AssetSetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AssetSetServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AssetSetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AssetSetService", + "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.ads.googleads.v23.services.AssetSetService", + "credentialsType": None, + } + ), + ) + + def mutate_asset_sets( + self, + request: Optional[ + Union[asset_set_service.MutateAssetSetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[asset_set_service.AssetSetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> asset_set_service.MutateAssetSetsResponse: + r"""Creates, updates or removes asset sets. Operation + statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAssetSetsRequest, dict]): + The request object. Request message for + [AssetSetService.MutateAssetSets][google.ads.googleads.v23.services.AssetSetService.MutateAssetSets]. + customer_id (str): + Required. The ID of the customer + whose asset sets are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetSetOperation]): + Required. The list of operations to + perform on individual asset sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAssetSetsResponse: + Response message for an asset set + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, asset_set_service.MutateAssetSetsRequest): + request = asset_set_service.MutateAssetSetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AssetSetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AssetSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/asset_set_service/transports/README.rst b/google/ads/googleads/v23/services/services/asset_set_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/asset_set_service/transports/README.rst rename to google/ads/googleads/v23/services/services/asset_set_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/asset_set_service/transports/__init__.py b/google/ads/googleads/v23/services/services/asset_set_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/asset_set_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/asset_set_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/asset_set_service/transports/base.py b/google/ads/googleads/v23/services/services/asset_set_service/transports/base.py new file mode 100644 index 000000000..e7ad40d68 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_set_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import asset_set_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AssetSetServiceTransport(abc.ABC): + """Abstract transport class for AssetSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_asset_sets: gapic_v1.method.wrap_method( + self.mutate_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_asset_sets( + self, + ) -> Callable[ + [asset_set_service.MutateAssetSetsRequest], + Union[ + asset_set_service.MutateAssetSetsResponse, + Awaitable[asset_set_service.MutateAssetSetsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AssetSetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_set_service/transports/grpc.py b/google/ads/googleads/v23/services/services/asset_set_service/transports/grpc.py new file mode 100644 index 000000000..150a705fb --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_set_service/transports/grpc.py @@ -0,0 +1,382 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import asset_set_service +from .base import AssetSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AssetSetService", + "rpcName": str(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.ads.googleads.v23.services.AssetSetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetSetServiceGrpcTransport(AssetSetServiceTransport): + """gRPC backend transport for AssetSetService. + + Service to manage asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_asset_sets( + self, + ) -> Callable[ + [asset_set_service.MutateAssetSetsRequest], + asset_set_service.MutateAssetSetsResponse, + ]: + r"""Return a callable for the mutate asset sets method over gRPC. + + Creates, updates or removes asset sets. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAssetSetsRequest], + ~.MutateAssetSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_sets" not in self._stubs: + self._stubs["mutate_asset_sets"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetSetService/MutateAssetSets", + request_serializer=asset_set_service.MutateAssetSetsRequest.serialize, + response_deserializer=asset_set_service.MutateAssetSetsResponse.deserialize, + ) + return self._stubs["mutate_asset_sets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/asset_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/asset_set_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..7341a15b3 --- /dev/null +++ b/google/ads/googleads/v23/services/services/asset_set_service/transports/grpc_asyncio.py @@ -0,0 +1,403 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import asset_set_service +from .base import AssetSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AssetSetService", + "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.ads.googleads.v23.services.AssetSetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AssetSetServiceGrpcAsyncIOTransport(AssetSetServiceTransport): + """gRPC AsyncIO backend transport for AssetSetService. + + Service to manage asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_asset_sets( + self, + ) -> Callable[ + [asset_set_service.MutateAssetSetsRequest], + Awaitable[asset_set_service.MutateAssetSetsResponse], + ]: + r"""Return a callable for the mutate asset sets method over gRPC. + + Creates, updates or removes asset sets. Operation + statuses are returned. + + Returns: + Callable[[~.MutateAssetSetsRequest], + Awaitable[~.MutateAssetSetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_asset_sets" not in self._stubs: + self._stubs["mutate_asset_sets"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AssetSetService/MutateAssetSets", + request_serializer=asset_set_service.MutateAssetSetsRequest.serialize, + response_deserializer=asset_set_service.MutateAssetSetsResponse.deserialize, + ) + return self._stubs["mutate_asset_sets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_asset_sets: self._wrap_method( + self.mutate_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AssetSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/audience_insights_service/__init__.py b/google/ads/googleads/v23/services/services/audience_insights_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/audience_insights_service/__init__.py rename to google/ads/googleads/v23/services/services/audience_insights_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/audience_insights_service/async_client.py b/google/ads/googleads/v23/services/services/audience_insights_service/async_client.py new file mode 100644 index 000000000..15f9bce43 --- /dev/null +++ b/google/ads/googleads/v23/services/services/audience_insights_service/async_client.py @@ -0,0 +1,1247 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.common.types import audience_insights_attribute +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import audience_insights_dimension +from google.ads.googleads.v23.services.types import audience_insights_service +from .transports.base import ( + AudienceInsightsServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AudienceInsightsServiceClient + +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 AudienceInsightsServiceAsyncClient: + """Audience Insights Service helps users find information about + groups of people and how they can be reached with Google Ads. + Accessible to allowlisted customers only. + """ + + _client: AudienceInsightsServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AudienceInsightsServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AudienceInsightsServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AudienceInsightsServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AudienceInsightsServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod( + AudienceInsightsServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AudienceInsightsServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AudienceInsightsServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AudienceInsightsServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AudienceInsightsServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AudienceInsightsServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AudienceInsightsServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AudienceInsightsServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AudienceInsightsServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AudienceInsightsServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceInsightsServiceAsyncClient: The constructed client. + """ + return AudienceInsightsServiceClient.from_service_account_info.__func__(AudienceInsightsServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceInsightsServiceAsyncClient: The constructed client. + """ + return AudienceInsightsServiceClient.from_service_account_file.__func__(AudienceInsightsServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AudienceInsightsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AudienceInsightsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AudienceInsightsServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AudienceInsightsServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AudienceInsightsServiceTransport, + Callable[..., AudienceInsightsServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the audience insights service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AudienceInsightsServiceTransport,Callable[..., AudienceInsightsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AudienceInsightsServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AudienceInsightsServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AudienceInsightsServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AudienceInsightsService", + "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.ads.googleads.v23.services.AudienceInsightsService", + "credentialsType": None, + } + ), + ) + + async def generate_insights_finder_report( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateInsightsFinderReportRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + baseline_audience: Optional[ + audience_insights_service.InsightsAudience + ] = None, + specific_audience: Optional[ + audience_insights_service.InsightsAudience + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateInsightsFinderReportResponse: + r"""Creates a saved report that can be viewed in the Insights Finder + tool. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateInsightsFinderReportRequest, dict]]): + The request object. Request message for + [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v23.services.AudienceInsightsService.GenerateInsightsFinderReport]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + baseline_audience (:class:`google.ads.googleads.v23.services.types.InsightsAudience`): + Required. A baseline audience for + this report, typically all people in a + region. + + This corresponds to the ``baseline_audience`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + specific_audience (:class:`google.ads.googleads.v23.services.types.InsightsAudience`): + Required. The specific audience of + interest for this report. The insights + in the report will be based on + attributes more prevalent in this + audience than in the report's baseline + audience. + + This corresponds to the ``specific_audience`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateInsightsFinderReportResponse: + The response message for + [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v23.services.AudienceInsightsService.GenerateInsightsFinderReport], + containing the shareable URL for the report. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, baseline_audience, specific_audience] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.GenerateInsightsFinderReportRequest, + ): + request = ( + audience_insights_service.GenerateInsightsFinderReportRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if baseline_audience is not None: + request.baseline_audience = baseline_audience + if specific_audience is not None: + request.specific_audience = specific_audience + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_insights_finder_report + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_audience_insights_attributes( + self, + request: Optional[ + Union[ + audience_insights_service.ListAudienceInsightsAttributesRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + dimensions: Optional[ + MutableSequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] + ] = None, + query_text: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.ListAudienceInsightsAttributesResponse: + r"""Searches for audience attributes that can be used to generate + insights. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListAudienceInsightsAttributesRequest, dict]]): + The request object. Request message for + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v23.services.AudienceInsightsService.ListAudienceInsightsAttributes]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + dimensions (:class:`MutableSequence[google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]`): + Required. The types of attributes to be returned. + Supported dimensions are CATEGORY, KNOWLEDGE_GRAPH, + DEVICE, GEO_TARGET_COUNTRY, SUB_COUNTRY_LOCATION, + YOUTUBE_LINEUP, AFFINITY_USER_INTEREST, + IN_MARKET_USER_INTEREST, LIFE_EVENT_USER_INTEREST, + PARENTAL_STATUS, INCOME_RANGE, AGE_RANGE, and GENDER. + + This corresponds to the ``dimensions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + query_text (:class:`str`): + Required. A free text query. If the requested dimensions + include Attributes CATEGORY or KNOWLEDGE_GRAPH, then the + attributes returned for those dimensions will match or + be related to this string. For other dimensions, this + field is ignored and all available attributes are + returned. + + This corresponds to the ``query_text`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListAudienceInsightsAttributesResponse: + Response message for + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v23.services.AudienceInsightsService.ListAudienceInsightsAttributes]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, dimensions, query_text] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.ListAudienceInsightsAttributesRequest, + ): + request = ( + audience_insights_service.ListAudienceInsightsAttributesRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if query_text is not None: + request.query_text = query_text + if dimensions: + request.dimensions.extend(dimensions) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_audience_insights_attributes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_insights_eligible_dates( + self, + request: Optional[ + Union[ + audience_insights_service.ListInsightsEligibleDatesRequest, dict + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.ListInsightsEligibleDatesResponse: + r"""Lists date ranges for which audience insights data can be + requested. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListInsightsEligibleDatesRequest, dict]]): + The request object. Request message for + [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v23.services.AudienceInsightsService.ListInsightsEligibleDates]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListInsightsEligibleDatesResponse: + Response message for + [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v23.services.AudienceInsightsService.ListInsightsEligibleDates]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, audience_insights_service.ListInsightsEligibleDatesRequest + ): + request = ( + audience_insights_service.ListInsightsEligibleDatesRequest( + request + ) + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_insights_eligible_dates + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_audience_composition_insights( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateAudienceCompositionInsightsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + audience: Optional[audience_insights_service.InsightsAudience] = None, + dimensions: Optional[ + MutableSequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateAudienceCompositionInsightsResponse: + r"""Returns a collection of attributes that are represented in an + audience of interest, with metrics that compare each attribute's + share of the audience with its share of a baseline audience. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateAudienceCompositionInsightsRequest, dict]]): + The request object. Request message for + [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + audience (:class:`google.ads.googleads.v23.services.types.InsightsAudience`): + Required. The audience of interest + for which insights are being requested. + + This corresponds to the ``audience`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + dimensions (:class:`MutableSequence[google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]`): + Required. The audience dimensions for which composition + insights should be returned. Supported dimensions are + KNOWLEDGE_GRAPH, GEO_TARGET_COUNTRY, + SUB_COUNTRY_LOCATION, YOUTUBE_CHANNEL, YOUTUBE_LINEUP, + AFFINITY_USER_INTEREST, IN_MARKET_USER_INTEREST, + LIFE_EVENT_USER_INTEREST, PARENTAL_STATUS, INCOME_RANGE, + AGE_RANGE, and GENDER. + + This corresponds to the ``dimensions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateAudienceCompositionInsightsResponse: + Response message for + [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, audience, dimensions] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.GenerateAudienceCompositionInsightsRequest, + ): + request = audience_insights_service.GenerateAudienceCompositionInsightsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if audience is not None: + request.audience = audience + if dimensions: + request.dimensions.extend(dimensions) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_audience_composition_insights + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_audience_definition( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateAudienceDefinitionRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + audience_description: Optional[ + audience_insights_service.InsightsAudienceDescription + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateAudienceDefinitionResponse: + r"""Returns a collection of audience attributes using generative AI + based on the provided audience description. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateAudienceDefinitionRequest, dict]]): + The request object. Request message for + [AudienceInsightsService.GenerateAudienceDefinition][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceDefinition]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + audience_description (:class:`google.ads.googleads.v23.services.types.InsightsAudienceDescription`): + Required. Provide a text description of an audience to + get AI-generated structured suggestions. This can take + around 5 or more seconds to complete Supported marketing + objectives are: AWARENESS, CONSIDERATION and RESEARCH. + Supported dimensions are: AGE_RANGE, GENDER, + PARENTAL_STATUS, AFFINITY_USER_INTEREST, + IN_MARKET_USER_INTEREST, LIFE_EVENT_USER_INTEREST, + CATEGORY and KNOWLEDGE_GRAPH. + + This corresponds to the ``audience_description`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateAudienceDefinitionResponse: + Response message for + [AudienceInsightsService.GenerateAudienceDefinition][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceDefinition]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, audience_description] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, audience_insights_service.GenerateAudienceDefinitionRequest + ): + request = ( + audience_insights_service.GenerateAudienceDefinitionRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if audience_description is not None: + request.audience_description = audience_description + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_audience_definition + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_suggested_targeting_insights( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateSuggestedTargetingInsightsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateSuggestedTargetingInsightsResponse: + r"""Returns a collection of targeting insights (e.g. targetable + audiences) that are relevant to the requested audience. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateSuggestedTargetingInsightsRequest, dict]]): + The request object. Request message for + [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateSuggestedTargetingInsightsResponse: + Response message for + [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.GenerateSuggestedTargetingInsightsRequest, + ): + request = audience_insights_service.GenerateSuggestedTargetingInsightsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_suggested_targeting_insights + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_audience_overlap_insights( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateAudienceOverlapInsightsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + country_location: Optional[criteria.LocationInfo] = None, + primary_attribute: Optional[ + audience_insights_attribute.AudienceInsightsAttribute + ] = None, + dimensions: Optional[ + MutableSequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateAudienceOverlapInsightsResponse: + r"""Returns a collection of audience attributes along with estimates + of the overlap between their potential YouTube reach and that of + a given input attribute. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateAudienceOverlapInsightsRequest, dict]]): + The request object. Request message for + [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + country_location (:class:`google.ads.googleads.v23.common.types.LocationInfo`): + Required. The country in which to + calculate the sizes and overlaps of + audiences. + + This corresponds to the ``country_location`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + primary_attribute (:class:`google.ads.googleads.v23.common.types.AudienceInsightsAttribute`): + Required. The audience attribute that + should be intersected with all other + eligible audiences. This must be an + Affinity or In-Market UserInterest, an + AgeRange or a Gender. + + This corresponds to the ``primary_attribute`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + dimensions (:class:`MutableSequence[google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]`): + Required. The types of attributes of which to calculate + the overlap with the primary_attribute. The values must + be a subset of AFFINITY_USER_INTEREST, + IN_MARKET_USER_INTEREST, AGE_RANGE and GENDER. + + This corresponds to the ``dimensions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateAudienceOverlapInsightsResponse: + Response message for + [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + country_location, + primary_attribute, + dimensions, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.GenerateAudienceOverlapInsightsRequest, + ): + request = audience_insights_service.GenerateAudienceOverlapInsightsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if country_location is not None: + request.country_location = country_location + if primary_attribute is not None: + request.primary_attribute = primary_attribute + if dimensions: + request.dimensions.extend(dimensions) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_audience_overlap_insights + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_targeting_suggestion_metrics( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateTargetingSuggestionMetricsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + audiences: Optional[ + MutableSequence[audience_insights_service.InsightsAudience] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateTargetingSuggestionMetricsResponse: + r"""Returns potential reach metrics for targetable audiences. + + This method helps answer questions like "How many Men aged 18+ + interested in Camping can be reached on YouTube?" + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateTargetingSuggestionMetricsRequest, dict]]): + The request object. Request message for + [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v23.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + audiences (:class:`MutableSequence[google.ads.googleads.v23.services.types.InsightsAudience]`): + Required. Audiences to request + metrics for. + + This corresponds to the ``audiences`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateTargetingSuggestionMetricsResponse: + Response message for + [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v23.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, audiences] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.GenerateTargetingSuggestionMetricsRequest, + ): + request = audience_insights_service.GenerateTargetingSuggestionMetricsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if audiences: + request.audiences.extend(audiences) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_targeting_suggestion_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AudienceInsightsServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AudienceInsightsServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/audience_insights_service/client.py b/google/ads/googleads/v23/services/services/audience_insights_service/client.py new file mode 100644 index 000000000..1fe50ecf3 --- /dev/null +++ b/google/ads/googleads/v23/services/services/audience_insights_service/client.py @@ -0,0 +1,1706 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.common.types import audience_insights_attribute +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import audience_insights_dimension +from google.ads.googleads.v23.services.types import audience_insights_service +from .transports.base import ( + AudienceInsightsServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import AudienceInsightsServiceGrpcTransport +from .transports.grpc_asyncio import AudienceInsightsServiceGrpcAsyncIOTransport + + +class AudienceInsightsServiceClientMeta(type): + """Metaclass for the AudienceInsightsService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AudienceInsightsServiceTransport]] + _transport_registry["grpc"] = AudienceInsightsServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + AudienceInsightsServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AudienceInsightsServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AudienceInsightsServiceClient( + metaclass=AudienceInsightsServiceClientMeta +): + """Audience Insights Service helps users find information about + groups of people and how they can be reached with Google Ads. + Accessible to allowlisted customers only. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceInsightsServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceInsightsServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AudienceInsightsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AudienceInsightsServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AudienceInsightsServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AudienceInsightsServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AudienceInsightsServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AudienceInsightsServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AudienceInsightsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AudienceInsightsServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AudienceInsightsServiceTransport, + Callable[..., AudienceInsightsServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the audience insights service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AudienceInsightsServiceTransport,Callable[..., AudienceInsightsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AudienceInsightsServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AudienceInsightsServiceClient._read_environment_variables() + self._client_cert_source = ( + AudienceInsightsServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + AudienceInsightsServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AudienceInsightsServiceTransport + ) + if transport_provided: + # transport is a AudienceInsightsServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AudienceInsightsServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AudienceInsightsServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AudienceInsightsServiceTransport], + Callable[..., AudienceInsightsServiceTransport], + ] = ( + AudienceInsightsServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., AudienceInsightsServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AudienceInsightsServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AudienceInsightsService", + "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.ads.googleads.v23.services.AudienceInsightsService", + "credentialsType": None, + } + ), + ) + + def generate_insights_finder_report( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateInsightsFinderReportRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + baseline_audience: Optional[ + audience_insights_service.InsightsAudience + ] = None, + specific_audience: Optional[ + audience_insights_service.InsightsAudience + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateInsightsFinderReportResponse: + r"""Creates a saved report that can be viewed in the Insights Finder + tool. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateInsightsFinderReportRequest, dict]): + The request object. Request message for + [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v23.services.AudienceInsightsService.GenerateInsightsFinderReport]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + baseline_audience (google.ads.googleads.v23.services.types.InsightsAudience): + Required. A baseline audience for + this report, typically all people in a + region. + + This corresponds to the ``baseline_audience`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + specific_audience (google.ads.googleads.v23.services.types.InsightsAudience): + Required. The specific audience of + interest for this report. The insights + in the report will be based on + attributes more prevalent in this + audience than in the report's baseline + audience. + + This corresponds to the ``specific_audience`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateInsightsFinderReportResponse: + The response message for + [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v23.services.AudienceInsightsService.GenerateInsightsFinderReport], + containing the shareable URL for the report. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, baseline_audience, specific_audience] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.GenerateInsightsFinderReportRequest, + ): + request = ( + audience_insights_service.GenerateInsightsFinderReportRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if baseline_audience is not None: + request.baseline_audience = baseline_audience + if specific_audience is not None: + request.specific_audience = specific_audience + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_insights_finder_report + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_audience_insights_attributes( + self, + request: Optional[ + Union[ + audience_insights_service.ListAudienceInsightsAttributesRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + dimensions: Optional[ + MutableSequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] + ] = None, + query_text: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.ListAudienceInsightsAttributesResponse: + r"""Searches for audience attributes that can be used to generate + insights. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListAudienceInsightsAttributesRequest, dict]): + The request object. Request message for + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v23.services.AudienceInsightsService.ListAudienceInsightsAttributes]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + dimensions (MutableSequence[google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): + Required. The types of attributes to be returned. + Supported dimensions are CATEGORY, KNOWLEDGE_GRAPH, + DEVICE, GEO_TARGET_COUNTRY, SUB_COUNTRY_LOCATION, + YOUTUBE_LINEUP, AFFINITY_USER_INTEREST, + IN_MARKET_USER_INTEREST, LIFE_EVENT_USER_INTEREST, + PARENTAL_STATUS, INCOME_RANGE, AGE_RANGE, and GENDER. + + This corresponds to the ``dimensions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + query_text (str): + Required. A free text query. If the requested dimensions + include Attributes CATEGORY or KNOWLEDGE_GRAPH, then the + attributes returned for those dimensions will match or + be related to this string. For other dimensions, this + field is ignored and all available attributes are + returned. + + This corresponds to the ``query_text`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListAudienceInsightsAttributesResponse: + Response message for + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v23.services.AudienceInsightsService.ListAudienceInsightsAttributes]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, dimensions, query_text] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.ListAudienceInsightsAttributesRequest, + ): + request = ( + audience_insights_service.ListAudienceInsightsAttributesRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if dimensions is not None: + request.dimensions = dimensions + if query_text is not None: + request.query_text = query_text + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_audience_insights_attributes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_insights_eligible_dates( + self, + request: Optional[ + Union[ + audience_insights_service.ListInsightsEligibleDatesRequest, dict + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.ListInsightsEligibleDatesResponse: + r"""Lists date ranges for which audience insights data can be + requested. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListInsightsEligibleDatesRequest, dict]): + The request object. Request message for + [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v23.services.AudienceInsightsService.ListInsightsEligibleDates]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListInsightsEligibleDatesResponse: + Response message for + [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v23.services.AudienceInsightsService.ListInsightsEligibleDates]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, audience_insights_service.ListInsightsEligibleDatesRequest + ): + request = ( + audience_insights_service.ListInsightsEligibleDatesRequest( + request + ) + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_insights_eligible_dates + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_audience_composition_insights( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateAudienceCompositionInsightsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + audience: Optional[audience_insights_service.InsightsAudience] = None, + dimensions: Optional[ + MutableSequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateAudienceCompositionInsightsResponse: + r"""Returns a collection of attributes that are represented in an + audience of interest, with metrics that compare each attribute's + share of the audience with its share of a baseline audience. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateAudienceCompositionInsightsRequest, dict]): + The request object. Request message for + [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + audience (google.ads.googleads.v23.services.types.InsightsAudience): + Required. The audience of interest + for which insights are being requested. + + This corresponds to the ``audience`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + dimensions (MutableSequence[google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): + Required. The audience dimensions for which composition + insights should be returned. Supported dimensions are + KNOWLEDGE_GRAPH, GEO_TARGET_COUNTRY, + SUB_COUNTRY_LOCATION, YOUTUBE_CHANNEL, YOUTUBE_LINEUP, + AFFINITY_USER_INTEREST, IN_MARKET_USER_INTEREST, + LIFE_EVENT_USER_INTEREST, PARENTAL_STATUS, INCOME_RANGE, + AGE_RANGE, and GENDER. + + This corresponds to the ``dimensions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateAudienceCompositionInsightsResponse: + Response message for + [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, audience, dimensions] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.GenerateAudienceCompositionInsightsRequest, + ): + request = audience_insights_service.GenerateAudienceCompositionInsightsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if audience is not None: + request.audience = audience + if dimensions is not None: + request.dimensions = dimensions + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_audience_composition_insights + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_audience_definition( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateAudienceDefinitionRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + audience_description: Optional[ + audience_insights_service.InsightsAudienceDescription + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateAudienceDefinitionResponse: + r"""Returns a collection of audience attributes using generative AI + based on the provided audience description. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateAudienceDefinitionRequest, dict]): + The request object. Request message for + [AudienceInsightsService.GenerateAudienceDefinition][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceDefinition]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + audience_description (google.ads.googleads.v23.services.types.InsightsAudienceDescription): + Required. Provide a text description of an audience to + get AI-generated structured suggestions. This can take + around 5 or more seconds to complete Supported marketing + objectives are: AWARENESS, CONSIDERATION and RESEARCH. + Supported dimensions are: AGE_RANGE, GENDER, + PARENTAL_STATUS, AFFINITY_USER_INTEREST, + IN_MARKET_USER_INTEREST, LIFE_EVENT_USER_INTEREST, + CATEGORY and KNOWLEDGE_GRAPH. + + This corresponds to the ``audience_description`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateAudienceDefinitionResponse: + Response message for + [AudienceInsightsService.GenerateAudienceDefinition][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceDefinition]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, audience_description] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, audience_insights_service.GenerateAudienceDefinitionRequest + ): + request = ( + audience_insights_service.GenerateAudienceDefinitionRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if audience_description is not None: + request.audience_description = audience_description + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_audience_definition + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_suggested_targeting_insights( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateSuggestedTargetingInsightsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateSuggestedTargetingInsightsResponse: + r"""Returns a collection of targeting insights (e.g. targetable + audiences) that are relevant to the requested audience. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateSuggestedTargetingInsightsRequest, dict]): + The request object. Request message for + [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateSuggestedTargetingInsightsResponse: + Response message for + [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.GenerateSuggestedTargetingInsightsRequest, + ): + request = audience_insights_service.GenerateSuggestedTargetingInsightsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_suggested_targeting_insights + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_audience_overlap_insights( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateAudienceOverlapInsightsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + country_location: Optional[criteria.LocationInfo] = None, + primary_attribute: Optional[ + audience_insights_attribute.AudienceInsightsAttribute + ] = None, + dimensions: Optional[ + MutableSequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateAudienceOverlapInsightsResponse: + r"""Returns a collection of audience attributes along with estimates + of the overlap between their potential YouTube reach and that of + a given input attribute. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateAudienceOverlapInsightsRequest, dict]): + The request object. Request message for + [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + country_location (google.ads.googleads.v23.common.types.LocationInfo): + Required. The country in which to + calculate the sizes and overlaps of + audiences. + + This corresponds to the ``country_location`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + primary_attribute (google.ads.googleads.v23.common.types.AudienceInsightsAttribute): + Required. The audience attribute that + should be intersected with all other + eligible audiences. This must be an + Affinity or In-Market UserInterest, an + AgeRange or a Gender. + + This corresponds to the ``primary_attribute`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + dimensions (MutableSequence[google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): + Required. The types of attributes of which to calculate + the overlap with the primary_attribute. The values must + be a subset of AFFINITY_USER_INTEREST, + IN_MARKET_USER_INTEREST, AGE_RANGE and GENDER. + + This corresponds to the ``dimensions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateAudienceOverlapInsightsResponse: + Response message for + [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + country_location, + primary_attribute, + dimensions, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.GenerateAudienceOverlapInsightsRequest, + ): + request = audience_insights_service.GenerateAudienceOverlapInsightsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if country_location is not None: + request.country_location = country_location + if primary_attribute is not None: + request.primary_attribute = primary_attribute + if dimensions is not None: + request.dimensions = dimensions + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_audience_overlap_insights + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_targeting_suggestion_metrics( + self, + request: Optional[ + Union[ + audience_insights_service.GenerateTargetingSuggestionMetricsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + audiences: Optional[ + MutableSequence[audience_insights_service.InsightsAudience] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_insights_service.GenerateTargetingSuggestionMetricsResponse: + r"""Returns potential reach metrics for targetable audiences. + + This method helps answer questions like "How many Men aged 18+ + interested in Camping can be reached on YouTube?" + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateTargetingSuggestionMetricsRequest, dict]): + The request object. Request message for + [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v23.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + audiences (MutableSequence[google.ads.googleads.v23.services.types.InsightsAudience]): + Required. Audiences to request + metrics for. + + This corresponds to the ``audiences`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateTargetingSuggestionMetricsResponse: + Response message for + [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v23.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, audiences] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + audience_insights_service.GenerateTargetingSuggestionMetricsRequest, + ): + request = audience_insights_service.GenerateTargetingSuggestionMetricsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if audiences is not None: + request.audiences = audiences + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_targeting_suggestion_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AudienceInsightsServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AudienceInsightsServiceClient",) diff --git a/google/ads/googleads/v19/services/services/audience_insights_service/transports/README.rst b/google/ads/googleads/v23/services/services/audience_insights_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/audience_insights_service/transports/README.rst rename to google/ads/googleads/v23/services/services/audience_insights_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/audience_insights_service/transports/__init__.py b/google/ads/googleads/v23/services/services/audience_insights_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/audience_insights_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/audience_insights_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/audience_insights_service/transports/base.py b/google/ads/googleads/v23/services/services/audience_insights_service/transports/base.py new file mode 100644 index 000000000..d9b9288db --- /dev/null +++ b/google/ads/googleads/v23/services/services/audience_insights_service/transports/base.py @@ -0,0 +1,308 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import audience_insights_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AudienceInsightsServiceTransport(abc.ABC): + """Abstract transport class for AudienceInsightsService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.generate_insights_finder_report: gapic_v1.method.wrap_method( + self.generate_insights_finder_report, + default_timeout=None, + client_info=client_info, + ), + self.list_audience_insights_attributes: gapic_v1.method.wrap_method( + self.list_audience_insights_attributes, + default_timeout=None, + client_info=client_info, + ), + self.list_insights_eligible_dates: gapic_v1.method.wrap_method( + self.list_insights_eligible_dates, + default_timeout=None, + client_info=client_info, + ), + self.generate_audience_composition_insights: gapic_v1.method.wrap_method( + self.generate_audience_composition_insights, + default_timeout=None, + client_info=client_info, + ), + self.generate_audience_definition: gapic_v1.method.wrap_method( + self.generate_audience_definition, + default_timeout=None, + client_info=client_info, + ), + self.generate_suggested_targeting_insights: gapic_v1.method.wrap_method( + self.generate_suggested_targeting_insights, + default_timeout=None, + client_info=client_info, + ), + self.generate_audience_overlap_insights: gapic_v1.method.wrap_method( + self.generate_audience_overlap_insights, + default_timeout=None, + client_info=client_info, + ), + self.generate_targeting_suggestion_metrics: gapic_v1.method.wrap_method( + self.generate_targeting_suggestion_metrics, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def generate_insights_finder_report( + self, + ) -> Callable[ + [audience_insights_service.GenerateInsightsFinderReportRequest], + Union[ + audience_insights_service.GenerateInsightsFinderReportResponse, + Awaitable[ + audience_insights_service.GenerateInsightsFinderReportResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def list_audience_insights_attributes( + self, + ) -> Callable[ + [audience_insights_service.ListAudienceInsightsAttributesRequest], + Union[ + audience_insights_service.ListAudienceInsightsAttributesResponse, + Awaitable[ + audience_insights_service.ListAudienceInsightsAttributesResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def list_insights_eligible_dates( + self, + ) -> Callable[ + [audience_insights_service.ListInsightsEligibleDatesRequest], + Union[ + audience_insights_service.ListInsightsEligibleDatesResponse, + Awaitable[ + audience_insights_service.ListInsightsEligibleDatesResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def generate_audience_composition_insights( + self, + ) -> Callable[ + [audience_insights_service.GenerateAudienceCompositionInsightsRequest], + Union[ + audience_insights_service.GenerateAudienceCompositionInsightsResponse, + Awaitable[ + audience_insights_service.GenerateAudienceCompositionInsightsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def generate_audience_definition( + self, + ) -> Callable[ + [audience_insights_service.GenerateAudienceDefinitionRequest], + Union[ + audience_insights_service.GenerateAudienceDefinitionResponse, + Awaitable[ + audience_insights_service.GenerateAudienceDefinitionResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def generate_suggested_targeting_insights( + self, + ) -> Callable[ + [audience_insights_service.GenerateSuggestedTargetingInsightsRequest], + Union[ + audience_insights_service.GenerateSuggestedTargetingInsightsResponse, + Awaitable[ + audience_insights_service.GenerateSuggestedTargetingInsightsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def generate_audience_overlap_insights( + self, + ) -> Callable[ + [audience_insights_service.GenerateAudienceOverlapInsightsRequest], + Union[ + audience_insights_service.GenerateAudienceOverlapInsightsResponse, + Awaitable[ + audience_insights_service.GenerateAudienceOverlapInsightsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def generate_targeting_suggestion_metrics( + self, + ) -> Callable[ + [audience_insights_service.GenerateTargetingSuggestionMetricsRequest], + Union[ + audience_insights_service.GenerateTargetingSuggestionMetricsResponse, + Awaitable[ + audience_insights_service.GenerateTargetingSuggestionMetricsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AudienceInsightsServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/audience_insights_service/transports/grpc.py b/google/ads/googleads/v23/services/services/audience_insights_service/transports/grpc.py new file mode 100644 index 000000000..3e99441ff --- /dev/null +++ b/google/ads/googleads/v23/services/services/audience_insights_service/transports/grpc.py @@ -0,0 +1,660 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import audience_insights_service +from .base import AudienceInsightsServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AudienceInsightsService", + "rpcName": str(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.ads.googleads.v23.services.AudienceInsightsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AudienceInsightsServiceGrpcTransport(AudienceInsightsServiceTransport): + """gRPC backend transport for AudienceInsightsService. + + Audience Insights Service helps users find information about + groups of people and how they can be reached with Google Ads. + Accessible to allowlisted customers only. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def generate_insights_finder_report( + self, + ) -> Callable[ + [audience_insights_service.GenerateInsightsFinderReportRequest], + audience_insights_service.GenerateInsightsFinderReportResponse, + ]: + r"""Return a callable for the generate insights finder + report method over gRPC. + + Creates a saved report that can be viewed in the Insights Finder + tool. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateInsightsFinderReportRequest], + ~.GenerateInsightsFinderReportResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_insights_finder_report" not in self._stubs: + self._stubs["generate_insights_finder_report"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateInsightsFinderReport", + request_serializer=audience_insights_service.GenerateInsightsFinderReportRequest.serialize, + response_deserializer=audience_insights_service.GenerateInsightsFinderReportResponse.deserialize, + ) + ) + return self._stubs["generate_insights_finder_report"] + + @property + def list_audience_insights_attributes( + self, + ) -> Callable[ + [audience_insights_service.ListAudienceInsightsAttributesRequest], + audience_insights_service.ListAudienceInsightsAttributesResponse, + ]: + r"""Return a callable for the list audience insights + attributes method over gRPC. + + Searches for audience attributes that can be used to generate + insights. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListAudienceInsightsAttributesRequest], + ~.ListAudienceInsightsAttributesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_audience_insights_attributes" not in self._stubs: + self._stubs["list_audience_insights_attributes"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/ListAudienceInsightsAttributes", + request_serializer=audience_insights_service.ListAudienceInsightsAttributesRequest.serialize, + response_deserializer=audience_insights_service.ListAudienceInsightsAttributesResponse.deserialize, + ) + ) + return self._stubs["list_audience_insights_attributes"] + + @property + def list_insights_eligible_dates( + self, + ) -> Callable[ + [audience_insights_service.ListInsightsEligibleDatesRequest], + audience_insights_service.ListInsightsEligibleDatesResponse, + ]: + r"""Return a callable for the list insights eligible dates method over gRPC. + + Lists date ranges for which audience insights data can be + requested. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListInsightsEligibleDatesRequest], + ~.ListInsightsEligibleDatesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_insights_eligible_dates" not in self._stubs: + self._stubs["list_insights_eligible_dates"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/ListInsightsEligibleDates", + request_serializer=audience_insights_service.ListInsightsEligibleDatesRequest.serialize, + response_deserializer=audience_insights_service.ListInsightsEligibleDatesResponse.deserialize, + ) + ) + return self._stubs["list_insights_eligible_dates"] + + @property + def generate_audience_composition_insights( + self, + ) -> Callable[ + [audience_insights_service.GenerateAudienceCompositionInsightsRequest], + audience_insights_service.GenerateAudienceCompositionInsightsResponse, + ]: + r"""Return a callable for the generate audience composition + insights method over gRPC. + + Returns a collection of attributes that are represented in an + audience of interest, with metrics that compare each attribute's + share of the audience with its share of a baseline audience. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateAudienceCompositionInsightsRequest], + ~.GenerateAudienceCompositionInsightsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_audience_composition_insights" not in self._stubs: + self._stubs["generate_audience_composition_insights"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateAudienceCompositionInsights", + request_serializer=audience_insights_service.GenerateAudienceCompositionInsightsRequest.serialize, + response_deserializer=audience_insights_service.GenerateAudienceCompositionInsightsResponse.deserialize, + ) + ) + return self._stubs["generate_audience_composition_insights"] + + @property + def generate_audience_definition( + self, + ) -> Callable[ + [audience_insights_service.GenerateAudienceDefinitionRequest], + audience_insights_service.GenerateAudienceDefinitionResponse, + ]: + r"""Return a callable for the generate audience definition method over gRPC. + + Returns a collection of audience attributes using generative AI + based on the provided audience description. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateAudienceDefinitionRequest], + ~.GenerateAudienceDefinitionResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_audience_definition" not in self._stubs: + self._stubs["generate_audience_definition"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateAudienceDefinition", + request_serializer=audience_insights_service.GenerateAudienceDefinitionRequest.serialize, + response_deserializer=audience_insights_service.GenerateAudienceDefinitionResponse.deserialize, + ) + ) + return self._stubs["generate_audience_definition"] + + @property + def generate_suggested_targeting_insights( + self, + ) -> Callable[ + [audience_insights_service.GenerateSuggestedTargetingInsightsRequest], + audience_insights_service.GenerateSuggestedTargetingInsightsResponse, + ]: + r"""Return a callable for the generate suggested targeting + insights method over gRPC. + + Returns a collection of targeting insights (e.g. targetable + audiences) that are relevant to the requested audience. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateSuggestedTargetingInsightsRequest], + ~.GenerateSuggestedTargetingInsightsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_suggested_targeting_insights" not in self._stubs: + self._stubs["generate_suggested_targeting_insights"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateSuggestedTargetingInsights", + request_serializer=audience_insights_service.GenerateSuggestedTargetingInsightsRequest.serialize, + response_deserializer=audience_insights_service.GenerateSuggestedTargetingInsightsResponse.deserialize, + ) + ) + return self._stubs["generate_suggested_targeting_insights"] + + @property + def generate_audience_overlap_insights( + self, + ) -> Callable[ + [audience_insights_service.GenerateAudienceOverlapInsightsRequest], + audience_insights_service.GenerateAudienceOverlapInsightsResponse, + ]: + r"""Return a callable for the generate audience overlap + insights method over gRPC. + + Returns a collection of audience attributes along with estimates + of the overlap between their potential YouTube reach and that of + a given input attribute. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateAudienceOverlapInsightsRequest], + ~.GenerateAudienceOverlapInsightsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_audience_overlap_insights" not in self._stubs: + self._stubs["generate_audience_overlap_insights"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateAudienceOverlapInsights", + request_serializer=audience_insights_service.GenerateAudienceOverlapInsightsRequest.serialize, + response_deserializer=audience_insights_service.GenerateAudienceOverlapInsightsResponse.deserialize, + ) + ) + return self._stubs["generate_audience_overlap_insights"] + + @property + def generate_targeting_suggestion_metrics( + self, + ) -> Callable[ + [audience_insights_service.GenerateTargetingSuggestionMetricsRequest], + audience_insights_service.GenerateTargetingSuggestionMetricsResponse, + ]: + r"""Return a callable for the generate targeting suggestion + metrics method over gRPC. + + Returns potential reach metrics for targetable audiences. + + This method helps answer questions like "How many Men aged 18+ + interested in Camping can be reached on YouTube?" + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateTargetingSuggestionMetricsRequest], + ~.GenerateTargetingSuggestionMetricsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_targeting_suggestion_metrics" not in self._stubs: + self._stubs["generate_targeting_suggestion_metrics"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateTargetingSuggestionMetrics", + request_serializer=audience_insights_service.GenerateTargetingSuggestionMetricsRequest.serialize, + response_deserializer=audience_insights_service.GenerateTargetingSuggestionMetricsResponse.deserialize, + ) + ) + return self._stubs["generate_targeting_suggestion_metrics"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AudienceInsightsServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/audience_insights_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/audience_insights_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..c23c6b1fa --- /dev/null +++ b/google/ads/googleads/v23/services/services/audience_insights_service/transports/grpc_asyncio.py @@ -0,0 +1,730 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import audience_insights_service +from .base import AudienceInsightsServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AudienceInsightsService", + "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.ads.googleads.v23.services.AudienceInsightsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AudienceInsightsServiceGrpcAsyncIOTransport( + AudienceInsightsServiceTransport +): + """gRPC AsyncIO backend transport for AudienceInsightsService. + + Audience Insights Service helps users find information about + groups of people and how they can be reached with Google Ads. + Accessible to allowlisted customers only. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def generate_insights_finder_report( + self, + ) -> Callable[ + [audience_insights_service.GenerateInsightsFinderReportRequest], + Awaitable[ + audience_insights_service.GenerateInsightsFinderReportResponse + ], + ]: + r"""Return a callable for the generate insights finder + report method over gRPC. + + Creates a saved report that can be viewed in the Insights Finder + tool. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateInsightsFinderReportRequest], + Awaitable[~.GenerateInsightsFinderReportResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_insights_finder_report" not in self._stubs: + self._stubs["generate_insights_finder_report"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateInsightsFinderReport", + request_serializer=audience_insights_service.GenerateInsightsFinderReportRequest.serialize, + response_deserializer=audience_insights_service.GenerateInsightsFinderReportResponse.deserialize, + ) + ) + return self._stubs["generate_insights_finder_report"] + + @property + def list_audience_insights_attributes( + self, + ) -> Callable[ + [audience_insights_service.ListAudienceInsightsAttributesRequest], + Awaitable[ + audience_insights_service.ListAudienceInsightsAttributesResponse + ], + ]: + r"""Return a callable for the list audience insights + attributes method over gRPC. + + Searches for audience attributes that can be used to generate + insights. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListAudienceInsightsAttributesRequest], + Awaitable[~.ListAudienceInsightsAttributesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_audience_insights_attributes" not in self._stubs: + self._stubs["list_audience_insights_attributes"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/ListAudienceInsightsAttributes", + request_serializer=audience_insights_service.ListAudienceInsightsAttributesRequest.serialize, + response_deserializer=audience_insights_service.ListAudienceInsightsAttributesResponse.deserialize, + ) + ) + return self._stubs["list_audience_insights_attributes"] + + @property + def list_insights_eligible_dates( + self, + ) -> Callable[ + [audience_insights_service.ListInsightsEligibleDatesRequest], + Awaitable[audience_insights_service.ListInsightsEligibleDatesResponse], + ]: + r"""Return a callable for the list insights eligible dates method over gRPC. + + Lists date ranges for which audience insights data can be + requested. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListInsightsEligibleDatesRequest], + Awaitable[~.ListInsightsEligibleDatesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_insights_eligible_dates" not in self._stubs: + self._stubs["list_insights_eligible_dates"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/ListInsightsEligibleDates", + request_serializer=audience_insights_service.ListInsightsEligibleDatesRequest.serialize, + response_deserializer=audience_insights_service.ListInsightsEligibleDatesResponse.deserialize, + ) + ) + return self._stubs["list_insights_eligible_dates"] + + @property + def generate_audience_composition_insights( + self, + ) -> Callable[ + [audience_insights_service.GenerateAudienceCompositionInsightsRequest], + Awaitable[ + audience_insights_service.GenerateAudienceCompositionInsightsResponse + ], + ]: + r"""Return a callable for the generate audience composition + insights method over gRPC. + + Returns a collection of attributes that are represented in an + audience of interest, with metrics that compare each attribute's + share of the audience with its share of a baseline audience. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateAudienceCompositionInsightsRequest], + Awaitable[~.GenerateAudienceCompositionInsightsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_audience_composition_insights" not in self._stubs: + self._stubs["generate_audience_composition_insights"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateAudienceCompositionInsights", + request_serializer=audience_insights_service.GenerateAudienceCompositionInsightsRequest.serialize, + response_deserializer=audience_insights_service.GenerateAudienceCompositionInsightsResponse.deserialize, + ) + ) + return self._stubs["generate_audience_composition_insights"] + + @property + def generate_audience_definition( + self, + ) -> Callable[ + [audience_insights_service.GenerateAudienceDefinitionRequest], + Awaitable[audience_insights_service.GenerateAudienceDefinitionResponse], + ]: + r"""Return a callable for the generate audience definition method over gRPC. + + Returns a collection of audience attributes using generative AI + based on the provided audience description. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateAudienceDefinitionRequest], + Awaitable[~.GenerateAudienceDefinitionResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_audience_definition" not in self._stubs: + self._stubs["generate_audience_definition"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateAudienceDefinition", + request_serializer=audience_insights_service.GenerateAudienceDefinitionRequest.serialize, + response_deserializer=audience_insights_service.GenerateAudienceDefinitionResponse.deserialize, + ) + ) + return self._stubs["generate_audience_definition"] + + @property + def generate_suggested_targeting_insights( + self, + ) -> Callable[ + [audience_insights_service.GenerateSuggestedTargetingInsightsRequest], + Awaitable[ + audience_insights_service.GenerateSuggestedTargetingInsightsResponse + ], + ]: + r"""Return a callable for the generate suggested targeting + insights method over gRPC. + + Returns a collection of targeting insights (e.g. targetable + audiences) that are relevant to the requested audience. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateSuggestedTargetingInsightsRequest], + Awaitable[~.GenerateSuggestedTargetingInsightsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_suggested_targeting_insights" not in self._stubs: + self._stubs["generate_suggested_targeting_insights"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateSuggestedTargetingInsights", + request_serializer=audience_insights_service.GenerateSuggestedTargetingInsightsRequest.serialize, + response_deserializer=audience_insights_service.GenerateSuggestedTargetingInsightsResponse.deserialize, + ) + ) + return self._stubs["generate_suggested_targeting_insights"] + + @property + def generate_audience_overlap_insights( + self, + ) -> Callable[ + [audience_insights_service.GenerateAudienceOverlapInsightsRequest], + Awaitable[ + audience_insights_service.GenerateAudienceOverlapInsightsResponse + ], + ]: + r"""Return a callable for the generate audience overlap + insights method over gRPC. + + Returns a collection of audience attributes along with estimates + of the overlap between their potential YouTube reach and that of + a given input attribute. + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateAudienceOverlapInsightsRequest], + Awaitable[~.GenerateAudienceOverlapInsightsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_audience_overlap_insights" not in self._stubs: + self._stubs["generate_audience_overlap_insights"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateAudienceOverlapInsights", + request_serializer=audience_insights_service.GenerateAudienceOverlapInsightsRequest.serialize, + response_deserializer=audience_insights_service.GenerateAudienceOverlapInsightsResponse.deserialize, + ) + ) + return self._stubs["generate_audience_overlap_insights"] + + @property + def generate_targeting_suggestion_metrics( + self, + ) -> Callable[ + [audience_insights_service.GenerateTargetingSuggestionMetricsRequest], + Awaitable[ + audience_insights_service.GenerateTargetingSuggestionMetricsResponse + ], + ]: + r"""Return a callable for the generate targeting suggestion + metrics method over gRPC. + + Returns potential reach metrics for targetable audiences. + + This method helps answer questions like "How many Men aged 18+ + interested in Camping can be reached on YouTube?" + + List of thrown errors: `AudienceInsightsError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateTargetingSuggestionMetricsRequest], + Awaitable[~.GenerateTargetingSuggestionMetricsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_targeting_suggestion_metrics" not in self._stubs: + self._stubs["generate_targeting_suggestion_metrics"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceInsightsService/GenerateTargetingSuggestionMetrics", + request_serializer=audience_insights_service.GenerateTargetingSuggestionMetricsRequest.serialize, + response_deserializer=audience_insights_service.GenerateTargetingSuggestionMetricsResponse.deserialize, + ) + ) + return self._stubs["generate_targeting_suggestion_metrics"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.generate_insights_finder_report: self._wrap_method( + self.generate_insights_finder_report, + default_timeout=None, + client_info=client_info, + ), + self.list_audience_insights_attributes: self._wrap_method( + self.list_audience_insights_attributes, + default_timeout=None, + client_info=client_info, + ), + self.list_insights_eligible_dates: self._wrap_method( + self.list_insights_eligible_dates, + default_timeout=None, + client_info=client_info, + ), + self.generate_audience_composition_insights: self._wrap_method( + self.generate_audience_composition_insights, + default_timeout=None, + client_info=client_info, + ), + self.generate_audience_definition: self._wrap_method( + self.generate_audience_definition, + default_timeout=None, + client_info=client_info, + ), + self.generate_suggested_targeting_insights: self._wrap_method( + self.generate_suggested_targeting_insights, + default_timeout=None, + client_info=client_info, + ), + self.generate_audience_overlap_insights: self._wrap_method( + self.generate_audience_overlap_insights, + default_timeout=None, + client_info=client_info, + ), + self.generate_targeting_suggestion_metrics: self._wrap_method( + self.generate_targeting_suggestion_metrics, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AudienceInsightsServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/audience_service/__init__.py b/google/ads/googleads/v23/services/services/audience_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/audience_service/__init__.py rename to google/ads/googleads/v23/services/services/audience_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/audience_service/async_client.py b/google/ads/googleads/v23/services/services/audience_service/async_client.py new file mode 100644 index 000000000..80a2908ec --- /dev/null +++ b/google/ads/googleads/v23/services/services/audience_service/async_client.py @@ -0,0 +1,427 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import audience_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AudienceServiceTransport, DEFAULT_CLIENT_INFO +from .client import AudienceServiceClient + +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 AudienceServiceAsyncClient: + """Service to manage audiences.""" + + _client: AudienceServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = AudienceServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = AudienceServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + AudienceServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = AudienceServiceClient._DEFAULT_UNIVERSE + + asset_group_path = staticmethod(AudienceServiceClient.asset_group_path) + parse_asset_group_path = staticmethod( + AudienceServiceClient.parse_asset_group_path + ) + audience_path = staticmethod(AudienceServiceClient.audience_path) + parse_audience_path = staticmethod( + AudienceServiceClient.parse_audience_path + ) + detailed_demographic_path = staticmethod( + AudienceServiceClient.detailed_demographic_path + ) + parse_detailed_demographic_path = staticmethod( + AudienceServiceClient.parse_detailed_demographic_path + ) + life_event_path = staticmethod(AudienceServiceClient.life_event_path) + parse_life_event_path = staticmethod( + AudienceServiceClient.parse_life_event_path + ) + common_billing_account_path = staticmethod( + AudienceServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AudienceServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(AudienceServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + AudienceServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AudienceServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AudienceServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AudienceServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AudienceServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AudienceServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AudienceServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceServiceAsyncClient: The constructed client. + """ + return AudienceServiceClient.from_service_account_info.__func__(AudienceServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceServiceAsyncClient: The constructed client. + """ + return AudienceServiceClient.from_service_account_file.__func__(AudienceServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AudienceServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AudienceServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AudienceServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = AudienceServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AudienceServiceTransport, + Callable[..., AudienceServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the audience service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AudienceServiceTransport,Callable[..., AudienceServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AudienceServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AudienceServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AudienceServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AudienceService", + "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.ads.googleads.v23.services.AudienceService", + "credentialsType": None, + } + ), + ) + + async def mutate_audiences( + self, + request: Optional[ + Union[audience_service.MutateAudiencesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[audience_service.AudienceOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_service.MutateAudiencesResponse: + r"""Creates audiences. Operation statuses are returned. + + List of thrown errors: `AudienceError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateAudiencesRequest, dict]]): + The request object. Request message for + [AudienceService.MutateAudiences][google.ads.googleads.v23.services.AudienceService.MutateAudiences]. + customer_id (:class:`str`): + Required. The ID of the customer + whose audiences are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.AudienceOperation]`): + Required. The list of operations to + perform on individual audiences. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAudiencesResponse: + Response message for an audience + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, audience_service.MutateAudiencesRequest): + request = audience_service.MutateAudiencesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_audiences + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "AudienceServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AudienceServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/audience_service/client.py b/google/ads/googleads/v23/services/services/audience_service/client.py new file mode 100644 index 000000000..c71b4e28f --- /dev/null +++ b/google/ads/googleads/v23/services/services/audience_service/client.py @@ -0,0 +1,939 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import audience_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import AudienceServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import AudienceServiceGrpcTransport +from .transports.grpc_asyncio import AudienceServiceGrpcAsyncIOTransport + + +class AudienceServiceClientMeta(type): + """Metaclass for the AudienceService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AudienceServiceTransport]] + _transport_registry["grpc"] = AudienceServiceGrpcTransport + _transport_registry["grpc_asyncio"] = AudienceServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AudienceServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AudienceServiceClient(metaclass=AudienceServiceClientMeta): + """Service to manage audiences.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AudienceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AudienceServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AudienceServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_group_path( + customer_id: str, + asset_group_id: str, + ) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def audience_path( + customer_id: str, + audience_id: str, + ) -> str: + """Returns a fully-qualified audience string.""" + return "customers/{customer_id}/audiences/{audience_id}".format( + customer_id=customer_id, + audience_id=audience_id, + ) + + @staticmethod + def parse_audience_path(path: str) -> Dict[str, str]: + """Parses a audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/audiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def detailed_demographic_path( + customer_id: str, + detailed_demographic_id: str, + ) -> str: + """Returns a fully-qualified detailed_demographic string.""" + return "customers/{customer_id}/detailedDemographics/{detailed_demographic_id}".format( + customer_id=customer_id, + detailed_demographic_id=detailed_demographic_id, + ) + + @staticmethod + def parse_detailed_demographic_path(path: str) -> Dict[str, str]: + """Parses a detailed_demographic path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/detailedDemographics/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def life_event_path( + customer_id: str, + life_event_id: str, + ) -> str: + """Returns a fully-qualified life_event string.""" + return "customers/{customer_id}/lifeEvents/{life_event_id}".format( + customer_id=customer_id, + life_event_id=life_event_id, + ) + + @staticmethod + def parse_life_event_path(path: str) -> Dict[str, str]: + """Parses a life_event path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/lifeEvents/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = AudienceServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = AudienceServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = AudienceServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = AudienceServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + AudienceServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = AudienceServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AudienceServiceTransport, + Callable[..., AudienceServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the audience service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AudienceServiceTransport,Callable[..., AudienceServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AudienceServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = AudienceServiceClient._read_environment_variables() + self._client_cert_source = ( + AudienceServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = AudienceServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, AudienceServiceTransport) + if transport_provided: + # transport is a AudienceServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(AudienceServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AudienceServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AudienceServiceTransport], + Callable[..., AudienceServiceTransport], + ] = ( + AudienceServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., AudienceServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AudienceServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AudienceService", + "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.ads.googleads.v23.services.AudienceService", + "credentialsType": None, + } + ), + ) + + def mutate_audiences( + self, + request: Optional[ + Union[audience_service.MutateAudiencesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[audience_service.AudienceOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> audience_service.MutateAudiencesResponse: + r"""Creates audiences. Operation statuses are returned. + + List of thrown errors: `AudienceError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateAudiencesRequest, dict]): + The request object. Request message for + [AudienceService.MutateAudiences][google.ads.googleads.v23.services.AudienceService.MutateAudiences]. + customer_id (str): + Required. The ID of the customer + whose audiences are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.AudienceOperation]): + Required. The list of operations to + perform on individual audiences. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateAudiencesResponse: + Response message for an audience + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, audience_service.MutateAudiencesRequest): + request = audience_service.MutateAudiencesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_audiences] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AudienceServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AudienceServiceClient",) diff --git a/google/ads/googleads/v19/services/services/audience_service/transports/README.rst b/google/ads/googleads/v23/services/services/audience_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/audience_service/transports/README.rst rename to google/ads/googleads/v23/services/services/audience_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/audience_service/transports/__init__.py b/google/ads/googleads/v23/services/services/audience_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/audience_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/audience_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/audience_service/transports/base.py b/google/ads/googleads/v23/services/services/audience_service/transports/base.py new file mode 100644 index 000000000..8f12ac3db --- /dev/null +++ b/google/ads/googleads/v23/services/services/audience_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import audience_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AudienceServiceTransport(abc.ABC): + """Abstract transport class for AudienceService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_audiences: gapic_v1.method.wrap_method( + self.mutate_audiences, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_audiences( + self, + ) -> Callable[ + [audience_service.MutateAudiencesRequest], + Union[ + audience_service.MutateAudiencesResponse, + Awaitable[audience_service.MutateAudiencesResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AudienceServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/audience_service/transports/grpc.py b/google/ads/googleads/v23/services/services/audience_service/transports/grpc.py new file mode 100644 index 000000000..1f35c896e --- /dev/null +++ b/google/ads/googleads/v23/services/services/audience_service/transports/grpc.py @@ -0,0 +1,383 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import audience_service +from .base import AudienceServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AudienceService", + "rpcName": str(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.ads.googleads.v23.services.AudienceService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AudienceServiceGrpcTransport(AudienceServiceTransport): + """gRPC backend transport for AudienceService. + + Service to manage audiences. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_audiences( + self, + ) -> Callable[ + [audience_service.MutateAudiencesRequest], + audience_service.MutateAudiencesResponse, + ]: + r"""Return a callable for the mutate audiences method over gRPC. + + Creates audiences. Operation statuses are returned. + + List of thrown errors: `AudienceError <>`__ + + Returns: + Callable[[~.MutateAudiencesRequest], + ~.MutateAudiencesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_audiences" not in self._stubs: + self._stubs["mutate_audiences"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceService/MutateAudiences", + request_serializer=audience_service.MutateAudiencesRequest.serialize, + response_deserializer=audience_service.MutateAudiencesResponse.deserialize, + ) + return self._stubs["mutate_audiences"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AudienceServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/audience_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/audience_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..a7fc913e6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/audience_service/transports/grpc_asyncio.py @@ -0,0 +1,404 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import audience_service +from .base import AudienceServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AudienceService", + "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.ads.googleads.v23.services.AudienceService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AudienceServiceGrpcAsyncIOTransport(AudienceServiceTransport): + """gRPC AsyncIO backend transport for AudienceService. + + Service to manage audiences. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_audiences( + self, + ) -> Callable[ + [audience_service.MutateAudiencesRequest], + Awaitable[audience_service.MutateAudiencesResponse], + ]: + r"""Return a callable for the mutate audiences method over gRPC. + + Creates audiences. Operation statuses are returned. + + List of thrown errors: `AudienceError <>`__ + + Returns: + Callable[[~.MutateAudiencesRequest], + Awaitable[~.MutateAudiencesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_audiences" not in self._stubs: + self._stubs["mutate_audiences"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AudienceService/MutateAudiences", + request_serializer=audience_service.MutateAudiencesRequest.serialize, + response_deserializer=audience_service.MutateAudiencesResponse.deserialize, + ) + return self._stubs["mutate_audiences"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_audiences: self._wrap_method( + self.mutate_audiences, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AudienceServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/__init__.py b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/__init__.py new file mode 100644 index 000000000..458f3456e --- /dev/null +++ b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import AutomaticallyCreatedAssetRemovalServiceClient +from .async_client import AutomaticallyCreatedAssetRemovalServiceAsyncClient + +__all__ = ( + "AutomaticallyCreatedAssetRemovalServiceClient", + "AutomaticallyCreatedAssetRemovalServiceAsyncClient", +) diff --git a/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/async_client.py b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/async_client.py new file mode 100644 index 000000000..91f3b782f --- /dev/null +++ b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/async_client.py @@ -0,0 +1,453 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + automatically_created_asset_removal_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AutomaticallyCreatedAssetRemovalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import AutomaticallyCreatedAssetRemovalServiceClient + +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 AutomaticallyCreatedAssetRemovalServiceAsyncClient: + """Service to remove automatically created assets.""" + + _client: AutomaticallyCreatedAssetRemovalServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ( + AutomaticallyCreatedAssetRemovalServiceClient.DEFAULT_ENDPOINT + ) + DEFAULT_MTLS_ENDPOINT = ( + AutomaticallyCreatedAssetRemovalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + AutomaticallyCreatedAssetRemovalServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ( + AutomaticallyCreatedAssetRemovalServiceClient._DEFAULT_UNIVERSE + ) + + common_billing_account_path = staticmethod( + AutomaticallyCreatedAssetRemovalServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + AutomaticallyCreatedAssetRemovalServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + AutomaticallyCreatedAssetRemovalServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + AutomaticallyCreatedAssetRemovalServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + AutomaticallyCreatedAssetRemovalServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + AutomaticallyCreatedAssetRemovalServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + AutomaticallyCreatedAssetRemovalServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + AutomaticallyCreatedAssetRemovalServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + AutomaticallyCreatedAssetRemovalServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + AutomaticallyCreatedAssetRemovalServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AutomaticallyCreatedAssetRemovalServiceAsyncClient: The constructed client. + """ + return AutomaticallyCreatedAssetRemovalServiceClient.from_service_account_info.__func__(AutomaticallyCreatedAssetRemovalServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AutomaticallyCreatedAssetRemovalServiceAsyncClient: The constructed client. + """ + return AutomaticallyCreatedAssetRemovalServiceClient.from_service_account_file.__func__(AutomaticallyCreatedAssetRemovalServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return AutomaticallyCreatedAssetRemovalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> AutomaticallyCreatedAssetRemovalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AutomaticallyCreatedAssetRemovalServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + AutomaticallyCreatedAssetRemovalServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AutomaticallyCreatedAssetRemovalServiceTransport, + Callable[..., AutomaticallyCreatedAssetRemovalServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the automatically created asset removal service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AutomaticallyCreatedAssetRemovalServiceTransport,Callable[..., AutomaticallyCreatedAssetRemovalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AutomaticallyCreatedAssetRemovalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = AutomaticallyCreatedAssetRemovalServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService", + "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.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService", + "credentialsType": None, + } + ), + ) + + async def remove_campaign_automatically_created_asset( + self, + request: Optional[ + Union[ + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetOperation + ] + ] = None, + partial_failure: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetResponse + ): + r"""Removes automatically created assets from a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ContextError <>`__ `FieldError <>`__ + `InternalError <>`__ `MutateError <>`__ + `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.RemoveCampaignAutomaticallyCreatedAssetRequest, dict]]): + The request object. Request message for + [AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset][google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset]. + customer_id (:class:`str`): + Required. The ID of the customer + whose assets are being removed. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.RemoveCampaignAutomaticallyCreatedAssetOperation]`): + Required. The list of operations. + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + partial_failure (:class:`bool`): + Required. If true, successful + operations will be carried out and + invalid operations will return errors. + If false, all operations will be carried + out in one transaction if and only if + they are all valid. + + This corresponds to the ``partial_failure`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.RemoveCampaignAutomaticallyCreatedAssetResponse: + Response message for + [AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset][google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations, partial_failure] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetRequest, + ): + request = automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if partial_failure is not None: + request.partial_failure = partial_failure + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.remove_campaign_automatically_created_asset + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__( + self, + ) -> "AutomaticallyCreatedAssetRemovalServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("AutomaticallyCreatedAssetRemovalServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/client.py b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/client.py new file mode 100644 index 000000000..47955c62c --- /dev/null +++ b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/client.py @@ -0,0 +1,924 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + automatically_created_asset_removal_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + AutomaticallyCreatedAssetRemovalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ( + AutomaticallyCreatedAssetRemovalServiceGrpcTransport, +) +from .transports.grpc_asyncio import ( + AutomaticallyCreatedAssetRemovalServiceGrpcAsyncIOTransport, +) + + +class AutomaticallyCreatedAssetRemovalServiceClientMeta(type): + """Metaclass for the AutomaticallyCreatedAssetRemovalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[AutomaticallyCreatedAssetRemovalServiceTransport]] + _transport_registry["grpc"] = ( + AutomaticallyCreatedAssetRemovalServiceGrpcTransport + ) + _transport_registry["grpc_asyncio"] = ( + AutomaticallyCreatedAssetRemovalServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[AutomaticallyCreatedAssetRemovalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class AutomaticallyCreatedAssetRemovalServiceClient( + metaclass=AutomaticallyCreatedAssetRemovalServiceClientMeta +): + """Service to remove automatically created assets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AutomaticallyCreatedAssetRemovalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + AutomaticallyCreatedAssetRemovalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> AutomaticallyCreatedAssetRemovalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + AutomaticallyCreatedAssetRemovalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + AutomaticallyCreatedAssetRemovalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + AutomaticallyCreatedAssetRemovalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + AutomaticallyCreatedAssetRemovalServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + AutomaticallyCreatedAssetRemovalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = AutomaticallyCreatedAssetRemovalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + AutomaticallyCreatedAssetRemovalServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + AutomaticallyCreatedAssetRemovalServiceTransport, + Callable[..., AutomaticallyCreatedAssetRemovalServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the automatically created asset removal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,AutomaticallyCreatedAssetRemovalServiceTransport,Callable[..., AutomaticallyCreatedAssetRemovalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the AutomaticallyCreatedAssetRemovalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ( + AutomaticallyCreatedAssetRemovalServiceClient._read_environment_variables() + ) + self._client_cert_source = AutomaticallyCreatedAssetRemovalServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = ( + AutomaticallyCreatedAssetRemovalServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, AutomaticallyCreatedAssetRemovalServiceTransport + ) + if transport_provided: + # transport is a AutomaticallyCreatedAssetRemovalServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + AutomaticallyCreatedAssetRemovalServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or AutomaticallyCreatedAssetRemovalServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[AutomaticallyCreatedAssetRemovalServiceTransport], + Callable[..., AutomaticallyCreatedAssetRemovalServiceTransport], + ] = ( + AutomaticallyCreatedAssetRemovalServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[ + ..., AutomaticallyCreatedAssetRemovalServiceTransport + ], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService", + "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.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService", + "credentialsType": None, + } + ), + ) + + def remove_campaign_automatically_created_asset( + self, + request: Optional[ + Union[ + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetOperation + ] + ] = None, + partial_failure: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetResponse + ): + r"""Removes automatically created assets from a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ContextError <>`__ `FieldError <>`__ + `InternalError <>`__ `MutateError <>`__ + `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.RemoveCampaignAutomaticallyCreatedAssetRequest, dict]): + The request object. Request message for + [AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset][google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset]. + customer_id (str): + Required. The ID of the customer + whose assets are being removed. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.RemoveCampaignAutomaticallyCreatedAssetOperation]): + Required. The list of operations. + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + partial_failure (bool): + Required. If true, successful + operations will be carried out and + invalid operations will return errors. + If false, all operations will be carried + out in one transaction if and only if + they are all valid. + + This corresponds to the ``partial_failure`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.RemoveCampaignAutomaticallyCreatedAssetResponse: + Response message for + [AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset][google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations, partial_failure] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetRequest, + ): + request = automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + if partial_failure is not None: + request.partial_failure = partial_failure + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.remove_campaign_automatically_created_asset + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "AutomaticallyCreatedAssetRemovalServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("AutomaticallyCreatedAssetRemovalServiceClient",) diff --git a/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/README.rst b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/README.rst new file mode 100644 index 000000000..8dc7dd5fc --- /dev/null +++ b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`AutomaticallyCreatedAssetRemovalServiceTransport` is the ABC for all transports. +- public child `AutomaticallyCreatedAssetRemovalServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `AutomaticallyCreatedAssetRemovalServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseAutomaticallyCreatedAssetRemovalServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `AutomaticallyCreatedAssetRemovalServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/__init__.py b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/__init__.py new file mode 100644 index 000000000..0bbd6fc51 --- /dev/null +++ b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/__init__.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict + +from .base import AutomaticallyCreatedAssetRemovalServiceTransport +from .grpc import AutomaticallyCreatedAssetRemovalServiceGrpcTransport +from .grpc_asyncio import ( + AutomaticallyCreatedAssetRemovalServiceGrpcAsyncIOTransport, +) + + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[AutomaticallyCreatedAssetRemovalServiceTransport]] +_transport_registry["grpc"] = ( + AutomaticallyCreatedAssetRemovalServiceGrpcTransport +) +_transport_registry["grpc_asyncio"] = ( + AutomaticallyCreatedAssetRemovalServiceGrpcAsyncIOTransport +) + +__all__ = ( + "AutomaticallyCreatedAssetRemovalServiceTransport", + "AutomaticallyCreatedAssetRemovalServiceGrpcTransport", + "AutomaticallyCreatedAssetRemovalServiceGrpcAsyncIOTransport", +) diff --git a/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/base.py b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/base.py new file mode 100644 index 000000000..153129244 --- /dev/null +++ b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + automatically_created_asset_removal_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class AutomaticallyCreatedAssetRemovalServiceTransport(abc.ABC): + """Abstract transport class for AutomaticallyCreatedAssetRemovalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.remove_campaign_automatically_created_asset: gapic_v1.method.wrap_method( + self.remove_campaign_automatically_created_asset, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def remove_campaign_automatically_created_asset( + self, + ) -> Callable[ + [ + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetRequest + ], + Union[ + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetResponse, + Awaitable[ + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("AutomaticallyCreatedAssetRemovalServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/grpc.py b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/grpc.py new file mode 100644 index 000000000..97a0437d8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/grpc.py @@ -0,0 +1,398 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + automatically_created_asset_removal_service, +) +from .base import ( + AutomaticallyCreatedAssetRemovalServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService", + "rpcName": str(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.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AutomaticallyCreatedAssetRemovalServiceGrpcTransport( + AutomaticallyCreatedAssetRemovalServiceTransport +): + """gRPC backend transport for AutomaticallyCreatedAssetRemovalService. + + Service to remove automatically created assets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def remove_campaign_automatically_created_asset( + self, + ) -> Callable[ + [ + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetRequest + ], + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetResponse, + ]: + r"""Return a callable for the remove campaign automatically + created asset method over gRPC. + + Removes automatically created assets from a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ContextError <>`__ `FieldError <>`__ + `InternalError <>`__ `MutateError <>`__ + `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.RemoveCampaignAutomaticallyCreatedAssetRequest], + ~.RemoveCampaignAutomaticallyCreatedAssetResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "remove_campaign_automatically_created_asset" not in self._stubs: + self._stubs["remove_campaign_automatically_created_asset"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService/RemoveCampaignAutomaticallyCreatedAsset", + request_serializer=automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetRequest.serialize, + response_deserializer=automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetResponse.deserialize, + ) + ) + return self._stubs["remove_campaign_automatically_created_asset"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("AutomaticallyCreatedAssetRemovalServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..7a68aff40 --- /dev/null +++ b/google/ads/googleads/v23/services/services/automatically_created_asset_removal_service/transports/grpc_asyncio.py @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + automatically_created_asset_removal_service, +) +from .base import ( + AutomaticallyCreatedAssetRemovalServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService", + "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.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class AutomaticallyCreatedAssetRemovalServiceGrpcAsyncIOTransport( + AutomaticallyCreatedAssetRemovalServiceTransport +): + """gRPC AsyncIO backend transport for AutomaticallyCreatedAssetRemovalService. + + Service to remove automatically created assets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def remove_campaign_automatically_created_asset( + self, + ) -> Callable[ + [ + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetRequest + ], + Awaitable[ + automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetResponse + ], + ]: + r"""Return a callable for the remove campaign automatically + created asset method over gRPC. + + Removes automatically created assets from a campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ContextError <>`__ `FieldError <>`__ + `InternalError <>`__ `MutateError <>`__ + `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.RemoveCampaignAutomaticallyCreatedAssetRequest], + Awaitable[~.RemoveCampaignAutomaticallyCreatedAssetResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "remove_campaign_automatically_created_asset" not in self._stubs: + self._stubs["remove_campaign_automatically_created_asset"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService/RemoveCampaignAutomaticallyCreatedAsset", + request_serializer=automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetRequest.serialize, + response_deserializer=automatically_created_asset_removal_service.RemoveCampaignAutomaticallyCreatedAssetResponse.deserialize, + ) + ) + return self._stubs["remove_campaign_automatically_created_asset"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.remove_campaign_automatically_created_asset: self._wrap_method( + self.remove_campaign_automatically_created_asset, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("AutomaticallyCreatedAssetRemovalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/batch_job_service/__init__.py b/google/ads/googleads/v23/services/services/batch_job_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/batch_job_service/__init__.py rename to google/ads/googleads/v23/services/services/batch_job_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/batch_job_service/async_client.py b/google/ads/googleads/v23/services/services/batch_job_service/async_client.py new file mode 100644 index 000000000..ced9ffccc --- /dev/null +++ b/google/ads/googleads/v23/services/services/batch_job_service/async_client.py @@ -0,0 +1,1192 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.resources.types import batch_job +from google.ads.googleads.v23.services.services.batch_job_service import pagers +from google.ads.googleads.v23.services.types import batch_job_service +from google.ads.googleads.v23.services.types import google_ads_service +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .transports.base import BatchJobServiceTransport, DEFAULT_CLIENT_INFO +from .client import BatchJobServiceClient + +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 BatchJobServiceAsyncClient: + """Service to manage batch jobs.""" + + _client: BatchJobServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = BatchJobServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = BatchJobServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + BatchJobServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = BatchJobServiceClient._DEFAULT_UNIVERSE + + accessible_bidding_strategy_path = staticmethod( + BatchJobServiceClient.accessible_bidding_strategy_path + ) + parse_accessible_bidding_strategy_path = staticmethod( + BatchJobServiceClient.parse_accessible_bidding_strategy_path + ) + ad_path = staticmethod(BatchJobServiceClient.ad_path) + parse_ad_path = staticmethod(BatchJobServiceClient.parse_ad_path) + ad_group_path = staticmethod(BatchJobServiceClient.ad_group_path) + parse_ad_group_path = staticmethod( + BatchJobServiceClient.parse_ad_group_path + ) + ad_group_ad_path = staticmethod(BatchJobServiceClient.ad_group_ad_path) + parse_ad_group_ad_path = staticmethod( + BatchJobServiceClient.parse_ad_group_ad_path + ) + ad_group_ad_label_path = staticmethod( + BatchJobServiceClient.ad_group_ad_label_path + ) + parse_ad_group_ad_label_path = staticmethod( + BatchJobServiceClient.parse_ad_group_ad_label_path + ) + ad_group_asset_path = staticmethod( + BatchJobServiceClient.ad_group_asset_path + ) + parse_ad_group_asset_path = staticmethod( + BatchJobServiceClient.parse_ad_group_asset_path + ) + ad_group_bid_modifier_path = staticmethod( + BatchJobServiceClient.ad_group_bid_modifier_path + ) + parse_ad_group_bid_modifier_path = staticmethod( + BatchJobServiceClient.parse_ad_group_bid_modifier_path + ) + ad_group_criterion_path = staticmethod( + BatchJobServiceClient.ad_group_criterion_path + ) + parse_ad_group_criterion_path = staticmethod( + BatchJobServiceClient.parse_ad_group_criterion_path + ) + ad_group_criterion_customizer_path = staticmethod( + BatchJobServiceClient.ad_group_criterion_customizer_path + ) + parse_ad_group_criterion_customizer_path = staticmethod( + BatchJobServiceClient.parse_ad_group_criterion_customizer_path + ) + ad_group_criterion_label_path = staticmethod( + BatchJobServiceClient.ad_group_criterion_label_path + ) + parse_ad_group_criterion_label_path = staticmethod( + BatchJobServiceClient.parse_ad_group_criterion_label_path + ) + ad_group_customizer_path = staticmethod( + BatchJobServiceClient.ad_group_customizer_path + ) + parse_ad_group_customizer_path = staticmethod( + BatchJobServiceClient.parse_ad_group_customizer_path + ) + ad_group_label_path = staticmethod( + BatchJobServiceClient.ad_group_label_path + ) + parse_ad_group_label_path = staticmethod( + BatchJobServiceClient.parse_ad_group_label_path + ) + ad_parameter_path = staticmethod(BatchJobServiceClient.ad_parameter_path) + parse_ad_parameter_path = staticmethod( + BatchJobServiceClient.parse_ad_parameter_path + ) + asset_path = staticmethod(BatchJobServiceClient.asset_path) + parse_asset_path = staticmethod(BatchJobServiceClient.parse_asset_path) + asset_group_path = staticmethod(BatchJobServiceClient.asset_group_path) + parse_asset_group_path = staticmethod( + BatchJobServiceClient.parse_asset_group_path + ) + asset_group_asset_path = staticmethod( + BatchJobServiceClient.asset_group_asset_path + ) + parse_asset_group_asset_path = staticmethod( + BatchJobServiceClient.parse_asset_group_asset_path + ) + asset_group_listing_group_filter_path = staticmethod( + BatchJobServiceClient.asset_group_listing_group_filter_path + ) + parse_asset_group_listing_group_filter_path = staticmethod( + BatchJobServiceClient.parse_asset_group_listing_group_filter_path + ) + asset_group_signal_path = staticmethod( + BatchJobServiceClient.asset_group_signal_path + ) + parse_asset_group_signal_path = staticmethod( + BatchJobServiceClient.parse_asset_group_signal_path + ) + asset_set_path = staticmethod(BatchJobServiceClient.asset_set_path) + parse_asset_set_path = staticmethod( + BatchJobServiceClient.parse_asset_set_path + ) + asset_set_asset_path = staticmethod( + BatchJobServiceClient.asset_set_asset_path + ) + parse_asset_set_asset_path = staticmethod( + BatchJobServiceClient.parse_asset_set_asset_path + ) + audience_path = staticmethod(BatchJobServiceClient.audience_path) + parse_audience_path = staticmethod( + BatchJobServiceClient.parse_audience_path + ) + batch_job_path = staticmethod(BatchJobServiceClient.batch_job_path) + parse_batch_job_path = staticmethod( + BatchJobServiceClient.parse_batch_job_path + ) + bidding_data_exclusion_path = staticmethod( + BatchJobServiceClient.bidding_data_exclusion_path + ) + parse_bidding_data_exclusion_path = staticmethod( + BatchJobServiceClient.parse_bidding_data_exclusion_path + ) + bidding_seasonality_adjustment_path = staticmethod( + BatchJobServiceClient.bidding_seasonality_adjustment_path + ) + parse_bidding_seasonality_adjustment_path = staticmethod( + BatchJobServiceClient.parse_bidding_seasonality_adjustment_path + ) + bidding_strategy_path = staticmethod( + BatchJobServiceClient.bidding_strategy_path + ) + parse_bidding_strategy_path = staticmethod( + BatchJobServiceClient.parse_bidding_strategy_path + ) + campaign_path = staticmethod(BatchJobServiceClient.campaign_path) + parse_campaign_path = staticmethod( + BatchJobServiceClient.parse_campaign_path + ) + campaign_asset_path = staticmethod( + BatchJobServiceClient.campaign_asset_path + ) + parse_campaign_asset_path = staticmethod( + BatchJobServiceClient.parse_campaign_asset_path + ) + campaign_asset_set_path = staticmethod( + BatchJobServiceClient.campaign_asset_set_path + ) + parse_campaign_asset_set_path = staticmethod( + BatchJobServiceClient.parse_campaign_asset_set_path + ) + campaign_bid_modifier_path = staticmethod( + BatchJobServiceClient.campaign_bid_modifier_path + ) + parse_campaign_bid_modifier_path = staticmethod( + BatchJobServiceClient.parse_campaign_bid_modifier_path + ) + campaign_budget_path = staticmethod( + BatchJobServiceClient.campaign_budget_path + ) + parse_campaign_budget_path = staticmethod( + BatchJobServiceClient.parse_campaign_budget_path + ) + campaign_conversion_goal_path = staticmethod( + BatchJobServiceClient.campaign_conversion_goal_path + ) + parse_campaign_conversion_goal_path = staticmethod( + BatchJobServiceClient.parse_campaign_conversion_goal_path + ) + campaign_criterion_path = staticmethod( + BatchJobServiceClient.campaign_criterion_path + ) + parse_campaign_criterion_path = staticmethod( + BatchJobServiceClient.parse_campaign_criterion_path + ) + campaign_customizer_path = staticmethod( + BatchJobServiceClient.campaign_customizer_path + ) + parse_campaign_customizer_path = staticmethod( + BatchJobServiceClient.parse_campaign_customizer_path + ) + campaign_draft_path = staticmethod( + BatchJobServiceClient.campaign_draft_path + ) + parse_campaign_draft_path = staticmethod( + BatchJobServiceClient.parse_campaign_draft_path + ) + campaign_group_path = staticmethod( + BatchJobServiceClient.campaign_group_path + ) + parse_campaign_group_path = staticmethod( + BatchJobServiceClient.parse_campaign_group_path + ) + campaign_label_path = staticmethod( + BatchJobServiceClient.campaign_label_path + ) + parse_campaign_label_path = staticmethod( + BatchJobServiceClient.parse_campaign_label_path + ) + campaign_shared_set_path = staticmethod( + BatchJobServiceClient.campaign_shared_set_path + ) + parse_campaign_shared_set_path = staticmethod( + BatchJobServiceClient.parse_campaign_shared_set_path + ) + carrier_constant_path = staticmethod( + BatchJobServiceClient.carrier_constant_path + ) + parse_carrier_constant_path = staticmethod( + BatchJobServiceClient.parse_carrier_constant_path + ) + combined_audience_path = staticmethod( + BatchJobServiceClient.combined_audience_path + ) + parse_combined_audience_path = staticmethod( + BatchJobServiceClient.parse_combined_audience_path + ) + conversion_action_path = staticmethod( + BatchJobServiceClient.conversion_action_path + ) + parse_conversion_action_path = staticmethod( + BatchJobServiceClient.parse_conversion_action_path + ) + conversion_custom_variable_path = staticmethod( + BatchJobServiceClient.conversion_custom_variable_path + ) + parse_conversion_custom_variable_path = staticmethod( + BatchJobServiceClient.parse_conversion_custom_variable_path + ) + conversion_goal_campaign_config_path = staticmethod( + BatchJobServiceClient.conversion_goal_campaign_config_path + ) + parse_conversion_goal_campaign_config_path = staticmethod( + BatchJobServiceClient.parse_conversion_goal_campaign_config_path + ) + conversion_value_rule_path = staticmethod( + BatchJobServiceClient.conversion_value_rule_path + ) + parse_conversion_value_rule_path = staticmethod( + BatchJobServiceClient.parse_conversion_value_rule_path + ) + conversion_value_rule_set_path = staticmethod( + BatchJobServiceClient.conversion_value_rule_set_path + ) + parse_conversion_value_rule_set_path = staticmethod( + BatchJobServiceClient.parse_conversion_value_rule_set_path + ) + custom_conversion_goal_path = staticmethod( + BatchJobServiceClient.custom_conversion_goal_path + ) + parse_custom_conversion_goal_path = staticmethod( + BatchJobServiceClient.parse_custom_conversion_goal_path + ) + customer_path = staticmethod(BatchJobServiceClient.customer_path) + parse_customer_path = staticmethod( + BatchJobServiceClient.parse_customer_path + ) + customer_asset_path = staticmethod( + BatchJobServiceClient.customer_asset_path + ) + parse_customer_asset_path = staticmethod( + BatchJobServiceClient.parse_customer_asset_path + ) + customer_conversion_goal_path = staticmethod( + BatchJobServiceClient.customer_conversion_goal_path + ) + parse_customer_conversion_goal_path = staticmethod( + BatchJobServiceClient.parse_customer_conversion_goal_path + ) + customer_customizer_path = staticmethod( + BatchJobServiceClient.customer_customizer_path + ) + parse_customer_customizer_path = staticmethod( + BatchJobServiceClient.parse_customer_customizer_path + ) + customer_label_path = staticmethod( + BatchJobServiceClient.customer_label_path + ) + parse_customer_label_path = staticmethod( + BatchJobServiceClient.parse_customer_label_path + ) + customer_negative_criterion_path = staticmethod( + BatchJobServiceClient.customer_negative_criterion_path + ) + parse_customer_negative_criterion_path = staticmethod( + BatchJobServiceClient.parse_customer_negative_criterion_path + ) + customizer_attribute_path = staticmethod( + BatchJobServiceClient.customizer_attribute_path + ) + parse_customizer_attribute_path = staticmethod( + BatchJobServiceClient.parse_customizer_attribute_path + ) + detailed_demographic_path = staticmethod( + BatchJobServiceClient.detailed_demographic_path + ) + parse_detailed_demographic_path = staticmethod( + BatchJobServiceClient.parse_detailed_demographic_path + ) + experiment_path = staticmethod(BatchJobServiceClient.experiment_path) + parse_experiment_path = staticmethod( + BatchJobServiceClient.parse_experiment_path + ) + experiment_arm_path = staticmethod( + BatchJobServiceClient.experiment_arm_path + ) + parse_experiment_arm_path = staticmethod( + BatchJobServiceClient.parse_experiment_arm_path + ) + geo_target_constant_path = staticmethod( + BatchJobServiceClient.geo_target_constant_path + ) + parse_geo_target_constant_path = staticmethod( + BatchJobServiceClient.parse_geo_target_constant_path + ) + keyword_plan_path = staticmethod(BatchJobServiceClient.keyword_plan_path) + parse_keyword_plan_path = staticmethod( + BatchJobServiceClient.parse_keyword_plan_path + ) + keyword_plan_ad_group_path = staticmethod( + BatchJobServiceClient.keyword_plan_ad_group_path + ) + parse_keyword_plan_ad_group_path = staticmethod( + BatchJobServiceClient.parse_keyword_plan_ad_group_path + ) + keyword_plan_ad_group_keyword_path = staticmethod( + BatchJobServiceClient.keyword_plan_ad_group_keyword_path + ) + parse_keyword_plan_ad_group_keyword_path = staticmethod( + BatchJobServiceClient.parse_keyword_plan_ad_group_keyword_path + ) + keyword_plan_campaign_path = staticmethod( + BatchJobServiceClient.keyword_plan_campaign_path + ) + parse_keyword_plan_campaign_path = staticmethod( + BatchJobServiceClient.parse_keyword_plan_campaign_path + ) + keyword_plan_campaign_keyword_path = staticmethod( + BatchJobServiceClient.keyword_plan_campaign_keyword_path + ) + parse_keyword_plan_campaign_keyword_path = staticmethod( + BatchJobServiceClient.parse_keyword_plan_campaign_keyword_path + ) + keyword_theme_constant_path = staticmethod( + BatchJobServiceClient.keyword_theme_constant_path + ) + parse_keyword_theme_constant_path = staticmethod( + BatchJobServiceClient.parse_keyword_theme_constant_path + ) + label_path = staticmethod(BatchJobServiceClient.label_path) + parse_label_path = staticmethod(BatchJobServiceClient.parse_label_path) + language_constant_path = staticmethod( + BatchJobServiceClient.language_constant_path + ) + parse_language_constant_path = staticmethod( + BatchJobServiceClient.parse_language_constant_path + ) + life_event_path = staticmethod(BatchJobServiceClient.life_event_path) + parse_life_event_path = staticmethod( + BatchJobServiceClient.parse_life_event_path + ) + mobile_app_category_constant_path = staticmethod( + BatchJobServiceClient.mobile_app_category_constant_path + ) + parse_mobile_app_category_constant_path = staticmethod( + BatchJobServiceClient.parse_mobile_app_category_constant_path + ) + mobile_device_constant_path = staticmethod( + BatchJobServiceClient.mobile_device_constant_path + ) + parse_mobile_device_constant_path = staticmethod( + BatchJobServiceClient.parse_mobile_device_constant_path + ) + operating_system_version_constant_path = staticmethod( + BatchJobServiceClient.operating_system_version_constant_path + ) + parse_operating_system_version_constant_path = staticmethod( + BatchJobServiceClient.parse_operating_system_version_constant_path + ) + recommendation_subscription_path = staticmethod( + BatchJobServiceClient.recommendation_subscription_path + ) + parse_recommendation_subscription_path = staticmethod( + BatchJobServiceClient.parse_recommendation_subscription_path + ) + remarketing_action_path = staticmethod( + BatchJobServiceClient.remarketing_action_path + ) + parse_remarketing_action_path = staticmethod( + BatchJobServiceClient.parse_remarketing_action_path + ) + shared_criterion_path = staticmethod( + BatchJobServiceClient.shared_criterion_path + ) + parse_shared_criterion_path = staticmethod( + BatchJobServiceClient.parse_shared_criterion_path + ) + shared_set_path = staticmethod(BatchJobServiceClient.shared_set_path) + parse_shared_set_path = staticmethod( + BatchJobServiceClient.parse_shared_set_path + ) + smart_campaign_setting_path = staticmethod( + BatchJobServiceClient.smart_campaign_setting_path + ) + parse_smart_campaign_setting_path = staticmethod( + BatchJobServiceClient.parse_smart_campaign_setting_path + ) + topic_constant_path = staticmethod( + BatchJobServiceClient.topic_constant_path + ) + parse_topic_constant_path = staticmethod( + BatchJobServiceClient.parse_topic_constant_path + ) + user_interest_path = staticmethod(BatchJobServiceClient.user_interest_path) + parse_user_interest_path = staticmethod( + BatchJobServiceClient.parse_user_interest_path + ) + user_list_path = staticmethod(BatchJobServiceClient.user_list_path) + parse_user_list_path = staticmethod( + BatchJobServiceClient.parse_user_list_path + ) + common_billing_account_path = staticmethod( + BatchJobServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + BatchJobServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(BatchJobServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + BatchJobServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + BatchJobServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + BatchJobServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + BatchJobServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + BatchJobServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + BatchJobServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + BatchJobServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BatchJobServiceAsyncClient: The constructed client. + """ + return BatchJobServiceClient.from_service_account_info.__func__(BatchJobServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BatchJobServiceAsyncClient: The constructed client. + """ + return BatchJobServiceClient.from_service_account_file.__func__(BatchJobServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return BatchJobServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> BatchJobServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BatchJobServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = BatchJobServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BatchJobServiceTransport, + Callable[..., BatchJobServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the batch job service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BatchJobServiceTransport,Callable[..., BatchJobServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BatchJobServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = BatchJobServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.BatchJobServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BatchJobService", + "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.ads.googleads.v23.services.BatchJobService", + "credentialsType": None, + } + ), + ) + + async def mutate_batch_job( + self, + request: Optional[ + Union[batch_job_service.MutateBatchJobRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[batch_job_service.BatchJobOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> batch_job_service.MutateBatchJobResponse: + r"""Mutates a batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateBatchJobRequest, dict]]): + The request object. Request message for + [BatchJobService.MutateBatchJob][google.ads.googleads.v23.services.BatchJobService.MutateBatchJob]. + customer_id (:class:`str`): + Required. The ID of the customer for + which to create a batch job. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (:class:`google.ads.googleads.v23.services.types.BatchJobOperation`): + Required. The operation to perform on + an individual batch job. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateBatchJobResponse: + Response message for + [BatchJobService.MutateBatchJob][google.ads.googleads.v23.services.BatchJobService.MutateBatchJob]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, batch_job_service.MutateBatchJobRequest): + request = batch_job_service.MutateBatchJobRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_batch_job + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_batch_job_results( + self, + request: Optional[ + Union[batch_job_service.ListBatchJobResultsRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListBatchJobResultsAsyncPager: + r"""Returns the results of the batch job. The job must be done. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListBatchJobResultsRequest, dict]]): + The request object. Request message for + [BatchJobService.ListBatchJobResults][google.ads.googleads.v23.services.BatchJobService.ListBatchJobResults]. + resource_name (:class:`str`): + Required. The resource name of the + batch job whose results are being + listed. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.batch_job_service.pagers.ListBatchJobResultsAsyncPager: + Response message for + [BatchJobService.ListBatchJobResults][google.ads.googleads.v23.services.BatchJobService.ListBatchJobResults]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, batch_job_service.ListBatchJobResultsRequest + ): + request = batch_job_service.ListBatchJobResultsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_batch_job_results + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListBatchJobResultsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def run_batch_job( + self, + request: Optional[ + Union[batch_job_service.RunBatchJobRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Runs the batch job. + + The Operation.metadata field type is BatchJobMetadata. When + finished, the long running operation will not contain errors or + a response. Instead, use ListBatchJobResults to get the results + of the job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.RunBatchJobRequest, dict]]): + The request object. Request message for + [BatchJobService.RunBatchJob][google.ads.googleads.v23.services.BatchJobService.RunBatchJob]. + resource_name (:class:`str`): + Required. The resource name of the + BatchJob to run. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, batch_job_service.RunBatchJobRequest): + request = batch_job_service.RunBatchJobRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.run_batch_job + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=batch_job.BatchJob.BatchJobMetadata, + ) + + # Done; return the response. + return response + + async def add_batch_job_operations( + self, + request: Optional[ + Union[batch_job_service.AddBatchJobOperationsRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + sequence_token: Optional[str] = None, + mutate_operations: Optional[ + MutableSequence[google_ads_service.MutateOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> batch_job_service.AddBatchJobOperationsResponse: + r"""Add operations to the batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.AddBatchJobOperationsRequest, dict]]): + The request object. Request message for + [BatchJobService.AddBatchJobOperations][google.ads.googleads.v23.services.BatchJobService.AddBatchJobOperations]. + resource_name (:class:`str`): + Required. The resource name of the + batch job. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + sequence_token (:class:`str`): + A token used to enforce sequencing. + + The first AddBatchJobOperations request for a batch job + should not set sequence_token. Subsequent requests must + set sequence_token to the value of next_sequence_token + received in the previous AddBatchJobOperations response. + + This corresponds to the ``sequence_token`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mutate_operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.MutateOperation]`): + Required. The list of mutates being + added. + Operations can use negative integers as + temp ids to signify dependencies between + entities created in this batch job. For + example, a customer with id = 1234 can + create a campaign and an ad group in + that same campaign by creating a + campaign in the first operation with the + resource name explicitly set to + "customers/1234/campaigns/-1", and + creating an ad group in the second + operation with the campaign field also + set to "customers/1234/campaigns/-1". + + This corresponds to the ``mutate_operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.AddBatchJobOperationsResponse: + Response message for + [BatchJobService.AddBatchJobOperations][google.ads.googleads.v23.services.BatchJobService.AddBatchJobOperations]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name, sequence_token, mutate_operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, batch_job_service.AddBatchJobOperationsRequest + ): + request = batch_job_service.AddBatchJobOperationsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + if sequence_token is not None: + request.sequence_token = sequence_token + if mutate_operations: + request.mutate_operations.extend(mutate_operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.add_batch_job_operations + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "BatchJobServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("BatchJobServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/batch_job_service/client.py b/google/ads/googleads/v23/services/services/batch_job_service/client.py new file mode 100644 index 000000000..b62e19505 --- /dev/null +++ b/google/ads/googleads/v23/services/services/batch_job_service/client.py @@ -0,0 +1,2785 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.resources.types import batch_job +from google.ads.googleads.v23.services.services.batch_job_service import pagers +from google.ads.googleads.v23.services.types import batch_job_service +from google.ads.googleads.v23.services.types import google_ads_service +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .transports.base import BatchJobServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import BatchJobServiceGrpcTransport +from .transports.grpc_asyncio import BatchJobServiceGrpcAsyncIOTransport + + +class BatchJobServiceClientMeta(type): + """Metaclass for the BatchJobService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BatchJobServiceTransport]] + _transport_registry["grpc"] = BatchJobServiceGrpcTransport + _transport_registry["grpc_asyncio"] = BatchJobServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[BatchJobServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BatchJobServiceClient(metaclass=BatchJobServiceClientMeta): + """Service to manage batch jobs.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BatchJobServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BatchJobServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BatchJobServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BatchJobServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def accessible_bidding_strategy_path( + customer_id: str, + bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified accessible_bidding_strategy string.""" + return "customers/{customer_id}/accessibleBiddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, + bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_accessible_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a accessible_bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accessibleBiddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_path( + customer_id: str, + ad_id: str, + ) -> str: + """Returns a fully-qualified ad string.""" + return "customers/{customer_id}/ads/{ad_id}".format( + customer_id=customer_id, + ad_id=ad_id, + ) + + @staticmethod + def parse_ad_path(path: str) -> Dict[str, str]: + """Parses a ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ads/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_path( + customer_id: str, + ad_group_id: str, + ) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad string.""" + return ( + "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + ) + ) + + @staticmethod + def parse_ad_group_ad_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_label_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_label string.""" + return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_asset_path( + customer_id: str, + ad_group_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified ad_group_asset string.""" + return "customers/{customer_id}/adGroupAssets/{ad_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_ad_group_asset_path(path: str) -> Dict[str, str]: + """Parses a ad_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_bid_modifier_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_bid_modifier string.""" + return "customers/{customer_id}/adGroupBidModifiers/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a ad_group_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_customizer_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_customizer string.""" + return "customers/{customer_id}/adGroupCriterionCustomizers/{ad_group_id}~{criterion_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_criterion_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionCustomizers/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_label_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_label string.""" + return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_customizer_path( + customer_id: str, + ad_group_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_customizer string.""" + return "customers/{customer_id}/adGroupCustomizers/{ad_group_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_label_path( + customer_id: str, + ad_group_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_label string.""" + return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_parameter_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + parameter_index: str, + ) -> str: + """Returns a fully-qualified ad_parameter string.""" + return "customers/{customer_id}/adParameters/{ad_group_id}~{criterion_id}~{parameter_index}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + parameter_index=parameter_index, + ) + + @staticmethod + def parse_ad_parameter_path(path: str) -> Dict[str, str]: + """Parses a ad_parameter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adParameters/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_path( + customer_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_path( + customer_id: str, + asset_group_id: str, + ) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_asset_path( + customer_id: str, + asset_group_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified asset_group_asset string.""" + return "customers/{customer_id}/assetGroupAssets/{asset_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_asset_group_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_listing_group_filter_path( + customer_id: str, + asset_group_id: str, + listing_group_filter_id: str, + ) -> str: + """Returns a fully-qualified asset_group_listing_group_filter string.""" + return "customers/{customer_id}/assetGroupListingGroupFilters/{asset_group_id}~{listing_group_filter_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + listing_group_filter_id=listing_group_filter_id, + ) + + @staticmethod + def parse_asset_group_listing_group_filter_path( + path: str, + ) -> Dict[str, str]: + """Parses a asset_group_listing_group_filter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupListingGroupFilters/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_signal_path( + customer_id: str, + asset_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified asset_group_signal string.""" + return "customers/{customer_id}/assetGroupSignals/{asset_group_id}~{criterion_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_asset_group_signal_path(path: str) -> Dict[str, str]: + """Parses a asset_group_signal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupSignals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_path( + customer_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_asset_path( + customer_id: str, + asset_set_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset_set_asset string.""" + return "customers/{customer_id}/assetSetAssets/{asset_set_id}~{asset_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_set_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_set_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSetAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def audience_path( + customer_id: str, + audience_id: str, + ) -> str: + """Returns a fully-qualified audience string.""" + return "customers/{customer_id}/audiences/{audience_id}".format( + customer_id=customer_id, + audience_id=audience_id, + ) + + @staticmethod + def parse_audience_path(path: str) -> Dict[str, str]: + """Parses a audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/audiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def batch_job_path( + customer_id: str, + batch_job_id: str, + ) -> str: + """Returns a fully-qualified batch_job string.""" + return "customers/{customer_id}/batchJobs/{batch_job_id}".format( + customer_id=customer_id, + batch_job_id=batch_job_id, + ) + + @staticmethod + def parse_batch_job_path(path: str) -> Dict[str, str]: + """Parses a batch_job path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/batchJobs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_data_exclusion_path( + customer_id: str, + seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_data_exclusion string.""" + return "customers/{customer_id}/biddingDataExclusions/{seasonality_event_id}".format( + customer_id=customer_id, + seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_data_exclusion_path(path: str) -> Dict[str, str]: + """Parses a bidding_data_exclusion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingDataExclusions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_seasonality_adjustment_path( + customer_id: str, + seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_seasonality_adjustment string.""" + return "customers/{customer_id}/biddingSeasonalityAdjustments/{seasonality_event_id}".format( + customer_id=customer_id, + seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_seasonality_adjustment_path(path: str) -> Dict[str, str]: + """Parses a bidding_seasonality_adjustment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingSeasonalityAdjustments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_strategy_path( + customer_id: str, + bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified bidding_strategy string.""" + return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, + bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_path( + customer_id: str, + campaign_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified campaign_asset string.""" + return "customers/{customer_id}/campaignAssets/{campaign_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_campaign_asset_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_set_path( + customer_id: str, + campaign_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_asset_set string.""" + return "customers/{customer_id}/campaignAssetSets/{campaign_id}~{asset_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_campaign_asset_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssetSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_bid_modifier_path( + customer_id: str, + campaign_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_bid_modifier string.""" + return "customers/{customer_id}/campaignBidModifiers/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a campaign_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_budget_path( + customer_id: str, + campaign_budget_id: str, + ) -> str: + """Returns a fully-qualified campaign_budget string.""" + return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( + customer_id=customer_id, + campaign_budget_id=campaign_budget_id, + ) + + @staticmethod + def parse_campaign_budget_path(path: str) -> Dict[str, str]: + """Parses a campaign_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_conversion_goal_path( + customer_id: str, + campaign_id: str, + category: str, + source: str, + ) -> str: + """Returns a fully-qualified campaign_conversion_goal string.""" + return "customers/{customer_id}/campaignConversionGoals/{campaign_id}~{category}~{source}".format( + customer_id=customer_id, + campaign_id=campaign_id, + category=category, + source=source, + ) + + @staticmethod + def parse_campaign_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a campaign_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignConversionGoals/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_criterion_path( + customer_id: str, + campaign_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_criterion string.""" + return "customers/{customer_id}/campaignCriteria/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_criterion_path(path: str) -> Dict[str, str]: + """Parses a campaign_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_customizer_path( + customer_id: str, + campaign_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified campaign_customizer string.""" + return "customers/{customer_id}/campaignCustomizers/{campaign_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_campaign_customizer_path(path: str) -> Dict[str, str]: + """Parses a campaign_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_draft_path( + customer_id: str, + base_campaign_id: str, + draft_id: str, + ) -> str: + """Returns a fully-qualified campaign_draft string.""" + return "customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}".format( + customer_id=customer_id, + base_campaign_id=base_campaign_id, + draft_id=draft_id, + ) + + @staticmethod + def parse_campaign_draft_path(path: str) -> Dict[str, str]: + """Parses a campaign_draft path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignDrafts/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_group_path( + customer_id: str, + campaign_group_id: str, + ) -> str: + """Returns a fully-qualified campaign_group string.""" + return ( + "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( + customer_id=customer_id, + campaign_group_id=campaign_group_id, + ) + ) + + @staticmethod + def parse_campaign_group_path(path: str) -> Dict[str, str]: + """Parses a campaign_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_label_path( + customer_id: str, + campaign_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified campaign_label string.""" + return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + label_id=label_id, + ) + + @staticmethod + def parse_campaign_label_path(path: str) -> Dict[str, str]: + """Parses a campaign_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_shared_set_path( + customer_id: str, + campaign_id: str, + shared_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_shared_set string.""" + return "customers/{customer_id}/campaignSharedSets/{campaign_id}~{shared_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_campaign_shared_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignSharedSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def carrier_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified carrier_constant string.""" + return "carrierConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_carrier_constant_path(path: str) -> Dict[str, str]: + """Parses a carrier_constant path into its component segments.""" + m = re.match(r"^carrierConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def combined_audience_path( + customer_id: str, + combined_audience_id: str, + ) -> str: + """Returns a fully-qualified combined_audience string.""" + return "customers/{customer_id}/combinedAudiences/{combined_audience_id}".format( + customer_id=customer_id, + combined_audience_id=combined_audience_id, + ) + + @staticmethod + def parse_combined_audience_path(path: str) -> Dict[str, str]: + """Parses a combined_audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/combinedAudiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_action_path( + customer_id: str, + conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, + conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_custom_variable_path( + customer_id: str, + conversion_custom_variable_id: str, + ) -> str: + """Returns a fully-qualified conversion_custom_variable string.""" + return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( + customer_id=customer_id, + conversion_custom_variable_id=conversion_custom_variable_id, + ) + + @staticmethod + def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: + """Parses a conversion_custom_variable path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_goal_campaign_config_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified conversion_goal_campaign_config string.""" + return "customers/{customer_id}/conversionGoalCampaignConfigs/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_conversion_goal_campaign_config_path(path: str) -> Dict[str, str]: + """Parses a conversion_goal_campaign_config path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionGoalCampaignConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_path( + customer_id: str, + conversion_value_rule_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule string.""" + return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( + customer_id=customer_id, + conversion_value_rule_id=conversion_value_rule_id, + ) + + @staticmethod + def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_set_path( + customer_id: str, + conversion_value_rule_set_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule_set string.""" + return "customers/{customer_id}/conversionValueRuleSets/{conversion_value_rule_set_id}".format( + customer_id=customer_id, + conversion_value_rule_set_id=conversion_value_rule_set_id, + ) + + @staticmethod + def parse_conversion_value_rule_set_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRuleSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def custom_conversion_goal_path( + customer_id: str, + goal_id: str, + ) -> str: + """Returns a fully-qualified custom_conversion_goal string.""" + return "customers/{customer_id}/customConversionGoals/{goal_id}".format( + customer_id=customer_id, + goal_id=goal_id, + ) + + @staticmethod + def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a custom_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_asset_path( + customer_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified customer_asset string.""" + return "customers/{customer_id}/customerAssets/{asset_id}~{field_type}".format( + customer_id=customer_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_customer_asset_path(path: str) -> Dict[str, str]: + """Parses a customer_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_conversion_goal_path( + customer_id: str, + category: str, + source: str, + ) -> str: + """Returns a fully-qualified customer_conversion_goal string.""" + return "customers/{customer_id}/customerConversionGoals/{category}~{source}".format( + customer_id=customer_id, + category=category, + source=source, + ) + + @staticmethod + def parse_customer_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a customer_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerConversionGoals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_customizer_path( + customer_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customer_customizer string.""" + return "customers/{customer_id}/customerCustomizers/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customer_customizer_path(path: str) -> Dict[str, str]: + """Parses a customer_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerCustomizers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_label_path( + customer_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified customer_label string.""" + return "customers/{customer_id}/customerLabels/{label_id}".format( + customer_id=customer_id, + label_id=label_id, + ) + + @staticmethod + def parse_customer_label_path(path: str) -> Dict[str, str]: + """Parses a customer_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerLabels/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_negative_criterion_path( + customer_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified customer_negative_criterion string.""" + return "customers/{customer_id}/customerNegativeCriteria/{criterion_id}".format( + customer_id=customer_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_customer_negative_criterion_path(path: str) -> Dict[str, str]: + """Parses a customer_negative_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerNegativeCriteria/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def detailed_demographic_path( + customer_id: str, + detailed_demographic_id: str, + ) -> str: + """Returns a fully-qualified detailed_demographic string.""" + return "customers/{customer_id}/detailedDemographics/{detailed_demographic_id}".format( + customer_id=customer_id, + detailed_demographic_id=detailed_demographic_id, + ) + + @staticmethod + def parse_detailed_demographic_path(path: str) -> Dict[str, str]: + """Parses a detailed_demographic path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/detailedDemographics/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_path( + customer_id: str, + trial_id: str, + ) -> str: + """Returns a fully-qualified experiment string.""" + return "customers/{customer_id}/experiments/{trial_id}".format( + customer_id=customer_id, + trial_id=trial_id, + ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str, str]: + """Parses a experiment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_arm_path( + customer_id: str, + trial_id: str, + trial_arm_id: str, + ) -> str: + """Returns a fully-qualified experiment_arm string.""" + return "customers/{customer_id}/experimentArms/{trial_id}~{trial_arm_id}".format( + customer_id=customer_id, + trial_id=trial_id, + trial_arm_id=trial_arm_id, + ) + + @staticmethod + def parse_experiment_arm_path(path: str) -> Dict[str, str]: + """Parses a experiment_arm path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experimentArms/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def geo_target_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_path( + customer_id: str, + keyword_plan_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan string.""" + return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( + customer_id=customer_id, + keyword_plan_id=keyword_plan_id, + ) + + @staticmethod + def parse_keyword_plan_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_ad_group_path( + customer_id: str, + keyword_plan_ad_group_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group string.""" + return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_id=keyword_plan_ad_group_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_ad_group_keyword_path( + customer_id: str, + keyword_plan_ad_group_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group_keyword string.""" + return "customers/{customer_id}/keywordPlanAdGroupKeywords/{keyword_plan_ad_group_keyword_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_keyword_id=keyword_plan_ad_group_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroupKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_path( + customer_id: str, + keyword_plan_campaign_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign string.""" + return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( + customer_id=customer_id, + keyword_plan_campaign_id=keyword_plan_campaign_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_keyword_path( + customer_id: str, + keyword_plan_campaign_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign_keyword string.""" + return "customers/{customer_id}/keywordPlanCampaignKeywords/{keyword_plan_campaign_keyword_id}".format( + customer_id=customer_id, + keyword_plan_campaign_keyword_id=keyword_plan_campaign_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaignKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_theme_constant_path( + express_category_id: str, + express_sub_category_id: str, + ) -> str: + """Returns a fully-qualified keyword_theme_constant string.""" + return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( + express_category_id=express_category_id, + express_sub_category_id=express_sub_category_id, + ) + + @staticmethod + def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: + """Parses a keyword_theme_constant path into its component segments.""" + m = re.match( + r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path( + customer_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, + label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def language_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified language_constant string.""" + return "languageConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_language_constant_path(path: str) -> Dict[str, str]: + """Parses a language_constant path into its component segments.""" + m = re.match(r"^languageConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def life_event_path( + customer_id: str, + life_event_id: str, + ) -> str: + """Returns a fully-qualified life_event string.""" + return "customers/{customer_id}/lifeEvents/{life_event_id}".format( + customer_id=customer_id, + life_event_id=life_event_id, + ) + + @staticmethod + def parse_life_event_path(path: str) -> Dict[str, str]: + """Parses a life_event path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/lifeEvents/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_app_category_constant_path( + mobile_app_category_id: str, + ) -> str: + """Returns a fully-qualified mobile_app_category_constant string.""" + return "mobileAppCategoryConstants/{mobile_app_category_id}".format( + mobile_app_category_id=mobile_app_category_id, + ) + + @staticmethod + def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: + """Parses a mobile_app_category_constant path into its component segments.""" + m = re.match( + r"^mobileAppCategoryConstants/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_device_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified mobile_device_constant string.""" + return "mobileDeviceConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_mobile_device_constant_path(path: str) -> Dict[str, str]: + """Parses a mobile_device_constant path into its component segments.""" + m = re.match(r"^mobileDeviceConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def operating_system_version_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified operating_system_version_constant string.""" + return "operatingSystemVersionConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_operating_system_version_constant_path( + path: str, + ) -> Dict[str, str]: + """Parses a operating_system_version_constant path into its component segments.""" + m = re.match( + r"^operatingSystemVersionConstants/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def recommendation_subscription_path( + customer_id: str, + recommendation_type: str, + ) -> str: + """Returns a fully-qualified recommendation_subscription string.""" + return "customers/{customer_id}/recommendationSubscriptions/{recommendation_type}".format( + customer_id=customer_id, + recommendation_type=recommendation_type, + ) + + @staticmethod + def parse_recommendation_subscription_path(path: str) -> Dict[str, str]: + """Parses a recommendation_subscription path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/recommendationSubscriptions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def remarketing_action_path( + customer_id: str, + remarketing_action_id: str, + ) -> str: + """Returns a fully-qualified remarketing_action string.""" + return "customers/{customer_id}/remarketingActions/{remarketing_action_id}".format( + customer_id=customer_id, + remarketing_action_id=remarketing_action_id, + ) + + @staticmethod + def parse_remarketing_action_path(path: str) -> Dict[str, str]: + """Parses a remarketing_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/remarketingActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_criterion_path( + customer_id: str, + shared_set_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified shared_criterion string.""" + return "customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}".format( + customer_id=customer_id, + shared_set_id=shared_set_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_shared_criterion_path(path: str) -> Dict[str, str]: + """Parses a shared_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_set_path( + customer_id: str, + shared_set_id: str, + ) -> str: + """Returns a fully-qualified shared_set string.""" + return "customers/{customer_id}/sharedSets/{shared_set_id}".format( + customer_id=customer_id, + shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_shared_set_path(path: str) -> Dict[str, str]: + """Parses a shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def smart_campaign_setting_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified smart_campaign_setting string.""" + return "customers/{customer_id}/smartCampaignSettings/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_smart_campaign_setting_path(path: str) -> Dict[str, str]: + """Parses a smart_campaign_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/smartCampaignSettings/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def topic_constant_path( + topic_id: str, + ) -> str: + """Returns a fully-qualified topic_constant string.""" + return "topicConstants/{topic_id}".format( + topic_id=topic_id, + ) + + @staticmethod + def parse_topic_constant_path(path: str) -> Dict[str, str]: + """Parses a topic_constant path into its component segments.""" + m = re.match(r"^topicConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def user_interest_path( + customer_id: str, + user_interest_id: str, + ) -> str: + """Returns a fully-qualified user_interest string.""" + return ( + "customers/{customer_id}/userInterests/{user_interest_id}".format( + customer_id=customer_id, + user_interest_id=user_interest_id, + ) + ) + + @staticmethod + def parse_user_interest_path(path: str) -> Dict[str, str]: + """Parses a user_interest path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userInterests/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_list_path( + customer_id: str, + user_list_id: str, + ) -> str: + """Returns a fully-qualified user_list string.""" + return "customers/{customer_id}/userLists/{user_list_id}".format( + customer_id=customer_id, + user_list_id=user_list_id, + ) + + @staticmethod + def parse_user_list_path(path: str) -> Dict[str, str]: + """Parses a user_list path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userLists/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = BatchJobServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = BatchJobServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = BatchJobServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = BatchJobServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + BatchJobServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = BatchJobServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BatchJobServiceTransport, + Callable[..., BatchJobServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the batch job service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BatchJobServiceTransport,Callable[..., BatchJobServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BatchJobServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = BatchJobServiceClient._read_environment_variables() + self._client_cert_source = ( + BatchJobServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = BatchJobServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, BatchJobServiceTransport) + if transport_provided: + # transport is a BatchJobServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(BatchJobServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or BatchJobServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[BatchJobServiceTransport], + Callable[..., BatchJobServiceTransport], + ] = ( + BatchJobServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., BatchJobServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.BatchJobServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BatchJobService", + "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.ads.googleads.v23.services.BatchJobService", + "credentialsType": None, + } + ), + ) + + def mutate_batch_job( + self, + request: Optional[ + Union[batch_job_service.MutateBatchJobRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[batch_job_service.BatchJobOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> batch_job_service.MutateBatchJobResponse: + r"""Mutates a batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateBatchJobRequest, dict]): + The request object. Request message for + [BatchJobService.MutateBatchJob][google.ads.googleads.v23.services.BatchJobService.MutateBatchJob]. + customer_id (str): + Required. The ID of the customer for + which to create a batch job. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v23.services.types.BatchJobOperation): + Required. The operation to perform on + an individual batch job. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateBatchJobResponse: + Response message for + [BatchJobService.MutateBatchJob][google.ads.googleads.v23.services.BatchJobService.MutateBatchJob]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, batch_job_service.MutateBatchJobRequest): + request = batch_job_service.MutateBatchJobRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_batch_job] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_batch_job_results( + self, + request: Optional[ + Union[batch_job_service.ListBatchJobResultsRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListBatchJobResultsPager: + r"""Returns the results of the batch job. The job must be done. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListBatchJobResultsRequest, dict]): + The request object. Request message for + [BatchJobService.ListBatchJobResults][google.ads.googleads.v23.services.BatchJobService.ListBatchJobResults]. + resource_name (str): + Required. The resource name of the + batch job whose results are being + listed. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.batch_job_service.pagers.ListBatchJobResultsPager: + Response message for + [BatchJobService.ListBatchJobResults][google.ads.googleads.v23.services.BatchJobService.ListBatchJobResults]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, batch_job_service.ListBatchJobResultsRequest + ): + request = batch_job_service.ListBatchJobResultsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_batch_job_results + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListBatchJobResultsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def run_batch_job( + self, + request: Optional[ + Union[batch_job_service.RunBatchJobRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Runs the batch job. + + The Operation.metadata field type is BatchJobMetadata. When + finished, the long running operation will not contain errors or + a response. Instead, use ListBatchJobResults to get the results + of the job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.RunBatchJobRequest, dict]): + The request object. Request message for + [BatchJobService.RunBatchJob][google.ads.googleads.v23.services.BatchJobService.RunBatchJob]. + resource_name (str): + Required. The resource name of the + BatchJob to run. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, batch_job_service.RunBatchJobRequest): + request = batch_job_service.RunBatchJobRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.run_batch_job] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=batch_job.BatchJob.BatchJobMetadata, + ) + + # Done; return the response. + return response + + def add_batch_job_operations( + self, + request: Optional[ + Union[batch_job_service.AddBatchJobOperationsRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + sequence_token: Optional[str] = None, + mutate_operations: Optional[ + MutableSequence[google_ads_service.MutateOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> batch_job_service.AddBatchJobOperationsResponse: + r"""Add operations to the batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.AddBatchJobOperationsRequest, dict]): + The request object. Request message for + [BatchJobService.AddBatchJobOperations][google.ads.googleads.v23.services.BatchJobService.AddBatchJobOperations]. + resource_name (str): + Required. The resource name of the + batch job. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + sequence_token (str): + A token used to enforce sequencing. + + The first AddBatchJobOperations request for a batch job + should not set sequence_token. Subsequent requests must + set sequence_token to the value of next_sequence_token + received in the previous AddBatchJobOperations response. + + This corresponds to the ``sequence_token`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mutate_operations (MutableSequence[google.ads.googleads.v23.services.types.MutateOperation]): + Required. The list of mutates being + added. + Operations can use negative integers as + temp ids to signify dependencies between + entities created in this batch job. For + example, a customer with id = 1234 can + create a campaign and an ad group in + that same campaign by creating a + campaign in the first operation with the + resource name explicitly set to + "customers/1234/campaigns/-1", and + creating an ad group in the second + operation with the campaign field also + set to "customers/1234/campaigns/-1". + + This corresponds to the ``mutate_operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.AddBatchJobOperationsResponse: + Response message for + [BatchJobService.AddBatchJobOperations][google.ads.googleads.v23.services.BatchJobService.AddBatchJobOperations]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name, sequence_token, mutate_operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, batch_job_service.AddBatchJobOperationsRequest + ): + request = batch_job_service.AddBatchJobOperationsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + if sequence_token is not None: + request.sequence_token = sequence_token + if mutate_operations is not None: + request.mutate_operations = mutate_operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.add_batch_job_operations + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "BatchJobServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("BatchJobServiceClient",) diff --git a/google/ads/googleads/v23/services/services/batch_job_service/pagers.py b/google/ads/googleads/v23/services/services/batch_job_service/pagers.py new file mode 100644 index 000000000..ffbb10cab --- /dev/null +++ b/google/ads/googleads/v23/services/services/batch_job_service/pagers.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Sequence, + Tuple, + Iterator, + Union, +) + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import batch_job_service + + +class ListBatchJobResultsPager: + """A pager for iterating through ``list_batch_job_results`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.ListBatchJobResultsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListBatchJobResults`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.ListBatchJobResultsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., batch_job_service.ListBatchJobResultsResponse], + request: batch_job_service.ListBatchJobResultsRequest, + response: batch_job_service.ListBatchJobResultsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.ListBatchJobResultsRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.ListBatchJobResultsResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = batch_job_service.ListBatchJobResultsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[batch_job_service.ListBatchJobResultsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[batch_job_service.BatchJobResult]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListBatchJobResultsAsyncPager: + """A pager for iterating through ``list_batch_job_results`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.ListBatchJobResultsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListBatchJobResults`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.ListBatchJobResultsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[batch_job_service.ListBatchJobResultsResponse] + ], + request: batch_job_service.ListBatchJobResultsRequest, + response: batch_job_service.ListBatchJobResultsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.ListBatchJobResultsRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.ListBatchJobResultsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = batch_job_service.ListBatchJobResultsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[batch_job_service.ListBatchJobResultsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[batch_job_service.BatchJobResult]: + async def async_generator(): + async for page in self.pages: + for response in page.results: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/batch_job_service/transports/README.rst b/google/ads/googleads/v23/services/services/batch_job_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/batch_job_service/transports/README.rst rename to google/ads/googleads/v23/services/services/batch_job_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/batch_job_service/transports/__init__.py b/google/ads/googleads/v23/services/services/batch_job_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/batch_job_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/batch_job_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/batch_job_service/transports/base.py b/google/ads/googleads/v23/services/services/batch_job_service/transports/base.py new file mode 100644 index 000000000..115a18ccc --- /dev/null +++ b/google/ads/googleads/v23/services/services/batch_job_service/transports/base.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import batch_job_service +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class BatchJobServiceTransport(abc.ABC): + """Abstract transport class for BatchJobService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_batch_job: gapic_v1.method.wrap_method( + self.mutate_batch_job, + default_timeout=None, + client_info=client_info, + ), + self.list_batch_job_results: gapic_v1.method.wrap_method( + self.list_batch_job_results, + default_timeout=None, + client_info=client_info, + ), + self.run_batch_job: gapic_v1.method.wrap_method( + self.run_batch_job, + default_timeout=None, + client_info=client_info, + ), + self.add_batch_job_operations: gapic_v1.method.wrap_method( + self.add_batch_job_operations, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def mutate_batch_job( + self, + ) -> Callable[ + [batch_job_service.MutateBatchJobRequest], + Union[ + batch_job_service.MutateBatchJobResponse, + Awaitable[batch_job_service.MutateBatchJobResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_batch_job_results( + self, + ) -> Callable[ + [batch_job_service.ListBatchJobResultsRequest], + Union[ + batch_job_service.ListBatchJobResultsResponse, + Awaitable[batch_job_service.ListBatchJobResultsResponse], + ], + ]: + raise NotImplementedError() + + @property + def run_batch_job( + self, + ) -> Callable[ + [batch_job_service.RunBatchJobRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def add_batch_job_operations( + self, + ) -> Callable[ + [batch_job_service.AddBatchJobOperationsRequest], + Union[ + batch_job_service.AddBatchJobOperationsResponse, + Awaitable[batch_job_service.AddBatchJobOperationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("BatchJobServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/batch_job_service/transports/grpc.py b/google/ads/googleads/v23/services/services/batch_job_service/transports/grpc.py new file mode 100644 index 000000000..2b00f04d3 --- /dev/null +++ b/google/ads/googleads/v23/services/services/batch_job_service/transports/grpc.py @@ -0,0 +1,516 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import batch_job_service +from google.longrunning import operations_pb2 # type: ignore +from .base import BatchJobServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.BatchJobService", + "rpcName": str(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.ads.googleads.v23.services.BatchJobService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BatchJobServiceGrpcTransport(BatchJobServiceTransport): + """gRPC backend transport for BatchJobService. + + Service to manage batch jobs. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # 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._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def mutate_batch_job( + self, + ) -> Callable[ + [batch_job_service.MutateBatchJobRequest], + batch_job_service.MutateBatchJobResponse, + ]: + r"""Return a callable for the mutate batch job method over gRPC. + + Mutates a batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateBatchJobRequest], + ~.MutateBatchJobResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_batch_job" not in self._stubs: + self._stubs["mutate_batch_job"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BatchJobService/MutateBatchJob", + request_serializer=batch_job_service.MutateBatchJobRequest.serialize, + response_deserializer=batch_job_service.MutateBatchJobResponse.deserialize, + ) + return self._stubs["mutate_batch_job"] + + @property + def list_batch_job_results( + self, + ) -> Callable[ + [batch_job_service.ListBatchJobResultsRequest], + batch_job_service.ListBatchJobResultsResponse, + ]: + r"""Return a callable for the list batch job results method over gRPC. + + Returns the results of the batch job. The job must be done. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListBatchJobResultsRequest], + ~.ListBatchJobResultsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_batch_job_results" not in self._stubs: + self._stubs["list_batch_job_results"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BatchJobService/ListBatchJobResults", + request_serializer=batch_job_service.ListBatchJobResultsRequest.serialize, + response_deserializer=batch_job_service.ListBatchJobResultsResponse.deserialize, + ) + ) + return self._stubs["list_batch_job_results"] + + @property + def run_batch_job( + self, + ) -> Callable[ + [batch_job_service.RunBatchJobRequest], operations_pb2.Operation + ]: + r"""Return a callable for the run batch job method over gRPC. + + Runs the batch job. + + The Operation.metadata field type is BatchJobMetadata. When + finished, the long running operation will not contain errors or + a response. Instead, use ListBatchJobResults to get the results + of the job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.RunBatchJobRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "run_batch_job" not in self._stubs: + self._stubs["run_batch_job"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BatchJobService/RunBatchJob", + request_serializer=batch_job_service.RunBatchJobRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["run_batch_job"] + + @property + def add_batch_job_operations( + self, + ) -> Callable[ + [batch_job_service.AddBatchJobOperationsRequest], + batch_job_service.AddBatchJobOperationsResponse, + ]: + r"""Return a callable for the add batch job operations method over gRPC. + + Add operations to the batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.AddBatchJobOperationsRequest], + ~.AddBatchJobOperationsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "add_batch_job_operations" not in self._stubs: + self._stubs["add_batch_job_operations"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BatchJobService/AddBatchJobOperations", + request_serializer=batch_job_service.AddBatchJobOperationsRequest.serialize, + response_deserializer=batch_job_service.AddBatchJobOperationsResponse.deserialize, + ) + ) + return self._stubs["add_batch_job_operations"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("BatchJobServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/batch_job_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/batch_job_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..9b017ce31 --- /dev/null +++ b/google/ads/googleads/v23/services/services/batch_job_service/transports/grpc_asyncio.py @@ -0,0 +1,555 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import batch_job_service +from google.longrunning import operations_pb2 # type: ignore +from .base import BatchJobServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.BatchJobService", + "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.ads.googleads.v23.services.BatchJobService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BatchJobServiceGrpcAsyncIOTransport(BatchJobServiceTransport): + """gRPC AsyncIO backend transport for BatchJobService. + + Service to manage batch jobs. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[ + operations_v1.OperationsAsyncClient + ] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # 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._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def mutate_batch_job( + self, + ) -> Callable[ + [batch_job_service.MutateBatchJobRequest], + Awaitable[batch_job_service.MutateBatchJobResponse], + ]: + r"""Return a callable for the mutate batch job method over gRPC. + + Mutates a batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateBatchJobRequest], + Awaitable[~.MutateBatchJobResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_batch_job" not in self._stubs: + self._stubs["mutate_batch_job"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BatchJobService/MutateBatchJob", + request_serializer=batch_job_service.MutateBatchJobRequest.serialize, + response_deserializer=batch_job_service.MutateBatchJobResponse.deserialize, + ) + return self._stubs["mutate_batch_job"] + + @property + def list_batch_job_results( + self, + ) -> Callable[ + [batch_job_service.ListBatchJobResultsRequest], + Awaitable[batch_job_service.ListBatchJobResultsResponse], + ]: + r"""Return a callable for the list batch job results method over gRPC. + + Returns the results of the batch job. The job must be done. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListBatchJobResultsRequest], + Awaitable[~.ListBatchJobResultsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_batch_job_results" not in self._stubs: + self._stubs["list_batch_job_results"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BatchJobService/ListBatchJobResults", + request_serializer=batch_job_service.ListBatchJobResultsRequest.serialize, + response_deserializer=batch_job_service.ListBatchJobResultsResponse.deserialize, + ) + ) + return self._stubs["list_batch_job_results"] + + @property + def run_batch_job( + self, + ) -> Callable[ + [batch_job_service.RunBatchJobRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the run batch job method over gRPC. + + Runs the batch job. + + The Operation.metadata field type is BatchJobMetadata. When + finished, the long running operation will not contain errors or + a response. Instead, use ListBatchJobResults to get the results + of the job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.RunBatchJobRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "run_batch_job" not in self._stubs: + self._stubs["run_batch_job"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BatchJobService/RunBatchJob", + request_serializer=batch_job_service.RunBatchJobRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["run_batch_job"] + + @property + def add_batch_job_operations( + self, + ) -> Callable[ + [batch_job_service.AddBatchJobOperationsRequest], + Awaitable[batch_job_service.AddBatchJobOperationsResponse], + ]: + r"""Return a callable for the add batch job operations method over gRPC. + + Add operations to the batch job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BatchJobError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.AddBatchJobOperationsRequest], + Awaitable[~.AddBatchJobOperationsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "add_batch_job_operations" not in self._stubs: + self._stubs["add_batch_job_operations"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BatchJobService/AddBatchJobOperations", + request_serializer=batch_job_service.AddBatchJobOperationsRequest.serialize, + response_deserializer=batch_job_service.AddBatchJobOperationsResponse.deserialize, + ) + ) + return self._stubs["add_batch_job_operations"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_batch_job: self._wrap_method( + self.mutate_batch_job, + default_timeout=None, + client_info=client_info, + ), + self.list_batch_job_results: self._wrap_method( + self.list_batch_job_results, + default_timeout=None, + client_info=client_info, + ), + self.run_batch_job: self._wrap_method( + self.run_batch_job, + default_timeout=None, + client_info=client_info, + ), + self.add_batch_job_operations: self._wrap_method( + self.add_batch_job_operations, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("BatchJobServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v23/services/services/benchmarks_service/__init__.py b/google/ads/googleads/v23/services/services/benchmarks_service/__init__.py new file mode 100644 index 000000000..866d1fa27 --- /dev/null +++ b/google/ads/googleads/v23/services/services/benchmarks_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import BenchmarksServiceClient +from .async_client import BenchmarksServiceAsyncClient + +__all__ = ( + "BenchmarksServiceClient", + "BenchmarksServiceAsyncClient", +) diff --git a/google/ads/googleads/v23/services/services/benchmarks_service/async_client.py b/google/ads/googleads/v23/services/services/benchmarks_service/async_client.py new file mode 100644 index 000000000..56339257d --- /dev/null +++ b/google/ads/googleads/v23/services/services/benchmarks_service/async_client.py @@ -0,0 +1,733 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import benchmarks_source_type +from google.ads.googleads.v23.services.types import benchmarks_service +from .transports.base import BenchmarksServiceTransport, DEFAULT_CLIENT_INFO +from .client import BenchmarksServiceClient + +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 BenchmarksServiceAsyncClient: + """BenchmarksService helps users compare YouTube advertisement + data against industry benchmarks. Accessible to allowlisted + customers only. + """ + + _client: BenchmarksServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = BenchmarksServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = BenchmarksServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + BenchmarksServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = BenchmarksServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod( + BenchmarksServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + BenchmarksServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + BenchmarksServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + BenchmarksServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + BenchmarksServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + BenchmarksServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + BenchmarksServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + BenchmarksServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + BenchmarksServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + BenchmarksServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BenchmarksServiceAsyncClient: The constructed client. + """ + return BenchmarksServiceClient.from_service_account_info.__func__(BenchmarksServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BenchmarksServiceAsyncClient: The constructed client. + """ + return BenchmarksServiceClient.from_service_account_file.__func__(BenchmarksServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return BenchmarksServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> BenchmarksServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BenchmarksServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = BenchmarksServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BenchmarksServiceTransport, + Callable[..., BenchmarksServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the benchmarks service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BenchmarksServiceTransport,Callable[..., BenchmarksServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BenchmarksServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = BenchmarksServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.BenchmarksServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BenchmarksService", + "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.ads.googleads.v23.services.BenchmarksService", + "credentialsType": None, + } + ), + ) + + async def list_benchmarks_available_dates( + self, + request: Optional[ + Union[benchmarks_service.ListBenchmarksAvailableDatesRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> benchmarks_service.ListBenchmarksAvailableDatesResponse: + r"""Returns a date range that supports benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListBenchmarksAvailableDatesRequest, dict]]): + The request object. Request message for + [BenchmarksService.ListBenchmarksAvailableDates][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksAvailableDates]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListBenchmarksAvailableDatesResponse: + Response message for + [BenchmarksService.ListBenchmarksAvailableDates][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksAvailableDates]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, benchmarks_service.ListBenchmarksAvailableDatesRequest + ): + request = benchmarks_service.ListBenchmarksAvailableDatesRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_benchmarks_available_dates + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_benchmarks_locations( + self, + request: Optional[ + Union[benchmarks_service.ListBenchmarksLocationsRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> benchmarks_service.ListBenchmarksLocationsResponse: + r"""Returns the list of locations that support benchmarks (for + example, countries). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListBenchmarksLocationsRequest, dict]]): + The request object. Request message for + [BenchmarksService.ListBenchmarksLocations][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksLocations]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListBenchmarksLocationsResponse: + Response message for + [BenchmarksService.ListBenchmarksLocations][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksLocations]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, benchmarks_service.ListBenchmarksLocationsRequest + ): + request = benchmarks_service.ListBenchmarksLocationsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_benchmarks_locations + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_benchmarks_products( + self, + request: Optional[ + Union[benchmarks_service.ListBenchmarksProductsRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> benchmarks_service.ListBenchmarksProductsResponse: + r"""Returns the list of products that supports benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListBenchmarksProductsRequest, dict]]): + The request object. Request message for + [BenchmarksService.ListBenchmarksProducts][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksProducts]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListBenchmarksProductsResponse: + Response message for + [BenchmarksService.ListBenchmarksProducts][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksProducts]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, benchmarks_service.ListBenchmarksProductsRequest + ): + request = benchmarks_service.ListBenchmarksProductsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_benchmarks_products + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_benchmarks_sources( + self, + request: Optional[ + Union[benchmarks_service.ListBenchmarksSourcesRequest, dict] + ] = None, + *, + benchmarks_sources: Optional[ + MutableSequence[ + benchmarks_source_type.BenchmarksSourceTypeEnum.BenchmarksSourceType + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> benchmarks_service.ListBenchmarksSourcesResponse: + r"""Returns the list of benchmarks sources (for example, Industry + Verticals). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListBenchmarksSourcesRequest, dict]]): + The request object. Request message for + [BenchmarksService.ListBenchmarksSources][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksSources]. + benchmarks_sources (:class:`MutableSequence[google.ads.googleads.v23.enums.types.BenchmarksSourceTypeEnum.BenchmarksSourceType]`): + Required. The types of benchmarks sources to be returned + (for example, INDUSTRY_VERTICAL). + + This corresponds to the ``benchmarks_sources`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListBenchmarksSourcesResponse: + Response message for + [BenchmarksService.ListBenchmarksSources][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksSources]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [benchmarks_sources] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, benchmarks_service.ListBenchmarksSourcesRequest + ): + request = benchmarks_service.ListBenchmarksSourcesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if benchmarks_sources: + request.benchmarks_sources.extend(benchmarks_sources) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_benchmarks_sources + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_benchmarks_metrics( + self, + request: Optional[ + Union[benchmarks_service.GenerateBenchmarksMetricsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + location: Optional[criteria.LocationInfo] = None, + benchmarks_source: Optional[benchmarks_service.BenchmarksSource] = None, + product_filter: Optional[benchmarks_service.ProductFilter] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> benchmarks_service.GenerateBenchmarksMetricsResponse: + r"""Returns YouTube advertisement metrics for the given client + against industry benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BenchmarksError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateBenchmarksMetricsRequest, dict]]): + The request object. Request message for + [BenchmarksService.GenerateBenchmarksMetrics][google.ads.googleads.v23.services.BenchmarksService.GenerateBenchmarksMetrics]. + customer_id (:class:`str`): + Required. The ID of the customer. + Supply a client customer ID to generate + metrics for the customer. A manager + account customer ID will not return + customer metrics since it does not have + any associated direct ad campaigns. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + location (:class:`google.ads.googleads.v23.common.types.LocationInfo`): + Required. The location to generate + benchmarks metrics for. + + This corresponds to the ``location`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + benchmarks_source (:class:`google.ads.googleads.v23.services.types.BenchmarksSource`): + Required. The source used to generate + benchmarks metrics for. + + This corresponds to the ``benchmarks_source`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_filter (:class:`google.ads.googleads.v23.services.types.ProductFilter`): + Required. The products to aggregate + metrics over. Product filter settings + support a list of product IDs or a list + of marketing objectives. + + This corresponds to the ``product_filter`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateBenchmarksMetricsResponse: + Response message for + [BenchmarksService.GenerateBenchmarksMetrics][google.ads.googleads.v23.services.BenchmarksService.GenerateBenchmarksMetrics]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + location, + benchmarks_source, + product_filter, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, benchmarks_service.GenerateBenchmarksMetricsRequest + ): + request = benchmarks_service.GenerateBenchmarksMetricsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if location is not None: + request.location = location + if benchmarks_source is not None: + request.benchmarks_source = benchmarks_source + if product_filter is not None: + request.product_filter = product_filter + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_benchmarks_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "BenchmarksServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("BenchmarksServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/benchmarks_service/client.py b/google/ads/googleads/v23/services/services/benchmarks_service/client.py new file mode 100644 index 000000000..3cd3b3742 --- /dev/null +++ b/google/ads/googleads/v23/services/services/benchmarks_service/client.py @@ -0,0 +1,1182 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import benchmarks_source_type +from google.ads.googleads.v23.services.types import benchmarks_service +from .transports.base import BenchmarksServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import BenchmarksServiceGrpcTransport +from .transports.grpc_asyncio import BenchmarksServiceGrpcAsyncIOTransport + + +class BenchmarksServiceClientMeta(type): + """Metaclass for the BenchmarksService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BenchmarksServiceTransport]] + _transport_registry["grpc"] = BenchmarksServiceGrpcTransport + _transport_registry["grpc_asyncio"] = BenchmarksServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[BenchmarksServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BenchmarksServiceClient(metaclass=BenchmarksServiceClientMeta): + """BenchmarksService helps users compare YouTube advertisement + data against industry benchmarks. Accessible to allowlisted + customers only. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BenchmarksServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BenchmarksServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BenchmarksServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BenchmarksServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = BenchmarksServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = BenchmarksServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = BenchmarksServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = BenchmarksServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + BenchmarksServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = BenchmarksServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BenchmarksServiceTransport, + Callable[..., BenchmarksServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the benchmarks service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BenchmarksServiceTransport,Callable[..., BenchmarksServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BenchmarksServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = BenchmarksServiceClient._read_environment_variables() + self._client_cert_source = ( + BenchmarksServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = BenchmarksServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, BenchmarksServiceTransport) + if transport_provided: + # transport is a BenchmarksServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(BenchmarksServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or BenchmarksServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[BenchmarksServiceTransport], + Callable[..., BenchmarksServiceTransport], + ] = ( + BenchmarksServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., BenchmarksServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.BenchmarksServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BenchmarksService", + "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.ads.googleads.v23.services.BenchmarksService", + "credentialsType": None, + } + ), + ) + + def list_benchmarks_available_dates( + self, + request: Optional[ + Union[benchmarks_service.ListBenchmarksAvailableDatesRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> benchmarks_service.ListBenchmarksAvailableDatesResponse: + r"""Returns a date range that supports benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListBenchmarksAvailableDatesRequest, dict]): + The request object. Request message for + [BenchmarksService.ListBenchmarksAvailableDates][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksAvailableDates]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListBenchmarksAvailableDatesResponse: + Response message for + [BenchmarksService.ListBenchmarksAvailableDates][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksAvailableDates]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, benchmarks_service.ListBenchmarksAvailableDatesRequest + ): + request = benchmarks_service.ListBenchmarksAvailableDatesRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_benchmarks_available_dates + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_benchmarks_locations( + self, + request: Optional[ + Union[benchmarks_service.ListBenchmarksLocationsRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> benchmarks_service.ListBenchmarksLocationsResponse: + r"""Returns the list of locations that support benchmarks (for + example, countries). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListBenchmarksLocationsRequest, dict]): + The request object. Request message for + [BenchmarksService.ListBenchmarksLocations][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksLocations]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListBenchmarksLocationsResponse: + Response message for + [BenchmarksService.ListBenchmarksLocations][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksLocations]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, benchmarks_service.ListBenchmarksLocationsRequest + ): + request = benchmarks_service.ListBenchmarksLocationsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_benchmarks_locations + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_benchmarks_products( + self, + request: Optional[ + Union[benchmarks_service.ListBenchmarksProductsRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> benchmarks_service.ListBenchmarksProductsResponse: + r"""Returns the list of products that supports benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListBenchmarksProductsRequest, dict]): + The request object. Request message for + [BenchmarksService.ListBenchmarksProducts][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksProducts]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListBenchmarksProductsResponse: + Response message for + [BenchmarksService.ListBenchmarksProducts][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksProducts]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, benchmarks_service.ListBenchmarksProductsRequest + ): + request = benchmarks_service.ListBenchmarksProductsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_benchmarks_products + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_benchmarks_sources( + self, + request: Optional[ + Union[benchmarks_service.ListBenchmarksSourcesRequest, dict] + ] = None, + *, + benchmarks_sources: Optional[ + MutableSequence[ + benchmarks_source_type.BenchmarksSourceTypeEnum.BenchmarksSourceType + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> benchmarks_service.ListBenchmarksSourcesResponse: + r"""Returns the list of benchmarks sources (for example, Industry + Verticals). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListBenchmarksSourcesRequest, dict]): + The request object. Request message for + [BenchmarksService.ListBenchmarksSources][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksSources]. + benchmarks_sources (MutableSequence[google.ads.googleads.v23.enums.types.BenchmarksSourceTypeEnum.BenchmarksSourceType]): + Required. The types of benchmarks sources to be returned + (for example, INDUSTRY_VERTICAL). + + This corresponds to the ``benchmarks_sources`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListBenchmarksSourcesResponse: + Response message for + [BenchmarksService.ListBenchmarksSources][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksSources]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [benchmarks_sources] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, benchmarks_service.ListBenchmarksSourcesRequest + ): + request = benchmarks_service.ListBenchmarksSourcesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if benchmarks_sources is not None: + request.benchmarks_sources = benchmarks_sources + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_benchmarks_sources + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_benchmarks_metrics( + self, + request: Optional[ + Union[benchmarks_service.GenerateBenchmarksMetricsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + location: Optional[criteria.LocationInfo] = None, + benchmarks_source: Optional[benchmarks_service.BenchmarksSource] = None, + product_filter: Optional[benchmarks_service.ProductFilter] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> benchmarks_service.GenerateBenchmarksMetricsResponse: + r"""Returns YouTube advertisement metrics for the given client + against industry benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BenchmarksError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateBenchmarksMetricsRequest, dict]): + The request object. Request message for + [BenchmarksService.GenerateBenchmarksMetrics][google.ads.googleads.v23.services.BenchmarksService.GenerateBenchmarksMetrics]. + customer_id (str): + Required. The ID of the customer. + Supply a client customer ID to generate + metrics for the customer. A manager + account customer ID will not return + customer metrics since it does not have + any associated direct ad campaigns. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + location (google.ads.googleads.v23.common.types.LocationInfo): + Required. The location to generate + benchmarks metrics for. + + This corresponds to the ``location`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + benchmarks_source (google.ads.googleads.v23.services.types.BenchmarksSource): + Required. The source used to generate + benchmarks metrics for. + + This corresponds to the ``benchmarks_source`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_filter (google.ads.googleads.v23.services.types.ProductFilter): + Required. The products to aggregate + metrics over. Product filter settings + support a list of product IDs or a list + of marketing objectives. + + This corresponds to the ``product_filter`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateBenchmarksMetricsResponse: + Response message for + [BenchmarksService.GenerateBenchmarksMetrics][google.ads.googleads.v23.services.BenchmarksService.GenerateBenchmarksMetrics]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + location, + benchmarks_source, + product_filter, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, benchmarks_service.GenerateBenchmarksMetricsRequest + ): + request = benchmarks_service.GenerateBenchmarksMetricsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if location is not None: + request.location = location + if benchmarks_source is not None: + request.benchmarks_source = benchmarks_source + if product_filter is not None: + request.product_filter = product_filter + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_benchmarks_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "BenchmarksServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("BenchmarksServiceClient",) diff --git a/google/ads/googleads/v23/services/services/benchmarks_service/transports/README.rst b/google/ads/googleads/v23/services/services/benchmarks_service/transports/README.rst new file mode 100644 index 000000000..ba78523ab --- /dev/null +++ b/google/ads/googleads/v23/services/services/benchmarks_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`BenchmarksServiceTransport` is the ABC for all transports. +- public child `BenchmarksServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `BenchmarksServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseBenchmarksServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `BenchmarksServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/google/ads/googleads/v23/services/services/benchmarks_service/transports/__init__.py b/google/ads/googleads/v23/services/services/benchmarks_service/transports/__init__.py new file mode 100644 index 000000000..7bf4c663b --- /dev/null +++ b/google/ads/googleads/v23/services/services/benchmarks_service/transports/__init__.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict + +from .base import BenchmarksServiceTransport +from .grpc import BenchmarksServiceGrpcTransport +from .grpc_asyncio import BenchmarksServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[BenchmarksServiceTransport]] +_transport_registry["grpc"] = BenchmarksServiceGrpcTransport +_transport_registry["grpc_asyncio"] = BenchmarksServiceGrpcAsyncIOTransport + +__all__ = ( + "BenchmarksServiceTransport", + "BenchmarksServiceGrpcTransport", + "BenchmarksServiceGrpcAsyncIOTransport", +) diff --git a/google/ads/googleads/v23/services/services/benchmarks_service/transports/base.py b/google/ads/googleads/v23/services/services/benchmarks_service/transports/base.py new file mode 100644 index 000000000..c906e8c50 --- /dev/null +++ b/google/ads/googleads/v23/services/services/benchmarks_service/transports/base.py @@ -0,0 +1,241 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import benchmarks_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class BenchmarksServiceTransport(abc.ABC): + """Abstract transport class for BenchmarksService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_benchmarks_available_dates: gapic_v1.method.wrap_method( + self.list_benchmarks_available_dates, + default_timeout=None, + client_info=client_info, + ), + self.list_benchmarks_locations: gapic_v1.method.wrap_method( + self.list_benchmarks_locations, + default_timeout=None, + client_info=client_info, + ), + self.list_benchmarks_products: gapic_v1.method.wrap_method( + self.list_benchmarks_products, + default_timeout=None, + client_info=client_info, + ), + self.list_benchmarks_sources: gapic_v1.method.wrap_method( + self.list_benchmarks_sources, + default_timeout=None, + client_info=client_info, + ), + self.generate_benchmarks_metrics: gapic_v1.method.wrap_method( + self.generate_benchmarks_metrics, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def list_benchmarks_available_dates( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksAvailableDatesRequest], + Union[ + benchmarks_service.ListBenchmarksAvailableDatesResponse, + Awaitable[benchmarks_service.ListBenchmarksAvailableDatesResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_benchmarks_locations( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksLocationsRequest], + Union[ + benchmarks_service.ListBenchmarksLocationsResponse, + Awaitable[benchmarks_service.ListBenchmarksLocationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_benchmarks_products( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksProductsRequest], + Union[ + benchmarks_service.ListBenchmarksProductsResponse, + Awaitable[benchmarks_service.ListBenchmarksProductsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_benchmarks_sources( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksSourcesRequest], + Union[ + benchmarks_service.ListBenchmarksSourcesResponse, + Awaitable[benchmarks_service.ListBenchmarksSourcesResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_benchmarks_metrics( + self, + ) -> Callable[ + [benchmarks_service.GenerateBenchmarksMetricsRequest], + Union[ + benchmarks_service.GenerateBenchmarksMetricsResponse, + Awaitable[benchmarks_service.GenerateBenchmarksMetricsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("BenchmarksServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/benchmarks_service/transports/grpc.py b/google/ads/googleads/v23/services/services/benchmarks_service/transports/grpc.py new file mode 100644 index 000000000..68432ce69 --- /dev/null +++ b/google/ads/googleads/v23/services/services/benchmarks_service/transports/grpc.py @@ -0,0 +1,534 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import benchmarks_service +from .base import BenchmarksServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.BenchmarksService", + "rpcName": str(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.ads.googleads.v23.services.BenchmarksService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BenchmarksServiceGrpcTransport(BenchmarksServiceTransport): + """gRPC backend transport for BenchmarksService. + + BenchmarksService helps users compare YouTube advertisement + data against industry benchmarks. Accessible to allowlisted + customers only. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def list_benchmarks_available_dates( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksAvailableDatesRequest], + benchmarks_service.ListBenchmarksAvailableDatesResponse, + ]: + r"""Return a callable for the list benchmarks available + dates method over gRPC. + + Returns a date range that supports benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListBenchmarksAvailableDatesRequest], + ~.ListBenchmarksAvailableDatesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_benchmarks_available_dates" not in self._stubs: + self._stubs["list_benchmarks_available_dates"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BenchmarksService/ListBenchmarksAvailableDates", + request_serializer=benchmarks_service.ListBenchmarksAvailableDatesRequest.serialize, + response_deserializer=benchmarks_service.ListBenchmarksAvailableDatesResponse.deserialize, + ) + ) + return self._stubs["list_benchmarks_available_dates"] + + @property + def list_benchmarks_locations( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksLocationsRequest], + benchmarks_service.ListBenchmarksLocationsResponse, + ]: + r"""Return a callable for the list benchmarks locations method over gRPC. + + Returns the list of locations that support benchmarks (for + example, countries). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListBenchmarksLocationsRequest], + ~.ListBenchmarksLocationsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_benchmarks_locations" not in self._stubs: + self._stubs["list_benchmarks_locations"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BenchmarksService/ListBenchmarksLocations", + request_serializer=benchmarks_service.ListBenchmarksLocationsRequest.serialize, + response_deserializer=benchmarks_service.ListBenchmarksLocationsResponse.deserialize, + ) + ) + return self._stubs["list_benchmarks_locations"] + + @property + def list_benchmarks_products( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksProductsRequest], + benchmarks_service.ListBenchmarksProductsResponse, + ]: + r"""Return a callable for the list benchmarks products method over gRPC. + + Returns the list of products that supports benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListBenchmarksProductsRequest], + ~.ListBenchmarksProductsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_benchmarks_products" not in self._stubs: + self._stubs["list_benchmarks_products"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BenchmarksService/ListBenchmarksProducts", + request_serializer=benchmarks_service.ListBenchmarksProductsRequest.serialize, + response_deserializer=benchmarks_service.ListBenchmarksProductsResponse.deserialize, + ) + ) + return self._stubs["list_benchmarks_products"] + + @property + def list_benchmarks_sources( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksSourcesRequest], + benchmarks_service.ListBenchmarksSourcesResponse, + ]: + r"""Return a callable for the list benchmarks sources method over gRPC. + + Returns the list of benchmarks sources (for example, Industry + Verticals). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListBenchmarksSourcesRequest], + ~.ListBenchmarksSourcesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_benchmarks_sources" not in self._stubs: + self._stubs["list_benchmarks_sources"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BenchmarksService/ListBenchmarksSources", + request_serializer=benchmarks_service.ListBenchmarksSourcesRequest.serialize, + response_deserializer=benchmarks_service.ListBenchmarksSourcesResponse.deserialize, + ) + ) + return self._stubs["list_benchmarks_sources"] + + @property + def generate_benchmarks_metrics( + self, + ) -> Callable[ + [benchmarks_service.GenerateBenchmarksMetricsRequest], + benchmarks_service.GenerateBenchmarksMetricsResponse, + ]: + r"""Return a callable for the generate benchmarks metrics method over gRPC. + + Returns YouTube advertisement metrics for the given client + against industry benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BenchmarksError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateBenchmarksMetricsRequest], + ~.GenerateBenchmarksMetricsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_benchmarks_metrics" not in self._stubs: + self._stubs["generate_benchmarks_metrics"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BenchmarksService/GenerateBenchmarksMetrics", + request_serializer=benchmarks_service.GenerateBenchmarksMetricsRequest.serialize, + response_deserializer=benchmarks_service.GenerateBenchmarksMetricsResponse.deserialize, + ) + ) + return self._stubs["generate_benchmarks_metrics"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("BenchmarksServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/benchmarks_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/benchmarks_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..1d2f493c4 --- /dev/null +++ b/google/ads/googleads/v23/services/services/benchmarks_service/transports/grpc_asyncio.py @@ -0,0 +1,575 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import benchmarks_service +from .base import BenchmarksServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.BenchmarksService", + "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.ads.googleads.v23.services.BenchmarksService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BenchmarksServiceGrpcAsyncIOTransport(BenchmarksServiceTransport): + """gRPC AsyncIO backend transport for BenchmarksService. + + BenchmarksService helps users compare YouTube advertisement + data against industry benchmarks. Accessible to allowlisted + customers only. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def list_benchmarks_available_dates( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksAvailableDatesRequest], + Awaitable[benchmarks_service.ListBenchmarksAvailableDatesResponse], + ]: + r"""Return a callable for the list benchmarks available + dates method over gRPC. + + Returns a date range that supports benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListBenchmarksAvailableDatesRequest], + Awaitable[~.ListBenchmarksAvailableDatesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_benchmarks_available_dates" not in self._stubs: + self._stubs["list_benchmarks_available_dates"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BenchmarksService/ListBenchmarksAvailableDates", + request_serializer=benchmarks_service.ListBenchmarksAvailableDatesRequest.serialize, + response_deserializer=benchmarks_service.ListBenchmarksAvailableDatesResponse.deserialize, + ) + ) + return self._stubs["list_benchmarks_available_dates"] + + @property + def list_benchmarks_locations( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksLocationsRequest], + Awaitable[benchmarks_service.ListBenchmarksLocationsResponse], + ]: + r"""Return a callable for the list benchmarks locations method over gRPC. + + Returns the list of locations that support benchmarks (for + example, countries). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListBenchmarksLocationsRequest], + Awaitable[~.ListBenchmarksLocationsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_benchmarks_locations" not in self._stubs: + self._stubs["list_benchmarks_locations"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BenchmarksService/ListBenchmarksLocations", + request_serializer=benchmarks_service.ListBenchmarksLocationsRequest.serialize, + response_deserializer=benchmarks_service.ListBenchmarksLocationsResponse.deserialize, + ) + ) + return self._stubs["list_benchmarks_locations"] + + @property + def list_benchmarks_products( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksProductsRequest], + Awaitable[benchmarks_service.ListBenchmarksProductsResponse], + ]: + r"""Return a callable for the list benchmarks products method over gRPC. + + Returns the list of products that supports benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListBenchmarksProductsRequest], + Awaitable[~.ListBenchmarksProductsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_benchmarks_products" not in self._stubs: + self._stubs["list_benchmarks_products"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BenchmarksService/ListBenchmarksProducts", + request_serializer=benchmarks_service.ListBenchmarksProductsRequest.serialize, + response_deserializer=benchmarks_service.ListBenchmarksProductsResponse.deserialize, + ) + ) + return self._stubs["list_benchmarks_products"] + + @property + def list_benchmarks_sources( + self, + ) -> Callable[ + [benchmarks_service.ListBenchmarksSourcesRequest], + Awaitable[benchmarks_service.ListBenchmarksSourcesResponse], + ]: + r"""Return a callable for the list benchmarks sources method over gRPC. + + Returns the list of benchmarks sources (for example, Industry + Verticals). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListBenchmarksSourcesRequest], + Awaitable[~.ListBenchmarksSourcesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_benchmarks_sources" not in self._stubs: + self._stubs["list_benchmarks_sources"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BenchmarksService/ListBenchmarksSources", + request_serializer=benchmarks_service.ListBenchmarksSourcesRequest.serialize, + response_deserializer=benchmarks_service.ListBenchmarksSourcesResponse.deserialize, + ) + ) + return self._stubs["list_benchmarks_sources"] + + @property + def generate_benchmarks_metrics( + self, + ) -> Callable[ + [benchmarks_service.GenerateBenchmarksMetricsRequest], + Awaitable[benchmarks_service.GenerateBenchmarksMetricsResponse], + ]: + r"""Return a callable for the generate benchmarks metrics method over gRPC. + + Returns YouTube advertisement metrics for the given client + against industry benchmarks. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BenchmarksError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateBenchmarksMetricsRequest], + Awaitable[~.GenerateBenchmarksMetricsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_benchmarks_metrics" not in self._stubs: + self._stubs["generate_benchmarks_metrics"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BenchmarksService/GenerateBenchmarksMetrics", + request_serializer=benchmarks_service.GenerateBenchmarksMetricsRequest.serialize, + response_deserializer=benchmarks_service.GenerateBenchmarksMetricsResponse.deserialize, + ) + ) + return self._stubs["generate_benchmarks_metrics"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.list_benchmarks_available_dates: self._wrap_method( + self.list_benchmarks_available_dates, + default_timeout=None, + client_info=client_info, + ), + self.list_benchmarks_locations: self._wrap_method( + self.list_benchmarks_locations, + default_timeout=None, + client_info=client_info, + ), + self.list_benchmarks_products: self._wrap_method( + self.list_benchmarks_products, + default_timeout=None, + client_info=client_info, + ), + self.list_benchmarks_sources: self._wrap_method( + self.list_benchmarks_sources, + default_timeout=None, + client_info=client_info, + ), + self.generate_benchmarks_metrics: self._wrap_method( + self.generate_benchmarks_metrics, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("BenchmarksServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/__init__.py b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/bidding_data_exclusion_service/__init__.py rename to google/ads/googleads/v23/services/services/bidding_data_exclusion_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/async_client.py b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/async_client.py new file mode 100644 index 000000000..d6a7b83d2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/async_client.py @@ -0,0 +1,439 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + bidding_data_exclusion_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + BiddingDataExclusionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import BiddingDataExclusionServiceClient + +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 BiddingDataExclusionServiceAsyncClient: + """Service to manage bidding data exclusions.""" + + _client: BiddingDataExclusionServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = BiddingDataExclusionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + BiddingDataExclusionServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + BiddingDataExclusionServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = BiddingDataExclusionServiceClient._DEFAULT_UNIVERSE + + bidding_data_exclusion_path = staticmethod( + BiddingDataExclusionServiceClient.bidding_data_exclusion_path + ) + parse_bidding_data_exclusion_path = staticmethod( + BiddingDataExclusionServiceClient.parse_bidding_data_exclusion_path + ) + campaign_path = staticmethod( + BiddingDataExclusionServiceClient.campaign_path + ) + parse_campaign_path = staticmethod( + BiddingDataExclusionServiceClient.parse_campaign_path + ) + common_billing_account_path = staticmethod( + BiddingDataExclusionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + BiddingDataExclusionServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + BiddingDataExclusionServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + BiddingDataExclusionServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + BiddingDataExclusionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + BiddingDataExclusionServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + BiddingDataExclusionServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + BiddingDataExclusionServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + BiddingDataExclusionServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + BiddingDataExclusionServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingDataExclusionServiceAsyncClient: The constructed client. + """ + return BiddingDataExclusionServiceClient.from_service_account_info.__func__(BiddingDataExclusionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingDataExclusionServiceAsyncClient: The constructed client. + """ + return BiddingDataExclusionServiceClient.from_service_account_file.__func__(BiddingDataExclusionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return BiddingDataExclusionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> BiddingDataExclusionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BiddingDataExclusionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = BiddingDataExclusionServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BiddingDataExclusionServiceTransport, + Callable[..., BiddingDataExclusionServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the bidding data exclusion service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BiddingDataExclusionServiceTransport,Callable[..., BiddingDataExclusionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BiddingDataExclusionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = BiddingDataExclusionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.BiddingDataExclusionServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BiddingDataExclusionService", + "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.ads.googleads.v23.services.BiddingDataExclusionService", + "credentialsType": None, + } + ), + ) + + async def mutate_bidding_data_exclusions( + self, + request: Optional[ + Union[ + bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + bidding_data_exclusion_service.BiddingDataExclusionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse: + r"""Creates, updates, or removes data exclusions. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateBiddingDataExclusionsRequest, dict]]): + The request object. Request message for + [BiddingDataExclusionService.MutateBiddingDataExclusions][google.ads.googleads.v23.services.BiddingDataExclusionService.MutateBiddingDataExclusions]. + customer_id (:class:`str`): + Required. ID of the customer whose + data exclusions are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.BiddingDataExclusionOperation]`): + Required. The list of operations to + perform on individual data exclusions. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateBiddingDataExclusionsResponse: + Response message for data exclusions + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest, + ): + request = bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_bidding_data_exclusions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "BiddingDataExclusionServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("BiddingDataExclusionServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/client.py b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/client.py new file mode 100644 index 000000000..ddb7c670d --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/client.py @@ -0,0 +1,936 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + bidding_data_exclusion_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + BiddingDataExclusionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import BiddingDataExclusionServiceGrpcTransport +from .transports.grpc_asyncio import ( + BiddingDataExclusionServiceGrpcAsyncIOTransport, +) + + +class BiddingDataExclusionServiceClientMeta(type): + """Metaclass for the BiddingDataExclusionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BiddingDataExclusionServiceTransport]] + _transport_registry["grpc"] = BiddingDataExclusionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + BiddingDataExclusionServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[BiddingDataExclusionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BiddingDataExclusionServiceClient( + metaclass=BiddingDataExclusionServiceClientMeta +): + """Service to manage bidding data exclusions.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingDataExclusionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingDataExclusionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BiddingDataExclusionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BiddingDataExclusionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def bidding_data_exclusion_path( + customer_id: str, + seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_data_exclusion string.""" + return "customers/{customer_id}/biddingDataExclusions/{seasonality_event_id}".format( + customer_id=customer_id, + seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_data_exclusion_path(path: str) -> Dict[str, str]: + """Parses a bidding_data_exclusion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingDataExclusions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + BiddingDataExclusionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + BiddingDataExclusionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + BiddingDataExclusionServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + BiddingDataExclusionServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = BiddingDataExclusionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = BiddingDataExclusionServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BiddingDataExclusionServiceTransport, + Callable[..., BiddingDataExclusionServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the bidding data exclusion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BiddingDataExclusionServiceTransport,Callable[..., BiddingDataExclusionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BiddingDataExclusionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = BiddingDataExclusionServiceClient._read_environment_variables() + self._client_cert_source = ( + BiddingDataExclusionServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + BiddingDataExclusionServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, BiddingDataExclusionServiceTransport + ) + if transport_provided: + # transport is a BiddingDataExclusionServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + BiddingDataExclusionServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or BiddingDataExclusionServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[BiddingDataExclusionServiceTransport], + Callable[..., BiddingDataExclusionServiceTransport], + ] = ( + BiddingDataExclusionServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., BiddingDataExclusionServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.BiddingDataExclusionServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BiddingDataExclusionService", + "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.ads.googleads.v23.services.BiddingDataExclusionService", + "credentialsType": None, + } + ), + ) + + def mutate_bidding_data_exclusions( + self, + request: Optional[ + Union[ + bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + bidding_data_exclusion_service.BiddingDataExclusionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse: + r"""Creates, updates, or removes data exclusions. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateBiddingDataExclusionsRequest, dict]): + The request object. Request message for + [BiddingDataExclusionService.MutateBiddingDataExclusions][google.ads.googleads.v23.services.BiddingDataExclusionService.MutateBiddingDataExclusions]. + customer_id (str): + Required. ID of the customer whose + data exclusions are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.BiddingDataExclusionOperation]): + Required. The list of operations to + perform on individual data exclusions. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateBiddingDataExclusionsResponse: + Response message for data exclusions + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest, + ): + request = bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_bidding_data_exclusions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "BiddingDataExclusionServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("BiddingDataExclusionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/README.rst b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/README.rst rename to google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/__init__.py b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/bidding_data_exclusion_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/base.py b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/base.py new file mode 100644 index 000000000..522be494c --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + bidding_data_exclusion_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class BiddingDataExclusionServiceTransport(abc.ABC): + """Abstract transport class for BiddingDataExclusionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_bidding_data_exclusions: gapic_v1.method.wrap_method( + self.mutate_bidding_data_exclusions, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_bidding_data_exclusions( + self, + ) -> Callable[ + [bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest], + Union[ + bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse, + Awaitable[ + bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("BiddingDataExclusionServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/grpc.py b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/grpc.py new file mode 100644 index 000000000..21a5ab440 --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/grpc.py @@ -0,0 +1,388 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + bidding_data_exclusion_service, +) +from .base import BiddingDataExclusionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.BiddingDataExclusionService", + "rpcName": str(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.ads.googleads.v23.services.BiddingDataExclusionService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BiddingDataExclusionServiceGrpcTransport( + BiddingDataExclusionServiceTransport +): + """gRPC backend transport for BiddingDataExclusionService. + + Service to manage bidding data exclusions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_bidding_data_exclusions( + self, + ) -> Callable[ + [bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest], + bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse, + ]: + r"""Return a callable for the mutate bidding data exclusions method over gRPC. + + Creates, updates, or removes data exclusions. + Operation statuses are returned. + + Returns: + Callable[[~.MutateBiddingDataExclusionsRequest], + ~.MutateBiddingDataExclusionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_bidding_data_exclusions" not in self._stubs: + self._stubs["mutate_bidding_data_exclusions"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BiddingDataExclusionService/MutateBiddingDataExclusions", + request_serializer=bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest.serialize, + response_deserializer=bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse.deserialize, + ) + ) + return self._stubs["mutate_bidding_data_exclusions"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("BiddingDataExclusionServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..4742d9a3e --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_data_exclusion_service/transports/grpc_asyncio.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + bidding_data_exclusion_service, +) +from .base import BiddingDataExclusionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.BiddingDataExclusionService", + "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.ads.googleads.v23.services.BiddingDataExclusionService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BiddingDataExclusionServiceGrpcAsyncIOTransport( + BiddingDataExclusionServiceTransport +): + """gRPC AsyncIO backend transport for BiddingDataExclusionService. + + Service to manage bidding data exclusions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_bidding_data_exclusions( + self, + ) -> Callable[ + [bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest], + Awaitable[ + bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse + ], + ]: + r"""Return a callable for the mutate bidding data exclusions method over gRPC. + + Creates, updates, or removes data exclusions. + Operation statuses are returned. + + Returns: + Callable[[~.MutateBiddingDataExclusionsRequest], + Awaitable[~.MutateBiddingDataExclusionsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_bidding_data_exclusions" not in self._stubs: + self._stubs["mutate_bidding_data_exclusions"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BiddingDataExclusionService/MutateBiddingDataExclusions", + request_serializer=bidding_data_exclusion_service.MutateBiddingDataExclusionsRequest.serialize, + response_deserializer=bidding_data_exclusion_service.MutateBiddingDataExclusionsResponse.deserialize, + ) + ) + return self._stubs["mutate_bidding_data_exclusions"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_bidding_data_exclusions: self._wrap_method( + self.mutate_bidding_data_exclusions, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("BiddingDataExclusionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/__init__.py b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/__init__.py rename to google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/async_client.py b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/async_client.py new file mode 100644 index 000000000..702e3bc9f --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/async_client.py @@ -0,0 +1,451 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + bidding_seasonality_adjustment_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + BiddingSeasonalityAdjustmentServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import BiddingSeasonalityAdjustmentServiceClient + +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 BiddingSeasonalityAdjustmentServiceAsyncClient: + """Service to manage bidding seasonality adjustments.""" + + _client: BiddingSeasonalityAdjustmentServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ( + BiddingSeasonalityAdjustmentServiceClient.DEFAULT_ENDPOINT + ) + DEFAULT_MTLS_ENDPOINT = ( + BiddingSeasonalityAdjustmentServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + BiddingSeasonalityAdjustmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ( + BiddingSeasonalityAdjustmentServiceClient._DEFAULT_UNIVERSE + ) + + bidding_seasonality_adjustment_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.bidding_seasonality_adjustment_path + ) + parse_bidding_seasonality_adjustment_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.parse_bidding_seasonality_adjustment_path + ) + campaign_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.campaign_path + ) + parse_campaign_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.parse_campaign_path + ) + common_billing_account_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + BiddingSeasonalityAdjustmentServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingSeasonalityAdjustmentServiceAsyncClient: The constructed client. + """ + return BiddingSeasonalityAdjustmentServiceClient.from_service_account_info.__func__(BiddingSeasonalityAdjustmentServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingSeasonalityAdjustmentServiceAsyncClient: The constructed client. + """ + return BiddingSeasonalityAdjustmentServiceClient.from_service_account_file.__func__(BiddingSeasonalityAdjustmentServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return BiddingSeasonalityAdjustmentServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> BiddingSeasonalityAdjustmentServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BiddingSeasonalityAdjustmentServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + BiddingSeasonalityAdjustmentServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BiddingSeasonalityAdjustmentServiceTransport, + Callable[..., BiddingSeasonalityAdjustmentServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the bidding seasonality adjustment service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BiddingSeasonalityAdjustmentServiceTransport,Callable[..., BiddingSeasonalityAdjustmentServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BiddingSeasonalityAdjustmentServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = BiddingSeasonalityAdjustmentServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.BiddingSeasonalityAdjustmentServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService", + "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.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService", + "credentialsType": None, + } + ), + ) + + async def mutate_bidding_seasonality_adjustments( + self, + request: Optional[ + Union[ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + bidding_seasonality_adjustment_service.BiddingSeasonalityAdjustmentOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse + ): + r"""Creates, updates, or removes seasonality adjustments. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateBiddingSeasonalityAdjustmentsRequest, dict]]): + The request object. Request message for + [BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments][google.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments]. + customer_id (:class:`str`): + Required. ID of the customer whose + seasonality adjustments are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.BiddingSeasonalityAdjustmentOperation]`): + Required. The list of operations to + perform on individual seasonality + adjustments. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateBiddingSeasonalityAdjustmentsResponse: + Response message for seasonality + adjustments mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest, + ): + request = bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_bidding_seasonality_adjustments + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__( + self, + ) -> "BiddingSeasonalityAdjustmentServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("BiddingSeasonalityAdjustmentServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/client.py b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/client.py new file mode 100644 index 000000000..48672ce89 --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/client.py @@ -0,0 +1,948 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + bidding_seasonality_adjustment_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + BiddingSeasonalityAdjustmentServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import BiddingSeasonalityAdjustmentServiceGrpcTransport +from .transports.grpc_asyncio import ( + BiddingSeasonalityAdjustmentServiceGrpcAsyncIOTransport, +) + + +class BiddingSeasonalityAdjustmentServiceClientMeta(type): + """Metaclass for the BiddingSeasonalityAdjustmentService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BiddingSeasonalityAdjustmentServiceTransport]] + _transport_registry["grpc"] = ( + BiddingSeasonalityAdjustmentServiceGrpcTransport + ) + _transport_registry["grpc_asyncio"] = ( + BiddingSeasonalityAdjustmentServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[BiddingSeasonalityAdjustmentServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BiddingSeasonalityAdjustmentServiceClient( + metaclass=BiddingSeasonalityAdjustmentServiceClientMeta +): + """Service to manage bidding seasonality adjustments.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingSeasonalityAdjustmentServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingSeasonalityAdjustmentServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BiddingSeasonalityAdjustmentServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BiddingSeasonalityAdjustmentServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def bidding_seasonality_adjustment_path( + customer_id: str, + seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_seasonality_adjustment string.""" + return "customers/{customer_id}/biddingSeasonalityAdjustments/{seasonality_event_id}".format( + customer_id=customer_id, + seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_seasonality_adjustment_path(path: str) -> Dict[str, str]: + """Parses a bidding_seasonality_adjustment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingSeasonalityAdjustments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + BiddingSeasonalityAdjustmentServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + BiddingSeasonalityAdjustmentServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + BiddingSeasonalityAdjustmentServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + BiddingSeasonalityAdjustmentServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = BiddingSeasonalityAdjustmentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + BiddingSeasonalityAdjustmentServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BiddingSeasonalityAdjustmentServiceTransport, + Callable[..., BiddingSeasonalityAdjustmentServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the bidding seasonality adjustment service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BiddingSeasonalityAdjustmentServiceTransport,Callable[..., BiddingSeasonalityAdjustmentServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BiddingSeasonalityAdjustmentServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ( + BiddingSeasonalityAdjustmentServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + BiddingSeasonalityAdjustmentServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + BiddingSeasonalityAdjustmentServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, BiddingSeasonalityAdjustmentServiceTransport + ) + if transport_provided: + # transport is a BiddingSeasonalityAdjustmentServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + BiddingSeasonalityAdjustmentServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or BiddingSeasonalityAdjustmentServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[BiddingSeasonalityAdjustmentServiceTransport], + Callable[..., BiddingSeasonalityAdjustmentServiceTransport], + ] = ( + BiddingSeasonalityAdjustmentServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., BiddingSeasonalityAdjustmentServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.BiddingSeasonalityAdjustmentServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService", + "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.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService", + "credentialsType": None, + } + ), + ) + + def mutate_bidding_seasonality_adjustments( + self, + request: Optional[ + Union[ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + bidding_seasonality_adjustment_service.BiddingSeasonalityAdjustmentOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse + ): + r"""Creates, updates, or removes seasonality adjustments. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateBiddingSeasonalityAdjustmentsRequest, dict]): + The request object. Request message for + [BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments][google.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments]. + customer_id (str): + Required. ID of the customer whose + seasonality adjustments are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.BiddingSeasonalityAdjustmentOperation]): + Required. The list of operations to + perform on individual seasonality + adjustments. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateBiddingSeasonalityAdjustmentsResponse: + Response message for seasonality + adjustments mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest, + ): + request = bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_bidding_seasonality_adjustments + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "BiddingSeasonalityAdjustmentServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("BiddingSeasonalityAdjustmentServiceClient",) diff --git a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/README.rst b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/README.rst rename to google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/__init__.py b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/bidding_seasonality_adjustment_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/base.py b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/base.py new file mode 100644 index 000000000..864d5dde5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + bidding_seasonality_adjustment_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class BiddingSeasonalityAdjustmentServiceTransport(abc.ABC): + """Abstract transport class for BiddingSeasonalityAdjustmentService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_bidding_seasonality_adjustments: gapic_v1.method.wrap_method( + self.mutate_bidding_seasonality_adjustments, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_bidding_seasonality_adjustments( + self, + ) -> Callable[ + [ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest + ], + Union[ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse, + Awaitable[ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("BiddingSeasonalityAdjustmentServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/grpc.py b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/grpc.py new file mode 100644 index 000000000..5577e200f --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/grpc.py @@ -0,0 +1,394 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + bidding_seasonality_adjustment_service, +) +from .base import ( + BiddingSeasonalityAdjustmentServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService", + "rpcName": str(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.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BiddingSeasonalityAdjustmentServiceGrpcTransport( + BiddingSeasonalityAdjustmentServiceTransport +): + """gRPC backend transport for BiddingSeasonalityAdjustmentService. + + Service to manage bidding seasonality adjustments. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_bidding_seasonality_adjustments( + self, + ) -> Callable[ + [ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest + ], + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse, + ]: + r"""Return a callable for the mutate bidding seasonality + adjustments method over gRPC. + + Creates, updates, or removes seasonality adjustments. + Operation statuses are returned. + + Returns: + Callable[[~.MutateBiddingSeasonalityAdjustmentsRequest], + ~.MutateBiddingSeasonalityAdjustmentsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_bidding_seasonality_adjustments" not in self._stubs: + self._stubs["mutate_bidding_seasonality_adjustments"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService/MutateBiddingSeasonalityAdjustments", + request_serializer=bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest.serialize, + response_deserializer=bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse.deserialize, + ) + ) + return self._stubs["mutate_bidding_seasonality_adjustments"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("BiddingSeasonalityAdjustmentServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..19e18d5cb --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_seasonality_adjustment_service/transports/grpc_asyncio.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + bidding_seasonality_adjustment_service, +) +from .base import ( + BiddingSeasonalityAdjustmentServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService", + "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.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BiddingSeasonalityAdjustmentServiceGrpcAsyncIOTransport( + BiddingSeasonalityAdjustmentServiceTransport +): + """gRPC AsyncIO backend transport for BiddingSeasonalityAdjustmentService. + + Service to manage bidding seasonality adjustments. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_bidding_seasonality_adjustments( + self, + ) -> Callable[ + [ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest + ], + Awaitable[ + bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse + ], + ]: + r"""Return a callable for the mutate bidding seasonality + adjustments method over gRPC. + + Creates, updates, or removes seasonality adjustments. + Operation statuses are returned. + + Returns: + Callable[[~.MutateBiddingSeasonalityAdjustmentsRequest], + Awaitable[~.MutateBiddingSeasonalityAdjustmentsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_bidding_seasonality_adjustments" not in self._stubs: + self._stubs["mutate_bidding_seasonality_adjustments"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService/MutateBiddingSeasonalityAdjustments", + request_serializer=bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsRequest.serialize, + response_deserializer=bidding_seasonality_adjustment_service.MutateBiddingSeasonalityAdjustmentsResponse.deserialize, + ) + ) + return self._stubs["mutate_bidding_seasonality_adjustments"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_bidding_seasonality_adjustments: self._wrap_method( + self.mutate_bidding_seasonality_adjustments, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("BiddingSeasonalityAdjustmentServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/bidding_strategy_service/__init__.py b/google/ads/googleads/v23/services/services/bidding_strategy_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/bidding_strategy_service/__init__.py rename to google/ads/googleads/v23/services/services/bidding_strategy_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/bidding_strategy_service/async_client.py b/google/ads/googleads/v23/services/services/bidding_strategy_service/async_client.py new file mode 100644 index 000000000..e0a890df2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_strategy_service/async_client.py @@ -0,0 +1,438 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import bidding_strategy_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + BiddingStrategyServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import BiddingStrategyServiceClient + +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 BiddingStrategyServiceAsyncClient: + """Service to manage bidding strategies.""" + + _client: BiddingStrategyServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = BiddingStrategyServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = BiddingStrategyServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + BiddingStrategyServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = BiddingStrategyServiceClient._DEFAULT_UNIVERSE + + bidding_strategy_path = staticmethod( + BiddingStrategyServiceClient.bidding_strategy_path + ) + parse_bidding_strategy_path = staticmethod( + BiddingStrategyServiceClient.parse_bidding_strategy_path + ) + common_billing_account_path = staticmethod( + BiddingStrategyServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + BiddingStrategyServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + BiddingStrategyServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + BiddingStrategyServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + BiddingStrategyServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + BiddingStrategyServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + BiddingStrategyServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + BiddingStrategyServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + BiddingStrategyServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + BiddingStrategyServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingStrategyServiceAsyncClient: The constructed client. + """ + return BiddingStrategyServiceClient.from_service_account_info.__func__(BiddingStrategyServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingStrategyServiceAsyncClient: The constructed client. + """ + return BiddingStrategyServiceClient.from_service_account_file.__func__(BiddingStrategyServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return BiddingStrategyServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> BiddingStrategyServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BiddingStrategyServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = BiddingStrategyServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BiddingStrategyServiceTransport, + Callable[..., BiddingStrategyServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the bidding strategy service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BiddingStrategyServiceTransport,Callable[..., BiddingStrategyServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BiddingStrategyServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = BiddingStrategyServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.BiddingStrategyServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BiddingStrategyService", + "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.ads.googleads.v23.services.BiddingStrategyService", + "credentialsType": None, + } + ), + ) + + async def mutate_bidding_strategies( + self, + request: Optional[ + Union[bidding_strategy_service.MutateBiddingStrategiesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[bidding_strategy_service.BiddingStrategyOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> bidding_strategy_service.MutateBiddingStrategiesResponse: + r"""Creates, updates, or removes bidding strategies. Operation + statuses are returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateBiddingStrategiesRequest, dict]]): + The request object. Request message for + [BiddingStrategyService.MutateBiddingStrategies][google.ads.googleads.v23.services.BiddingStrategyService.MutateBiddingStrategies]. + customer_id (:class:`str`): + Required. The ID of the customer + whose bidding strategies are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.BiddingStrategyOperation]`): + Required. The list of operations to + perform on individual bidding + strategies. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateBiddingStrategiesResponse: + Response message for bidding strategy + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, bidding_strategy_service.MutateBiddingStrategiesRequest + ): + request = bidding_strategy_service.MutateBiddingStrategiesRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_bidding_strategies + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "BiddingStrategyServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("BiddingStrategyServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/bidding_strategy_service/client.py b/google/ads/googleads/v23/services/services/bidding_strategy_service/client.py new file mode 100644 index 000000000..3ecc97414 --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_strategy_service/client.py @@ -0,0 +1,914 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import bidding_strategy_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + BiddingStrategyServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import BiddingStrategyServiceGrpcTransport +from .transports.grpc_asyncio import BiddingStrategyServiceGrpcAsyncIOTransport + + +class BiddingStrategyServiceClientMeta(type): + """Metaclass for the BiddingStrategyService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BiddingStrategyServiceTransport]] + _transport_registry["grpc"] = BiddingStrategyServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + BiddingStrategyServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[BiddingStrategyServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BiddingStrategyServiceClient(metaclass=BiddingStrategyServiceClientMeta): + """Service to manage bidding strategies.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingStrategyServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BiddingStrategyServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BiddingStrategyServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BiddingStrategyServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def bidding_strategy_path( + customer_id: str, + bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified bidding_strategy string.""" + return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, + bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + BiddingStrategyServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + BiddingStrategyServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = BiddingStrategyServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = BiddingStrategyServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + BiddingStrategyServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = BiddingStrategyServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BiddingStrategyServiceTransport, + Callable[..., BiddingStrategyServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the bidding strategy service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BiddingStrategyServiceTransport,Callable[..., BiddingStrategyServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BiddingStrategyServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = BiddingStrategyServiceClient._read_environment_variables() + self._client_cert_source = ( + BiddingStrategyServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + BiddingStrategyServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, BiddingStrategyServiceTransport + ) + if transport_provided: + # transport is a BiddingStrategyServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(BiddingStrategyServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or BiddingStrategyServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[BiddingStrategyServiceTransport], + Callable[..., BiddingStrategyServiceTransport], + ] = ( + BiddingStrategyServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., BiddingStrategyServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.BiddingStrategyServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BiddingStrategyService", + "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.ads.googleads.v23.services.BiddingStrategyService", + "credentialsType": None, + } + ), + ) + + def mutate_bidding_strategies( + self, + request: Optional[ + Union[bidding_strategy_service.MutateBiddingStrategiesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[bidding_strategy_service.BiddingStrategyOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> bidding_strategy_service.MutateBiddingStrategiesResponse: + r"""Creates, updates, or removes bidding strategies. Operation + statuses are returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateBiddingStrategiesRequest, dict]): + The request object. Request message for + [BiddingStrategyService.MutateBiddingStrategies][google.ads.googleads.v23.services.BiddingStrategyService.MutateBiddingStrategies]. + customer_id (str): + Required. The ID of the customer + whose bidding strategies are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.BiddingStrategyOperation]): + Required. The list of operations to + perform on individual bidding + strategies. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateBiddingStrategiesResponse: + Response message for bidding strategy + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, bidding_strategy_service.MutateBiddingStrategiesRequest + ): + request = bidding_strategy_service.MutateBiddingStrategiesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_bidding_strategies + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "BiddingStrategyServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("BiddingStrategyServiceClient",) diff --git a/google/ads/googleads/v19/services/services/bidding_strategy_service/transports/README.rst b/google/ads/googleads/v23/services/services/bidding_strategy_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/bidding_strategy_service/transports/README.rst rename to google/ads/googleads/v23/services/services/bidding_strategy_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/bidding_strategy_service/transports/__init__.py b/google/ads/googleads/v23/services/services/bidding_strategy_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/bidding_strategy_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/bidding_strategy_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/bidding_strategy_service/transports/base.py b/google/ads/googleads/v23/services/services/bidding_strategy_service/transports/base.py new file mode 100644 index 000000000..ea82e2a61 --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_strategy_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import bidding_strategy_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class BiddingStrategyServiceTransport(abc.ABC): + """Abstract transport class for BiddingStrategyService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_bidding_strategies: gapic_v1.method.wrap_method( + self.mutate_bidding_strategies, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_bidding_strategies( + self, + ) -> Callable[ + [bidding_strategy_service.MutateBiddingStrategiesRequest], + Union[ + bidding_strategy_service.MutateBiddingStrategiesResponse, + Awaitable[bidding_strategy_service.MutateBiddingStrategiesResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("BiddingStrategyServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/bidding_strategy_service/transports/grpc.py b/google/ads/googleads/v23/services/services/bidding_strategy_service/transports/grpc.py new file mode 100644 index 000000000..6b59e1417 --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_strategy_service/transports/grpc.py @@ -0,0 +1,397 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import bidding_strategy_service +from .base import BiddingStrategyServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.BiddingStrategyService", + "rpcName": str(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.ads.googleads.v23.services.BiddingStrategyService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BiddingStrategyServiceGrpcTransport(BiddingStrategyServiceTransport): + """gRPC backend transport for BiddingStrategyService. + + Service to manage bidding strategies. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_bidding_strategies( + self, + ) -> Callable[ + [bidding_strategy_service.MutateBiddingStrategiesRequest], + bidding_strategy_service.MutateBiddingStrategiesResponse, + ]: + r"""Return a callable for the mutate bidding strategies method over gRPC. + + Creates, updates, or removes bidding strategies. Operation + statuses are returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateBiddingStrategiesRequest], + ~.MutateBiddingStrategiesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_bidding_strategies" not in self._stubs: + self._stubs["mutate_bidding_strategies"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BiddingStrategyService/MutateBiddingStrategies", + request_serializer=bidding_strategy_service.MutateBiddingStrategiesRequest.serialize, + response_deserializer=bidding_strategy_service.MutateBiddingStrategiesResponse.deserialize, + ) + ) + return self._stubs["mutate_bidding_strategies"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("BiddingStrategyServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/bidding_strategy_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/bidding_strategy_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..fcb34dea7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/bidding_strategy_service/transports/grpc_asyncio.py @@ -0,0 +1,420 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import bidding_strategy_service +from .base import BiddingStrategyServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.BiddingStrategyService", + "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.ads.googleads.v23.services.BiddingStrategyService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BiddingStrategyServiceGrpcAsyncIOTransport( + BiddingStrategyServiceTransport +): + """gRPC AsyncIO backend transport for BiddingStrategyService. + + Service to manage bidding strategies. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_bidding_strategies( + self, + ) -> Callable[ + [bidding_strategy_service.MutateBiddingStrategiesRequest], + Awaitable[bidding_strategy_service.MutateBiddingStrategiesResponse], + ]: + r"""Return a callable for the mutate bidding strategies method over gRPC. + + Creates, updates, or removes bidding strategies. Operation + statuses are returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateBiddingStrategiesRequest], + Awaitable[~.MutateBiddingStrategiesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_bidding_strategies" not in self._stubs: + self._stubs["mutate_bidding_strategies"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BiddingStrategyService/MutateBiddingStrategies", + request_serializer=bidding_strategy_service.MutateBiddingStrategiesRequest.serialize, + response_deserializer=bidding_strategy_service.MutateBiddingStrategiesResponse.deserialize, + ) + ) + return self._stubs["mutate_bidding_strategies"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_bidding_strategies: self._wrap_method( + self.mutate_bidding_strategies, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("BiddingStrategyServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/billing_setup_service/__init__.py b/google/ads/googleads/v23/services/services/billing_setup_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/billing_setup_service/__init__.py rename to google/ads/googleads/v23/services/services/billing_setup_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/billing_setup_service/async_client.py b/google/ads/googleads/v23/services/services/billing_setup_service/async_client.py new file mode 100644 index 000000000..b3a906a51 --- /dev/null +++ b/google/ads/googleads/v23/services/services/billing_setup_service/async_client.py @@ -0,0 +1,435 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import billing_setup_service +from .transports.base import BillingSetupServiceTransport, DEFAULT_CLIENT_INFO +from .client import BillingSetupServiceClient + +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 BillingSetupServiceAsyncClient: + """A service for designating the business entity responsible for + accrued costs. + A billing setup is associated with a payments account. + Billing-related activity for all billing setups associated with + a particular payments account will appear on a single invoice + generated monthly. + + Mutates: + + The REMOVE operation cancels a pending billing setup. The CREATE + operation creates a new billing setup. + """ + + _client: BillingSetupServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = BillingSetupServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = BillingSetupServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + BillingSetupServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = BillingSetupServiceClient._DEFAULT_UNIVERSE + + billing_setup_path = staticmethod( + BillingSetupServiceClient.billing_setup_path + ) + parse_billing_setup_path = staticmethod( + BillingSetupServiceClient.parse_billing_setup_path + ) + payments_account_path = staticmethod( + BillingSetupServiceClient.payments_account_path + ) + parse_payments_account_path = staticmethod( + BillingSetupServiceClient.parse_payments_account_path + ) + common_billing_account_path = staticmethod( + BillingSetupServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + BillingSetupServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + BillingSetupServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + BillingSetupServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + BillingSetupServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + BillingSetupServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + BillingSetupServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + BillingSetupServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + BillingSetupServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + BillingSetupServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BillingSetupServiceAsyncClient: The constructed client. + """ + return BillingSetupServiceClient.from_service_account_info.__func__(BillingSetupServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BillingSetupServiceAsyncClient: The constructed client. + """ + return BillingSetupServiceClient.from_service_account_file.__func__(BillingSetupServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return BillingSetupServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> BillingSetupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BillingSetupServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = BillingSetupServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BillingSetupServiceTransport, + Callable[..., BillingSetupServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the billing setup service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BillingSetupServiceTransport,Callable[..., BillingSetupServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BillingSetupServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = BillingSetupServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.BillingSetupServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BillingSetupService", + "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.ads.googleads.v23.services.BillingSetupService", + "credentialsType": None, + } + ), + ) + + async def mutate_billing_setup( + self, + request: Optional[ + Union[billing_setup_service.MutateBillingSetupRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[billing_setup_service.BillingSetupOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> billing_setup_service.MutateBillingSetupResponse: + r"""Creates a billing setup, or cancels an existing billing setup. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BillingSetupError <>`__ + `DateError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateBillingSetupRequest, dict]]): + The request object. Request message for billing setup + mutate operations. + customer_id (:class:`str`): + Required. Id of the customer to apply + the billing setup mutate operation to. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (:class:`google.ads.googleads.v23.services.types.BillingSetupOperation`): + Required. The operation to perform. + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateBillingSetupResponse: + Response message for a billing setup + operation. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, billing_setup_service.MutateBillingSetupRequest + ): + request = billing_setup_service.MutateBillingSetupRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_billing_setup + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "BillingSetupServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("BillingSetupServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/billing_setup_service/client.py b/google/ads/googleads/v23/services/services/billing_setup_service/client.py new file mode 100644 index 000000000..0804156d9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/billing_setup_service/client.py @@ -0,0 +1,909 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import billing_setup_service +from .transports.base import BillingSetupServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import BillingSetupServiceGrpcTransport +from .transports.grpc_asyncio import BillingSetupServiceGrpcAsyncIOTransport + + +class BillingSetupServiceClientMeta(type): + """Metaclass for the BillingSetupService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BillingSetupServiceTransport]] + _transport_registry["grpc"] = BillingSetupServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + BillingSetupServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[BillingSetupServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BillingSetupServiceClient(metaclass=BillingSetupServiceClientMeta): + """A service for designating the business entity responsible for + accrued costs. + A billing setup is associated with a payments account. + Billing-related activity for all billing setups associated with + a particular payments account will appear on a single invoice + generated monthly. + + Mutates: + + The REMOVE operation cancels a pending billing setup. The CREATE + operation creates a new billing setup. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BillingSetupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BillingSetupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BillingSetupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BillingSetupServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def billing_setup_path( + customer_id: str, + billing_setup_id: str, + ) -> str: + """Returns a fully-qualified billing_setup string.""" + return ( + "customers/{customer_id}/billingSetups/{billing_setup_id}".format( + customer_id=customer_id, + billing_setup_id=billing_setup_id, + ) + ) + + @staticmethod + def parse_billing_setup_path(path: str) -> Dict[str, str]: + """Parses a billing_setup path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/billingSetups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def payments_account_path( + customer_id: str, + payments_account_id: str, + ) -> str: + """Returns a fully-qualified payments_account string.""" + return "customers/{customer_id}/paymentsAccounts/{payments_account_id}".format( + customer_id=customer_id, + payments_account_id=payments_account_id, + ) + + @staticmethod + def parse_payments_account_path(path: str) -> Dict[str, str]: + """Parses a payments_account path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/paymentsAccounts/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = BillingSetupServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = BillingSetupServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = BillingSetupServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = BillingSetupServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + BillingSetupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = BillingSetupServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BillingSetupServiceTransport, + Callable[..., BillingSetupServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the billing setup service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BillingSetupServiceTransport,Callable[..., BillingSetupServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BillingSetupServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = BillingSetupServiceClient._read_environment_variables() + self._client_cert_source = ( + BillingSetupServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = BillingSetupServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, BillingSetupServiceTransport) + if transport_provided: + # transport is a BillingSetupServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(BillingSetupServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or BillingSetupServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[BillingSetupServiceTransport], + Callable[..., BillingSetupServiceTransport], + ] = ( + BillingSetupServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., BillingSetupServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.BillingSetupServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BillingSetupService", + "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.ads.googleads.v23.services.BillingSetupService", + "credentialsType": None, + } + ), + ) + + def mutate_billing_setup( + self, + request: Optional[ + Union[billing_setup_service.MutateBillingSetupRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[billing_setup_service.BillingSetupOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> billing_setup_service.MutateBillingSetupResponse: + r"""Creates a billing setup, or cancels an existing billing setup. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BillingSetupError <>`__ + `DateError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateBillingSetupRequest, dict]): + The request object. Request message for billing setup + mutate operations. + customer_id (str): + Required. Id of the customer to apply + the billing setup mutate operation to. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v23.services.types.BillingSetupOperation): + Required. The operation to perform. + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateBillingSetupResponse: + Response message for a billing setup + operation. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, billing_setup_service.MutateBillingSetupRequest + ): + request = billing_setup_service.MutateBillingSetupRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_billing_setup + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "BillingSetupServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("BillingSetupServiceClient",) diff --git a/google/ads/googleads/v19/services/services/billing_setup_service/transports/README.rst b/google/ads/googleads/v23/services/services/billing_setup_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/billing_setup_service/transports/README.rst rename to google/ads/googleads/v23/services/services/billing_setup_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/billing_setup_service/transports/__init__.py b/google/ads/googleads/v23/services/services/billing_setup_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/billing_setup_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/billing_setup_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/billing_setup_service/transports/base.py b/google/ads/googleads/v23/services/services/billing_setup_service/transports/base.py new file mode 100644 index 000000000..59597980d --- /dev/null +++ b/google/ads/googleads/v23/services/services/billing_setup_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import billing_setup_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class BillingSetupServiceTransport(abc.ABC): + """Abstract transport class for BillingSetupService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_billing_setup: gapic_v1.method.wrap_method( + self.mutate_billing_setup, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_billing_setup( + self, + ) -> Callable[ + [billing_setup_service.MutateBillingSetupRequest], + Union[ + billing_setup_service.MutateBillingSetupResponse, + Awaitable[billing_setup_service.MutateBillingSetupResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("BillingSetupServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/billing_setup_service/transports/grpc.py b/google/ads/googleads/v23/services/services/billing_setup_service/transports/grpc.py new file mode 100644 index 000000000..8bca61a90 --- /dev/null +++ b/google/ads/googleads/v23/services/services/billing_setup_service/transports/grpc.py @@ -0,0 +1,399 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import billing_setup_service +from .base import BillingSetupServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.BillingSetupService", + "rpcName": str(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.ads.googleads.v23.services.BillingSetupService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BillingSetupServiceGrpcTransport(BillingSetupServiceTransport): + """gRPC backend transport for BillingSetupService. + + A service for designating the business entity responsible for + accrued costs. + A billing setup is associated with a payments account. + Billing-related activity for all billing setups associated with + a particular payments account will appear on a single invoice + generated monthly. + + Mutates: + + The REMOVE operation cancels a pending billing setup. The CREATE + operation creates a new billing setup. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_billing_setup( + self, + ) -> Callable[ + [billing_setup_service.MutateBillingSetupRequest], + billing_setup_service.MutateBillingSetupResponse, + ]: + r"""Return a callable for the mutate billing setup method over gRPC. + + Creates a billing setup, or cancels an existing billing setup. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BillingSetupError <>`__ + `DateError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateBillingSetupRequest], + ~.MutateBillingSetupResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_billing_setup" not in self._stubs: + self._stubs["mutate_billing_setup"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BillingSetupService/MutateBillingSetup", + request_serializer=billing_setup_service.MutateBillingSetupRequest.serialize, + response_deserializer=billing_setup_service.MutateBillingSetupResponse.deserialize, + ) + ) + return self._stubs["mutate_billing_setup"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("BillingSetupServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/billing_setup_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/billing_setup_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..ef780ed07 --- /dev/null +++ b/google/ads/googleads/v23/services/services/billing_setup_service/transports/grpc_asyncio.py @@ -0,0 +1,420 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import billing_setup_service +from .base import BillingSetupServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.BillingSetupService", + "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.ads.googleads.v23.services.BillingSetupService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BillingSetupServiceGrpcAsyncIOTransport(BillingSetupServiceTransport): + """gRPC AsyncIO backend transport for BillingSetupService. + + A service for designating the business entity responsible for + accrued costs. + A billing setup is associated with a payments account. + Billing-related activity for all billing setups associated with + a particular payments account will appear on a single invoice + generated monthly. + + Mutates: + + The REMOVE operation cancels a pending billing setup. The CREATE + operation creates a new billing setup. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_billing_setup( + self, + ) -> Callable[ + [billing_setup_service.MutateBillingSetupRequest], + Awaitable[billing_setup_service.MutateBillingSetupResponse], + ]: + r"""Return a callable for the mutate billing setup method over gRPC. + + Creates a billing setup, or cancels an existing billing setup. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `BillingSetupError <>`__ + `DateError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateBillingSetupRequest], + Awaitable[~.MutateBillingSetupResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_billing_setup" not in self._stubs: + self._stubs["mutate_billing_setup"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BillingSetupService/MutateBillingSetup", + request_serializer=billing_setup_service.MutateBillingSetupRequest.serialize, + response_deserializer=billing_setup_service.MutateBillingSetupResponse.deserialize, + ) + ) + return self._stubs["mutate_billing_setup"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_billing_setup: self._wrap_method( + self.mutate_billing_setup, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("BillingSetupServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/brand_suggestion_service/__init__.py b/google/ads/googleads/v23/services/services/brand_suggestion_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/brand_suggestion_service/__init__.py rename to google/ads/googleads/v23/services/services/brand_suggestion_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/brand_suggestion_service/async_client.py b/google/ads/googleads/v23/services/services/brand_suggestion_service/async_client.py new file mode 100644 index 000000000..8365142e1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/brand_suggestion_service/async_client.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import brand_suggestion_service +from .transports.base import ( + BrandSuggestionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import BrandSuggestionServiceClient + +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 BrandSuggestionServiceAsyncClient: + """This service will suggest brands based on a prefix.""" + + _client: BrandSuggestionServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = BrandSuggestionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = BrandSuggestionServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + BrandSuggestionServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = BrandSuggestionServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod( + BrandSuggestionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + BrandSuggestionServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + BrandSuggestionServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + BrandSuggestionServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + BrandSuggestionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + BrandSuggestionServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + BrandSuggestionServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + BrandSuggestionServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + BrandSuggestionServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + BrandSuggestionServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BrandSuggestionServiceAsyncClient: The constructed client. + """ + return BrandSuggestionServiceClient.from_service_account_info.__func__(BrandSuggestionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BrandSuggestionServiceAsyncClient: The constructed client. + """ + return BrandSuggestionServiceClient.from_service_account_file.__func__(BrandSuggestionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return BrandSuggestionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> BrandSuggestionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BrandSuggestionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = BrandSuggestionServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BrandSuggestionServiceTransport, + Callable[..., BrandSuggestionServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the brand suggestion service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BrandSuggestionServiceTransport,Callable[..., BrandSuggestionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BrandSuggestionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = BrandSuggestionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.BrandSuggestionServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BrandSuggestionService", + "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.ads.googleads.v23.services.BrandSuggestionService", + "credentialsType": None, + } + ), + ) + + async def suggest_brands( + self, + request: Optional[ + Union[brand_suggestion_service.SuggestBrandsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + brand_prefix: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> brand_suggestion_service.SuggestBrandsResponse: + r"""Rpc to return a list of matching brands based on a + prefix for this customer. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.SuggestBrandsRequest, dict]]): + The request object. Request message for + [BrandSuggestionService.SuggestBrands][google.ads.googleads.v23.services.BrandSuggestionService.SuggestBrands]. + customer_id (:class:`str`): + Required. The ID of the customer onto + which to apply the brand suggestion + operation. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + brand_prefix (:class:`str`): + Required. The prefix of a brand name. + This corresponds to the ``brand_prefix`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestBrandsResponse: + Response message for + [BrandSuggestionService.SuggestBrands][google.ads.googleads.v23.services.BrandSuggestionService.SuggestBrands]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, brand_prefix] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, brand_suggestion_service.SuggestBrandsRequest + ): + request = brand_suggestion_service.SuggestBrandsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if brand_prefix is not None: + request.brand_prefix = brand_prefix + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.suggest_brands + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "BrandSuggestionServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("BrandSuggestionServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/brand_suggestion_service/client.py b/google/ads/googleads/v23/services/services/brand_suggestion_service/client.py new file mode 100644 index 000000000..a9c460fb7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/brand_suggestion_service/client.py @@ -0,0 +1,861 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import brand_suggestion_service +from .transports.base import ( + BrandSuggestionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import BrandSuggestionServiceGrpcTransport +from .transports.grpc_asyncio import BrandSuggestionServiceGrpcAsyncIOTransport + + +class BrandSuggestionServiceClientMeta(type): + """Metaclass for the BrandSuggestionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[BrandSuggestionServiceTransport]] + _transport_registry["grpc"] = BrandSuggestionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + BrandSuggestionServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[BrandSuggestionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class BrandSuggestionServiceClient(metaclass=BrandSuggestionServiceClientMeta): + """This service will suggest brands based on a prefix.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BrandSuggestionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + BrandSuggestionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> BrandSuggestionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + BrandSuggestionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + BrandSuggestionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + BrandSuggestionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = BrandSuggestionServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = BrandSuggestionServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + BrandSuggestionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = BrandSuggestionServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + BrandSuggestionServiceTransport, + Callable[..., BrandSuggestionServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the brand suggestion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,BrandSuggestionServiceTransport,Callable[..., BrandSuggestionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the BrandSuggestionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = BrandSuggestionServiceClient._read_environment_variables() + self._client_cert_source = ( + BrandSuggestionServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + BrandSuggestionServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, BrandSuggestionServiceTransport + ) + if transport_provided: + # transport is a BrandSuggestionServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(BrandSuggestionServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or BrandSuggestionServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[BrandSuggestionServiceTransport], + Callable[..., BrandSuggestionServiceTransport], + ] = ( + BrandSuggestionServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., BrandSuggestionServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.BrandSuggestionServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.BrandSuggestionService", + "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.ads.googleads.v23.services.BrandSuggestionService", + "credentialsType": None, + } + ), + ) + + def suggest_brands( + self, + request: Optional[ + Union[brand_suggestion_service.SuggestBrandsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + brand_prefix: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> brand_suggestion_service.SuggestBrandsResponse: + r"""Rpc to return a list of matching brands based on a + prefix for this customer. + + Args: + request (Union[google.ads.googleads.v23.services.types.SuggestBrandsRequest, dict]): + The request object. Request message for + [BrandSuggestionService.SuggestBrands][google.ads.googleads.v23.services.BrandSuggestionService.SuggestBrands]. + customer_id (str): + Required. The ID of the customer onto + which to apply the brand suggestion + operation. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + brand_prefix (str): + Required. The prefix of a brand name. + This corresponds to the ``brand_prefix`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestBrandsResponse: + Response message for + [BrandSuggestionService.SuggestBrands][google.ads.googleads.v23.services.BrandSuggestionService.SuggestBrands]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, brand_prefix] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, brand_suggestion_service.SuggestBrandsRequest + ): + request = brand_suggestion_service.SuggestBrandsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if brand_prefix is not None: + request.brand_prefix = brand_prefix + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.suggest_brands] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "BrandSuggestionServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("BrandSuggestionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/brand_suggestion_service/transports/README.rst b/google/ads/googleads/v23/services/services/brand_suggestion_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/brand_suggestion_service/transports/README.rst rename to google/ads/googleads/v23/services/services/brand_suggestion_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/brand_suggestion_service/transports/__init__.py b/google/ads/googleads/v23/services/services/brand_suggestion_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/brand_suggestion_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/brand_suggestion_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/brand_suggestion_service/transports/base.py b/google/ads/googleads/v23/services/services/brand_suggestion_service/transports/base.py new file mode 100644 index 000000000..cc6e7a679 --- /dev/null +++ b/google/ads/googleads/v23/services/services/brand_suggestion_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import brand_suggestion_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class BrandSuggestionServiceTransport(abc.ABC): + """Abstract transport class for BrandSuggestionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.suggest_brands: gapic_v1.method.wrap_method( + self.suggest_brands, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def suggest_brands( + self, + ) -> Callable[ + [brand_suggestion_service.SuggestBrandsRequest], + Union[ + brand_suggestion_service.SuggestBrandsResponse, + Awaitable[brand_suggestion_service.SuggestBrandsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("BrandSuggestionServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/brand_suggestion_service/transports/grpc.py b/google/ads/googleads/v23/services/services/brand_suggestion_service/transports/grpc.py new file mode 100644 index 000000000..88e8d3b65 --- /dev/null +++ b/google/ads/googleads/v23/services/services/brand_suggestion_service/transports/grpc.py @@ -0,0 +1,382 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import brand_suggestion_service +from .base import BrandSuggestionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.BrandSuggestionService", + "rpcName": str(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.ads.googleads.v23.services.BrandSuggestionService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BrandSuggestionServiceGrpcTransport(BrandSuggestionServiceTransport): + """gRPC backend transport for BrandSuggestionService. + + This service will suggest brands based on a prefix. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def suggest_brands( + self, + ) -> Callable[ + [brand_suggestion_service.SuggestBrandsRequest], + brand_suggestion_service.SuggestBrandsResponse, + ]: + r"""Return a callable for the suggest brands method over gRPC. + + Rpc to return a list of matching brands based on a + prefix for this customer. + + Returns: + Callable[[~.SuggestBrandsRequest], + ~.SuggestBrandsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_brands" not in self._stubs: + self._stubs["suggest_brands"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BrandSuggestionService/SuggestBrands", + request_serializer=brand_suggestion_service.SuggestBrandsRequest.serialize, + response_deserializer=brand_suggestion_service.SuggestBrandsResponse.deserialize, + ) + return self._stubs["suggest_brands"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("BrandSuggestionServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/brand_suggestion_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/brand_suggestion_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..f26584850 --- /dev/null +++ b/google/ads/googleads/v23/services/services/brand_suggestion_service/transports/grpc_asyncio.py @@ -0,0 +1,405 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import brand_suggestion_service +from .base import BrandSuggestionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.BrandSuggestionService", + "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.ads.googleads.v23.services.BrandSuggestionService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class BrandSuggestionServiceGrpcAsyncIOTransport( + BrandSuggestionServiceTransport +): + """gRPC AsyncIO backend transport for BrandSuggestionService. + + This service will suggest brands based on a prefix. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def suggest_brands( + self, + ) -> Callable[ + [brand_suggestion_service.SuggestBrandsRequest], + Awaitable[brand_suggestion_service.SuggestBrandsResponse], + ]: + r"""Return a callable for the suggest brands method over gRPC. + + Rpc to return a list of matching brands based on a + prefix for this customer. + + Returns: + Callable[[~.SuggestBrandsRequest], + Awaitable[~.SuggestBrandsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_brands" not in self._stubs: + self._stubs["suggest_brands"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.BrandSuggestionService/SuggestBrands", + request_serializer=brand_suggestion_service.SuggestBrandsRequest.serialize, + response_deserializer=brand_suggestion_service.SuggestBrandsResponse.deserialize, + ) + return self._stubs["suggest_brands"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.suggest_brands: self._wrap_method( + self.suggest_brands, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("BrandSuggestionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_asset_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_asset_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_asset_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_asset_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_asset_service/async_client.py new file mode 100644 index 000000000..e5868a9d8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_asset_service/async_client.py @@ -0,0 +1,433 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import campaign_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignAssetServiceTransport, DEFAULT_CLIENT_INFO +from .client import CampaignAssetServiceClient + +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 CampaignAssetServiceAsyncClient: + """Service to manage campaign assets.""" + + _client: CampaignAssetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignAssetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CampaignAssetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignAssetServiceClient._DEFAULT_UNIVERSE + + asset_path = staticmethod(CampaignAssetServiceClient.asset_path) + parse_asset_path = staticmethod(CampaignAssetServiceClient.parse_asset_path) + campaign_path = staticmethod(CampaignAssetServiceClient.campaign_path) + parse_campaign_path = staticmethod( + CampaignAssetServiceClient.parse_campaign_path + ) + campaign_asset_path = staticmethod( + CampaignAssetServiceClient.campaign_asset_path + ) + parse_campaign_asset_path = staticmethod( + CampaignAssetServiceClient.parse_campaign_asset_path + ) + common_billing_account_path = staticmethod( + CampaignAssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignAssetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignAssetServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignAssetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignAssetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignAssetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignAssetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignAssetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignAssetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignAssetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetServiceAsyncClient: The constructed client. + """ + return CampaignAssetServiceClient.from_service_account_info.__func__(CampaignAssetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetServiceAsyncClient: The constructed client. + """ + return CampaignAssetServiceClient.from_service_account_file.__func__(CampaignAssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignAssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignAssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignAssetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignAssetServiceTransport, + Callable[..., CampaignAssetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign asset service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignAssetServiceTransport,Callable[..., CampaignAssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignAssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignAssetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignAssetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignAssetService", + "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.ads.googleads.v23.services.CampaignAssetService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_assets( + self, + request: Optional[ + Union[campaign_asset_service.MutateCampaignAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_asset_service.CampaignAssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_asset_service.MutateCampaignAssetsResponse: + r"""Creates, updates, or removes campaign assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignAssetsRequest, dict]]): + The request object. Request message for + [CampaignAssetService.MutateCampaignAssets][google.ads.googleads.v23.services.CampaignAssetService.MutateCampaignAssets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaign assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignAssetOperation]`): + Required. The list of operations to + perform on individual campaign assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignAssetsResponse: + Response message for a campaign asset + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_asset_service.MutateCampaignAssetsRequest + ): + request = campaign_asset_service.MutateCampaignAssetsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignAssetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignAssetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_asset_service/client.py b/google/ads/googleads/v23/services/services/campaign_asset_service/client.py new file mode 100644 index 000000000..b3d73304c --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_asset_service/client.py @@ -0,0 +1,944 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import campaign_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignAssetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignAssetServiceGrpcTransport +from .transports.grpc_asyncio import CampaignAssetServiceGrpcAsyncIOTransport + + +class CampaignAssetServiceClientMeta(type): + """Metaclass for the CampaignAssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignAssetServiceTransport]] + _transport_registry["grpc"] = CampaignAssetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignAssetServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignAssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignAssetServiceClient(metaclass=CampaignAssetServiceClientMeta): + """Service to manage campaign assets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignAssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_path( + customer_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_path( + customer_id: str, + campaign_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified campaign_asset string.""" + return "customers/{customer_id}/campaignAssets/{campaign_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_campaign_asset_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignAssetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignAssetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CampaignAssetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CampaignAssetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CampaignAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignAssetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignAssetServiceTransport, + Callable[..., CampaignAssetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignAssetServiceTransport,Callable[..., CampaignAssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignAssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignAssetServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignAssetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = CampaignAssetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignAssetServiceTransport + ) + if transport_provided: + # transport is a CampaignAssetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CampaignAssetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignAssetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignAssetServiceTransport], + Callable[..., CampaignAssetServiceTransport], + ] = ( + CampaignAssetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignAssetServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignAssetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignAssetService", + "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.ads.googleads.v23.services.CampaignAssetService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_assets( + self, + request: Optional[ + Union[campaign_asset_service.MutateCampaignAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_asset_service.CampaignAssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_asset_service.MutateCampaignAssetsResponse: + r"""Creates, updates, or removes campaign assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignAssetsRequest, dict]): + The request object. Request message for + [CampaignAssetService.MutateCampaignAssets][google.ads.googleads.v23.services.CampaignAssetService.MutateCampaignAssets]. + customer_id (str): + Required. The ID of the customer + whose campaign assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignAssetOperation]): + Required. The list of operations to + perform on individual campaign assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignAssetsResponse: + Response message for a campaign asset + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_asset_service.MutateCampaignAssetsRequest + ): + request = campaign_asset_service.MutateCampaignAssetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignAssetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignAssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_asset_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_asset_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_asset_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_asset_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_asset_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_asset_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_asset_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_asset_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_asset_service/transports/base.py new file mode 100644 index 000000000..123cdc9db --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_asset_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import campaign_asset_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignAssetServiceTransport(abc.ABC): + """Abstract transport class for CampaignAssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_assets: gapic_v1.method.wrap_method( + self.mutate_campaign_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_assets( + self, + ) -> Callable[ + [campaign_asset_service.MutateCampaignAssetsRequest], + Union[ + campaign_asset_service.MutateCampaignAssetsResponse, + Awaitable[campaign_asset_service.MutateCampaignAssetsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignAssetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_asset_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_asset_service/transports/grpc.py new file mode 100644 index 000000000..6d340bd37 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_asset_service/transports/grpc.py @@ -0,0 +1,390 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import campaign_asset_service +from .base import CampaignAssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignAssetService", + "rpcName": str(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.ads.googleads.v23.services.CampaignAssetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignAssetServiceGrpcTransport(CampaignAssetServiceTransport): + """gRPC backend transport for CampaignAssetService. + + Service to manage campaign assets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaign_assets( + self, + ) -> Callable[ + [campaign_asset_service.MutateCampaignAssetsRequest], + campaign_asset_service.MutateCampaignAssetsResponse, + ]: + r"""Return a callable for the mutate campaign assets method over gRPC. + + Creates, updates, or removes campaign assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCampaignAssetsRequest], + ~.MutateCampaignAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_assets" not in self._stubs: + self._stubs["mutate_campaign_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignAssetService/MutateCampaignAssets", + request_serializer=campaign_asset_service.MutateCampaignAssetsRequest.serialize, + response_deserializer=campaign_asset_service.MutateCampaignAssetsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_assets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_asset_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..36868df9f --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_asset_service/transports/grpc_asyncio.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import campaign_asset_service +from .base import CampaignAssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignAssetService", + "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.ads.googleads.v23.services.CampaignAssetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignAssetServiceGrpcAsyncIOTransport(CampaignAssetServiceTransport): + """gRPC AsyncIO backend transport for CampaignAssetService. + + Service to manage campaign assets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaign_assets( + self, + ) -> Callable[ + [campaign_asset_service.MutateCampaignAssetsRequest], + Awaitable[campaign_asset_service.MutateCampaignAssetsResponse], + ]: + r"""Return a callable for the mutate campaign assets method over gRPC. + + Creates, updates, or removes campaign assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `NotAllowlistedError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCampaignAssetsRequest], + Awaitable[~.MutateCampaignAssetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_assets" not in self._stubs: + self._stubs["mutate_campaign_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignAssetService/MutateCampaignAssets", + request_serializer=campaign_asset_service.MutateCampaignAssetsRequest.serialize, + response_deserializer=campaign_asset_service.MutateCampaignAssetsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_assets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_assets: self._wrap_method( + self.mutate_campaign_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignAssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_set_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_asset_set_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_asset_set_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_asset_set_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_asset_set_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_asset_set_service/async_client.py new file mode 100644 index 000000000..70b1e389b --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_asset_set_service/async_client.py @@ -0,0 +1,437 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import campaign_asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignAssetSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CampaignAssetSetServiceClient + +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 CampaignAssetSetServiceAsyncClient: + """Service to manage campaign asset set""" + + _client: CampaignAssetSetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignAssetSetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CampaignAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignAssetSetServiceClient._DEFAULT_UNIVERSE + + asset_set_path = staticmethod(CampaignAssetSetServiceClient.asset_set_path) + parse_asset_set_path = staticmethod( + CampaignAssetSetServiceClient.parse_asset_set_path + ) + campaign_path = staticmethod(CampaignAssetSetServiceClient.campaign_path) + parse_campaign_path = staticmethod( + CampaignAssetSetServiceClient.parse_campaign_path + ) + campaign_asset_set_path = staticmethod( + CampaignAssetSetServiceClient.campaign_asset_set_path + ) + parse_campaign_asset_set_path = staticmethod( + CampaignAssetSetServiceClient.parse_campaign_asset_set_path + ) + common_billing_account_path = staticmethod( + CampaignAssetSetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignAssetSetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignAssetSetServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignAssetSetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignAssetSetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignAssetSetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignAssetSetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignAssetSetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignAssetSetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignAssetSetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetSetServiceAsyncClient: The constructed client. + """ + return CampaignAssetSetServiceClient.from_service_account_info.__func__(CampaignAssetSetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetSetServiceAsyncClient: The constructed client. + """ + return CampaignAssetSetServiceClient.from_service_account_file.__func__(CampaignAssetSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignAssetSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignAssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignAssetSetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignAssetSetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignAssetSetServiceTransport, + Callable[..., CampaignAssetSetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign asset set service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignAssetSetServiceTransport,Callable[..., CampaignAssetSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignAssetSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignAssetSetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignAssetSetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignAssetSetService", + "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.ads.googleads.v23.services.CampaignAssetSetService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_asset_sets( + self, + request: Optional[ + Union[ + campaign_asset_set_service.MutateCampaignAssetSetsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_asset_set_service.CampaignAssetSetOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_asset_set_service.MutateCampaignAssetSetsResponse: + r"""Creates, updates or removes campaign asset sets. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignAssetSetsRequest, dict]]): + The request object. Request message for + [CampaignAssetSetService.MutateCampaignAssetSets][google.ads.googleads.v23.services.CampaignAssetSetService.MutateCampaignAssetSets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaign asset sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignAssetSetOperation]`): + Required. The list of operations to + perform on individual campaign asset + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignAssetSetsResponse: + Response message for a campaign asset + set mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_asset_set_service.MutateCampaignAssetSetsRequest + ): + request = campaign_asset_set_service.MutateCampaignAssetSetsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignAssetSetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignAssetSetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_asset_set_service/client.py b/google/ads/googleads/v23/services/services/campaign_asset_set_service/client.py new file mode 100644 index 000000000..8c1988fbb --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_asset_set_service/client.py @@ -0,0 +1,949 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import campaign_asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignAssetSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignAssetSetServiceGrpcTransport +from .transports.grpc_asyncio import CampaignAssetSetServiceGrpcAsyncIOTransport + + +class CampaignAssetSetServiceClientMeta(type): + """Metaclass for the CampaignAssetSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignAssetSetServiceTransport]] + _transport_registry["grpc"] = CampaignAssetSetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignAssetSetServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignAssetSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignAssetSetServiceClient( + metaclass=CampaignAssetSetServiceClientMeta +): + """Service to manage campaign asset set""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignAssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignAssetSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_set_path( + customer_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_set_path( + customer_id: str, + campaign_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_asset_set string.""" + return "customers/{customer_id}/campaignAssetSets/{campaign_id}~{asset_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_campaign_asset_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssetSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignAssetSetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignAssetSetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CampaignAssetSetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CampaignAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CampaignAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignAssetSetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignAssetSetServiceTransport, + Callable[..., CampaignAssetSetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign asset set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignAssetSetServiceTransport,Callable[..., CampaignAssetSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignAssetSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignAssetSetServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignAssetSetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CampaignAssetSetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignAssetSetServiceTransport + ) + if transport_provided: + # transport is a CampaignAssetSetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CampaignAssetSetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignAssetSetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignAssetSetServiceTransport], + Callable[..., CampaignAssetSetServiceTransport], + ] = ( + CampaignAssetSetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignAssetSetServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignAssetSetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignAssetSetService", + "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.ads.googleads.v23.services.CampaignAssetSetService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_asset_sets( + self, + request: Optional[ + Union[ + campaign_asset_set_service.MutateCampaignAssetSetsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_asset_set_service.CampaignAssetSetOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_asset_set_service.MutateCampaignAssetSetsResponse: + r"""Creates, updates or removes campaign asset sets. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignAssetSetsRequest, dict]): + The request object. Request message for + [CampaignAssetSetService.MutateCampaignAssetSets][google.ads.googleads.v23.services.CampaignAssetSetService.MutateCampaignAssetSets]. + customer_id (str): + Required. The ID of the customer + whose campaign asset sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignAssetSetOperation]): + Required. The list of operations to + perform on individual campaign asset + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignAssetSetsResponse: + Response message for a campaign asset + set mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_asset_set_service.MutateCampaignAssetSetsRequest + ): + request = campaign_asset_set_service.MutateCampaignAssetSetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignAssetSetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignAssetSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_asset_set_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/base.py new file mode 100644 index 000000000..0dbfb3e14 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import campaign_asset_set_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignAssetSetServiceTransport(abc.ABC): + """Abstract transport class for CampaignAssetSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_asset_sets: gapic_v1.method.wrap_method( + self.mutate_campaign_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_asset_sets( + self, + ) -> Callable[ + [campaign_asset_set_service.MutateCampaignAssetSetsRequest], + Union[ + campaign_asset_set_service.MutateCampaignAssetSetsResponse, + Awaitable[ + campaign_asset_set_service.MutateCampaignAssetSetsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignAssetSetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/grpc.py new file mode 100644 index 000000000..d154b8d95 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/grpc.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import campaign_asset_set_service +from .base import CampaignAssetSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignAssetSetService", + "rpcName": str(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.ads.googleads.v23.services.CampaignAssetSetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignAssetSetServiceGrpcTransport(CampaignAssetSetServiceTransport): + """gRPC backend transport for CampaignAssetSetService. + + Service to manage campaign asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaign_asset_sets( + self, + ) -> Callable[ + [campaign_asset_set_service.MutateCampaignAssetSetsRequest], + campaign_asset_set_service.MutateCampaignAssetSetsResponse, + ]: + r"""Return a callable for the mutate campaign asset sets method over gRPC. + + Creates, updates or removes campaign asset sets. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignAssetSetsRequest], + ~.MutateCampaignAssetSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_asset_sets" not in self._stubs: + self._stubs["mutate_campaign_asset_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignAssetSetService/MutateCampaignAssetSets", + request_serializer=campaign_asset_set_service.MutateCampaignAssetSetsRequest.serialize, + response_deserializer=campaign_asset_set_service.MutateCampaignAssetSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_asset_sets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignAssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..f2174f916 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_asset_set_service/transports/grpc_asyncio.py @@ -0,0 +1,407 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import campaign_asset_set_service +from .base import CampaignAssetSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignAssetSetService", + "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.ads.googleads.v23.services.CampaignAssetSetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignAssetSetServiceGrpcAsyncIOTransport( + CampaignAssetSetServiceTransport +): + """gRPC AsyncIO backend transport for CampaignAssetSetService. + + Service to manage campaign asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaign_asset_sets( + self, + ) -> Callable[ + [campaign_asset_set_service.MutateCampaignAssetSetsRequest], + Awaitable[campaign_asset_set_service.MutateCampaignAssetSetsResponse], + ]: + r"""Return a callable for the mutate campaign asset sets method over gRPC. + + Creates, updates or removes campaign asset sets. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignAssetSetsRequest], + Awaitable[~.MutateCampaignAssetSetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_asset_sets" not in self._stubs: + self._stubs["mutate_campaign_asset_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignAssetSetService/MutateCampaignAssetSets", + request_serializer=campaign_asset_set_service.MutateCampaignAssetSetsRequest.serialize, + response_deserializer=campaign_asset_set_service.MutateCampaignAssetSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_asset_sets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_asset_sets: self._wrap_method( + self.mutate_campaign_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignAssetSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_bid_modifier_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_bid_modifier_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/async_client.py new file mode 100644 index 000000000..2118488d7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/async_client.py @@ -0,0 +1,451 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + campaign_bid_modifier_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignBidModifierServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CampaignBidModifierServiceClient + +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 CampaignBidModifierServiceAsyncClient: + """Service to manage campaign bid modifiers.""" + + _client: CampaignBidModifierServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignBidModifierServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CampaignBidModifierServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignBidModifierServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignBidModifierServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod(CampaignBidModifierServiceClient.campaign_path) + parse_campaign_path = staticmethod( + CampaignBidModifierServiceClient.parse_campaign_path + ) + campaign_bid_modifier_path = staticmethod( + CampaignBidModifierServiceClient.campaign_bid_modifier_path + ) + parse_campaign_bid_modifier_path = staticmethod( + CampaignBidModifierServiceClient.parse_campaign_bid_modifier_path + ) + common_billing_account_path = staticmethod( + CampaignBidModifierServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignBidModifierServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignBidModifierServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignBidModifierServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignBidModifierServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignBidModifierServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignBidModifierServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignBidModifierServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignBidModifierServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignBidModifierServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBidModifierServiceAsyncClient: The constructed client. + """ + return CampaignBidModifierServiceClient.from_service_account_info.__func__(CampaignBidModifierServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBidModifierServiceAsyncClient: The constructed client. + """ + return CampaignBidModifierServiceClient.from_service_account_file.__func__(CampaignBidModifierServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignBidModifierServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignBidModifierServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignBidModifierServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignBidModifierServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignBidModifierServiceTransport, + Callable[..., CampaignBidModifierServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign bid modifier service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignBidModifierServiceTransport,Callable[..., CampaignBidModifierServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignBidModifierServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignBidModifierServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignBidModifierServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignBidModifierService", + "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.ads.googleads.v23.services.CampaignBidModifierService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_bid_modifiers( + self, + request: Optional[ + Union[ + campaign_bid_modifier_service.MutateCampaignBidModifiersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_bid_modifier_service.CampaignBidModifierOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_bid_modifier_service.MutateCampaignBidModifiersResponse: + r"""Creates, updates, or removes campaign bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ContextError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignBidModifiersRequest, dict]]): + The request object. Request message for + [CampaignBidModifierService.MutateCampaignBidModifiers][google.ads.googleads.v23.services.CampaignBidModifierService.MutateCampaignBidModifiers]. + customer_id (:class:`str`): + Required. ID of the customer whose + campaign bid modifiers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignBidModifierOperation]`): + Required. The list of operations to + perform on individual campaign bid + modifiers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignBidModifiersResponse: + Response message for campaign bid + modifiers mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + campaign_bid_modifier_service.MutateCampaignBidModifiersRequest, + ): + request = ( + campaign_bid_modifier_service.MutateCampaignBidModifiersRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_bid_modifiers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignBidModifierServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignBidModifierServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/client.py b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/client.py new file mode 100644 index 000000000..b8a641f3e --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/client.py @@ -0,0 +1,952 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + campaign_bid_modifier_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignBidModifierServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignBidModifierServiceGrpcTransport +from .transports.grpc_asyncio import ( + CampaignBidModifierServiceGrpcAsyncIOTransport, +) + + +class CampaignBidModifierServiceClientMeta(type): + """Metaclass for the CampaignBidModifierService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignBidModifierServiceTransport]] + _transport_registry["grpc"] = CampaignBidModifierServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignBidModifierServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignBidModifierServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignBidModifierServiceClient( + metaclass=CampaignBidModifierServiceClientMeta +): + """Service to manage campaign bid modifiers.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBidModifierServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBidModifierServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignBidModifierServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignBidModifierServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_bid_modifier_path( + customer_id: str, + campaign_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_bid_modifier string.""" + return "customers/{customer_id}/campaignBidModifiers/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a campaign_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignBidModifierServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignBidModifierServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CampaignBidModifierServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + CampaignBidModifierServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = CampaignBidModifierServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignBidModifierServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignBidModifierServiceTransport, + Callable[..., CampaignBidModifierServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign bid modifier service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignBidModifierServiceTransport,Callable[..., CampaignBidModifierServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignBidModifierServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignBidModifierServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignBidModifierServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CampaignBidModifierServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignBidModifierServiceTransport + ) + if transport_provided: + # transport is a CampaignBidModifierServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CampaignBidModifierServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignBidModifierServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignBidModifierServiceTransport], + Callable[..., CampaignBidModifierServiceTransport], + ] = ( + CampaignBidModifierServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignBidModifierServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignBidModifierServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignBidModifierService", + "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.ads.googleads.v23.services.CampaignBidModifierService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_bid_modifiers( + self, + request: Optional[ + Union[ + campaign_bid_modifier_service.MutateCampaignBidModifiersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_bid_modifier_service.CampaignBidModifierOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_bid_modifier_service.MutateCampaignBidModifiersResponse: + r"""Creates, updates, or removes campaign bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ContextError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignBidModifiersRequest, dict]): + The request object. Request message for + [CampaignBidModifierService.MutateCampaignBidModifiers][google.ads.googleads.v23.services.CampaignBidModifierService.MutateCampaignBidModifiers]. + customer_id (str): + Required. ID of the customer whose + campaign bid modifiers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignBidModifierOperation]): + Required. The list of operations to + perform on individual campaign bid + modifiers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignBidModifiersResponse: + Response message for campaign bid + modifiers mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + campaign_bid_modifier_service.MutateCampaignBidModifiersRequest, + ): + request = ( + campaign_bid_modifier_service.MutateCampaignBidModifiersRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_bid_modifiers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignBidModifierServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignBidModifierServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_bid_modifier_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/base.py new file mode 100644 index 000000000..a4ee3a56a --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + campaign_bid_modifier_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignBidModifierServiceTransport(abc.ABC): + """Abstract transport class for CampaignBidModifierService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_bid_modifiers: gapic_v1.method.wrap_method( + self.mutate_campaign_bid_modifiers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_bid_modifiers( + self, + ) -> Callable[ + [campaign_bid_modifier_service.MutateCampaignBidModifiersRequest], + Union[ + campaign_bid_modifier_service.MutateCampaignBidModifiersResponse, + Awaitable[ + campaign_bid_modifier_service.MutateCampaignBidModifiersResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignBidModifierServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/grpc.py new file mode 100644 index 000000000..9ce431d93 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/grpc.py @@ -0,0 +1,398 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + campaign_bid_modifier_service, +) +from .base import CampaignBidModifierServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignBidModifierService", + "rpcName": str(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.ads.googleads.v23.services.CampaignBidModifierService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignBidModifierServiceGrpcTransport( + CampaignBidModifierServiceTransport +): + """gRPC backend transport for CampaignBidModifierService. + + Service to manage campaign bid modifiers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaign_bid_modifiers( + self, + ) -> Callable[ + [campaign_bid_modifier_service.MutateCampaignBidModifiersRequest], + campaign_bid_modifier_service.MutateCampaignBidModifiersResponse, + ]: + r"""Return a callable for the mutate campaign bid modifiers method over gRPC. + + Creates, updates, or removes campaign bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ContextError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignBidModifiersRequest], + ~.MutateCampaignBidModifiersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_bid_modifiers" not in self._stubs: + self._stubs["mutate_campaign_bid_modifiers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignBidModifierService/MutateCampaignBidModifiers", + request_serializer=campaign_bid_modifier_service.MutateCampaignBidModifiersRequest.serialize, + response_deserializer=campaign_bid_modifier_service.MutateCampaignBidModifiersResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_bid_modifiers"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignBidModifierServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..c18d1d94c --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_bid_modifier_service/transports/grpc_asyncio.py @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + campaign_bid_modifier_service, +) +from .base import CampaignBidModifierServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignBidModifierService", + "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.ads.googleads.v23.services.CampaignBidModifierService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignBidModifierServiceGrpcAsyncIOTransport( + CampaignBidModifierServiceTransport +): + """gRPC AsyncIO backend transport for CampaignBidModifierService. + + Service to manage campaign bid modifiers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaign_bid_modifiers( + self, + ) -> Callable[ + [campaign_bid_modifier_service.MutateCampaignBidModifiersRequest], + Awaitable[ + campaign_bid_modifier_service.MutateCampaignBidModifiersResponse + ], + ]: + r"""Return a callable for the mutate campaign bid modifiers method over gRPC. + + Creates, updates, or removes campaign bid modifiers. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ContextError <>`__ + `CriterionError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignBidModifiersRequest], + Awaitable[~.MutateCampaignBidModifiersResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_bid_modifiers" not in self._stubs: + self._stubs["mutate_campaign_bid_modifiers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignBidModifierService/MutateCampaignBidModifiers", + request_serializer=campaign_bid_modifier_service.MutateCampaignBidModifiersRequest.serialize, + response_deserializer=campaign_bid_modifier_service.MutateCampaignBidModifiersResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_bid_modifiers"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_bid_modifiers: self._wrap_method( + self.mutate_campaign_bid_modifiers, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignBidModifierServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_budget_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_budget_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_budget_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_budget_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_budget_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_budget_service/async_client.py new file mode 100644 index 000000000..9070bdad3 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_budget_service/async_client.py @@ -0,0 +1,430 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import campaign_budget_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignBudgetServiceTransport, DEFAULT_CLIENT_INFO +from .client import CampaignBudgetServiceClient + +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 CampaignBudgetServiceAsyncClient: + """Service to manage campaign budgets.""" + + _client: CampaignBudgetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignBudgetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CampaignBudgetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignBudgetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignBudgetServiceClient._DEFAULT_UNIVERSE + + campaign_budget_path = staticmethod( + CampaignBudgetServiceClient.campaign_budget_path + ) + parse_campaign_budget_path = staticmethod( + CampaignBudgetServiceClient.parse_campaign_budget_path + ) + common_billing_account_path = staticmethod( + CampaignBudgetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignBudgetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignBudgetServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignBudgetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignBudgetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignBudgetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignBudgetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignBudgetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignBudgetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignBudgetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBudgetServiceAsyncClient: The constructed client. + """ + return CampaignBudgetServiceClient.from_service_account_info.__func__(CampaignBudgetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBudgetServiceAsyncClient: The constructed client. + """ + return CampaignBudgetServiceClient.from_service_account_file.__func__(CampaignBudgetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignBudgetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignBudgetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignBudgetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignBudgetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignBudgetServiceTransport, + Callable[..., CampaignBudgetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign budget service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignBudgetServiceTransport,Callable[..., CampaignBudgetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignBudgetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignBudgetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignBudgetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignBudgetService", + "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.ads.googleads.v23.services.CampaignBudgetService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_budgets( + self, + request: Optional[ + Union[campaign_budget_service.MutateCampaignBudgetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_budget_service.CampaignBudgetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_budget_service.MutateCampaignBudgetsResponse: + r"""Creates, updates, or removes campaign budgets. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignBudgetError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignBudgetsRequest, dict]]): + The request object. Request message for + [CampaignBudgetService.MutateCampaignBudgets][google.ads.googleads.v23.services.CampaignBudgetService.MutateCampaignBudgets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaign budgets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignBudgetOperation]`): + Required. The list of operations to + perform on individual campaign budgets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignBudgetsResponse: + Response message for campaign budget + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_budget_service.MutateCampaignBudgetsRequest + ): + request = campaign_budget_service.MutateCampaignBudgetsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_budgets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignBudgetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignBudgetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_budget_service/client.py b/google/ads/googleads/v23/services/services/campaign_budget_service/client.py new file mode 100644 index 000000000..a22d82238 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_budget_service/client.py @@ -0,0 +1,906 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import campaign_budget_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignBudgetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignBudgetServiceGrpcTransport +from .transports.grpc_asyncio import CampaignBudgetServiceGrpcAsyncIOTransport + + +class CampaignBudgetServiceClientMeta(type): + """Metaclass for the CampaignBudgetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignBudgetServiceTransport]] + _transport_registry["grpc"] = CampaignBudgetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignBudgetServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignBudgetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignBudgetServiceClient(metaclass=CampaignBudgetServiceClientMeta): + """Service to manage campaign budgets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBudgetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignBudgetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignBudgetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignBudgetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_budget_path( + customer_id: str, + campaign_budget_id: str, + ) -> str: + """Returns a fully-qualified campaign_budget string.""" + return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( + customer_id=customer_id, + campaign_budget_id=campaign_budget_id, + ) + + @staticmethod + def parse_campaign_budget_path(path: str) -> Dict[str, str]: + """Parses a campaign_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignBudgetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignBudgetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CampaignBudgetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CampaignBudgetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CampaignBudgetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignBudgetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignBudgetServiceTransport, + Callable[..., CampaignBudgetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign budget service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignBudgetServiceTransport,Callable[..., CampaignBudgetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignBudgetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignBudgetServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignBudgetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CampaignBudgetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignBudgetServiceTransport + ) + if transport_provided: + # transport is a CampaignBudgetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CampaignBudgetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignBudgetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignBudgetServiceTransport], + Callable[..., CampaignBudgetServiceTransport], + ] = ( + CampaignBudgetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignBudgetServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignBudgetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignBudgetService", + "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.ads.googleads.v23.services.CampaignBudgetService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_budgets( + self, + request: Optional[ + Union[campaign_budget_service.MutateCampaignBudgetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_budget_service.CampaignBudgetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_budget_service.MutateCampaignBudgetsResponse: + r"""Creates, updates, or removes campaign budgets. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignBudgetError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignBudgetsRequest, dict]): + The request object. Request message for + [CampaignBudgetService.MutateCampaignBudgets][google.ads.googleads.v23.services.CampaignBudgetService.MutateCampaignBudgets]. + customer_id (str): + Required. The ID of the customer + whose campaign budgets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignBudgetOperation]): + Required. The list of operations to + perform on individual campaign budgets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignBudgetsResponse: + Response message for campaign budget + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_budget_service.MutateCampaignBudgetsRequest + ): + request = campaign_budget_service.MutateCampaignBudgetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_budgets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignBudgetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignBudgetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_budget_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_budget_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_budget_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_budget_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_budget_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_budget_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_budget_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_budget_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_budget_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_budget_service/transports/base.py new file mode 100644 index 000000000..834235687 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_budget_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import campaign_budget_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignBudgetServiceTransport(abc.ABC): + """Abstract transport class for CampaignBudgetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_budgets: gapic_v1.method.wrap_method( + self.mutate_campaign_budgets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_budgets( + self, + ) -> Callable[ + [campaign_budget_service.MutateCampaignBudgetsRequest], + Union[ + campaign_budget_service.MutateCampaignBudgetsResponse, + Awaitable[campaign_budget_service.MutateCampaignBudgetsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignBudgetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_budget_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_budget_service/transports/grpc.py new file mode 100644 index 000000000..96eefb1fb --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_budget_service/transports/grpc.py @@ -0,0 +1,393 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import campaign_budget_service +from .base import CampaignBudgetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignBudgetService", + "rpcName": str(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.ads.googleads.v23.services.CampaignBudgetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignBudgetServiceGrpcTransport(CampaignBudgetServiceTransport): + """gRPC backend transport for CampaignBudgetService. + + Service to manage campaign budgets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaign_budgets( + self, + ) -> Callable[ + [campaign_budget_service.MutateCampaignBudgetsRequest], + campaign_budget_service.MutateCampaignBudgetsResponse, + ]: + r"""Return a callable for the mutate campaign budgets method over gRPC. + + Creates, updates, or removes campaign budgets. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignBudgetError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignBudgetsRequest], + ~.MutateCampaignBudgetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_budgets" not in self._stubs: + self._stubs["mutate_campaign_budgets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignBudgetService/MutateCampaignBudgets", + request_serializer=campaign_budget_service.MutateCampaignBudgetsRequest.serialize, + response_deserializer=campaign_budget_service.MutateCampaignBudgetsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_budgets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignBudgetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_budget_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_budget_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..3d6f99025 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_budget_service/transports/grpc_asyncio.py @@ -0,0 +1,414 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import campaign_budget_service +from .base import CampaignBudgetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignBudgetService", + "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.ads.googleads.v23.services.CampaignBudgetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignBudgetServiceGrpcAsyncIOTransport(CampaignBudgetServiceTransport): + """gRPC AsyncIO backend transport for CampaignBudgetService. + + Service to manage campaign budgets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaign_budgets( + self, + ) -> Callable[ + [campaign_budget_service.MutateCampaignBudgetsRequest], + Awaitable[campaign_budget_service.MutateCampaignBudgetsResponse], + ]: + r"""Return a callable for the mutate campaign budgets method over gRPC. + + Creates, updates, or removes campaign budgets. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignBudgetError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignBudgetsRequest], + Awaitable[~.MutateCampaignBudgetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_budgets" not in self._stubs: + self._stubs["mutate_campaign_budgets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignBudgetService/MutateCampaignBudgets", + request_serializer=campaign_budget_service.MutateCampaignBudgetsRequest.serialize, + response_deserializer=campaign_budget_service.MutateCampaignBudgetsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_budgets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_budgets: self._wrap_method( + self.mutate_campaign_budgets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignBudgetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_conversion_goal_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_conversion_goal_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/async_client.py new file mode 100644 index 000000000..ece8c47b2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/async_client.py @@ -0,0 +1,442 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + campaign_conversion_goal_service, +) +from .transports.base import ( + CampaignConversionGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CampaignConversionGoalServiceClient + +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 CampaignConversionGoalServiceAsyncClient: + """Service to manage campaign conversion goal.""" + + _client: CampaignConversionGoalServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignConversionGoalServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CampaignConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignConversionGoalServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod( + CampaignConversionGoalServiceClient.campaign_path + ) + parse_campaign_path = staticmethod( + CampaignConversionGoalServiceClient.parse_campaign_path + ) + campaign_conversion_goal_path = staticmethod( + CampaignConversionGoalServiceClient.campaign_conversion_goal_path + ) + parse_campaign_conversion_goal_path = staticmethod( + CampaignConversionGoalServiceClient.parse_campaign_conversion_goal_path + ) + common_billing_account_path = staticmethod( + CampaignConversionGoalServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignConversionGoalServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignConversionGoalServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignConversionGoalServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignConversionGoalServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignConversionGoalServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignConversionGoalServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignConversionGoalServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignConversionGoalServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignConversionGoalServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignConversionGoalServiceAsyncClient: The constructed client. + """ + return CampaignConversionGoalServiceClient.from_service_account_info.__func__(CampaignConversionGoalServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignConversionGoalServiceAsyncClient: The constructed client. + """ + return CampaignConversionGoalServiceClient.from_service_account_file.__func__(CampaignConversionGoalServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignConversionGoalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignConversionGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignConversionGoalServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + CampaignConversionGoalServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignConversionGoalServiceTransport, + Callable[..., CampaignConversionGoalServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign conversion goal service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignConversionGoalServiceTransport,Callable[..., CampaignConversionGoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignConversionGoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignConversionGoalServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignConversionGoalServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignConversionGoalService", + "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.ads.googleads.v23.services.CampaignConversionGoalService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_conversion_goals( + self, + request: Optional[ + Union[ + campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_conversion_goal_service.CampaignConversionGoalOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse: + r"""Creates, updates or removes campaign conversion + goals. Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignConversionGoalsRequest, dict]]): + The request object. Request message for + [CampaignConversionGoalService.MutateCampaignConversionGoals][google.ads.googleads.v23.services.CampaignConversionGoalService.MutateCampaignConversionGoals]. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaign conversion goals are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignConversionGoalOperation]`): + Required. The list of operations to + perform on individual campaign + conversion goal. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignConversionGoalsResponse: + Response message for a campaign + conversion goal mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest, + ): + request = campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_conversion_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignConversionGoalServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignConversionGoalServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/client.py b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/client.py new file mode 100644 index 000000000..4a80f9507 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/client.py @@ -0,0 +1,943 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + campaign_conversion_goal_service, +) +from .transports.base import ( + CampaignConversionGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignConversionGoalServiceGrpcTransport +from .transports.grpc_asyncio import ( + CampaignConversionGoalServiceGrpcAsyncIOTransport, +) + + +class CampaignConversionGoalServiceClientMeta(type): + """Metaclass for the CampaignConversionGoalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignConversionGoalServiceTransport]] + _transport_registry["grpc"] = CampaignConversionGoalServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignConversionGoalServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignConversionGoalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignConversionGoalServiceClient( + metaclass=CampaignConversionGoalServiceClientMeta +): + """Service to manage campaign conversion goal.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignConversionGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignConversionGoalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_conversion_goal_path( + customer_id: str, + campaign_id: str, + category: str, + source: str, + ) -> str: + """Returns a fully-qualified campaign_conversion_goal string.""" + return "customers/{customer_id}/campaignConversionGoals/{campaign_id}~{category}~{source}".format( + customer_id=customer_id, + campaign_id=campaign_id, + category=category, + source=source, + ) + + @staticmethod + def parse_campaign_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a campaign_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignConversionGoals/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignConversionGoalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignConversionGoalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CampaignConversionGoalServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + CampaignConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = CampaignConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignConversionGoalServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignConversionGoalServiceTransport, + Callable[..., CampaignConversionGoalServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign conversion goal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignConversionGoalServiceTransport,Callable[..., CampaignConversionGoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignConversionGoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignConversionGoalServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignConversionGoalServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CampaignConversionGoalServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignConversionGoalServiceTransport + ) + if transport_provided: + # transport is a CampaignConversionGoalServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CampaignConversionGoalServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignConversionGoalServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignConversionGoalServiceTransport], + Callable[..., CampaignConversionGoalServiceTransport], + ] = ( + CampaignConversionGoalServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignConversionGoalServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignConversionGoalServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignConversionGoalService", + "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.ads.googleads.v23.services.CampaignConversionGoalService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_conversion_goals( + self, + request: Optional[ + Union[ + campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_conversion_goal_service.CampaignConversionGoalOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse: + r"""Creates, updates or removes campaign conversion + goals. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignConversionGoalsRequest, dict]): + The request object. Request message for + [CampaignConversionGoalService.MutateCampaignConversionGoals][google.ads.googleads.v23.services.CampaignConversionGoalService.MutateCampaignConversionGoals]. + customer_id (str): + Required. The ID of the customer + whose campaign conversion goals are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignConversionGoalOperation]): + Required. The list of operations to + perform on individual campaign + conversion goal. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignConversionGoalsResponse: + Response message for a campaign + conversion goal mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest, + ): + request = campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_conversion_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignConversionGoalServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignConversionGoalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_conversion_goal_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/base.py new file mode 100644 index 000000000..9c29e8d20 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + campaign_conversion_goal_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignConversionGoalServiceTransport(abc.ABC): + """Abstract transport class for CampaignConversionGoalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_conversion_goals: gapic_v1.method.wrap_method( + self.mutate_campaign_conversion_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_conversion_goals( + self, + ) -> Callable[ + [campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest], + Union[ + campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse, + Awaitable[ + campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignConversionGoalServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/grpc.py new file mode 100644 index 000000000..ebfdd325d --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/grpc.py @@ -0,0 +1,389 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + campaign_conversion_goal_service, +) +from .base import CampaignConversionGoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignConversionGoalService", + "rpcName": str(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.ads.googleads.v23.services.CampaignConversionGoalService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignConversionGoalServiceGrpcTransport( + CampaignConversionGoalServiceTransport +): + """gRPC backend transport for CampaignConversionGoalService. + + Service to manage campaign conversion goal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaign_conversion_goals( + self, + ) -> Callable[ + [campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest], + campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse, + ]: + r"""Return a callable for the mutate campaign conversion + goals method over gRPC. + + Creates, updates or removes campaign conversion + goals. Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignConversionGoalsRequest], + ~.MutateCampaignConversionGoalsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_conversion_goals" not in self._stubs: + self._stubs["mutate_campaign_conversion_goals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignConversionGoalService/MutateCampaignConversionGoals", + request_serializer=campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest.serialize, + response_deserializer=campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_conversion_goals"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignConversionGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..a5405324b --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_conversion_goal_service/transports/grpc_asyncio.py @@ -0,0 +1,412 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + campaign_conversion_goal_service, +) +from .base import CampaignConversionGoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignConversionGoalService", + "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.ads.googleads.v23.services.CampaignConversionGoalService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignConversionGoalServiceGrpcAsyncIOTransport( + CampaignConversionGoalServiceTransport +): + """gRPC AsyncIO backend transport for CampaignConversionGoalService. + + Service to manage campaign conversion goal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaign_conversion_goals( + self, + ) -> Callable[ + [campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest], + Awaitable[ + campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse + ], + ]: + r"""Return a callable for the mutate campaign conversion + goals method over gRPC. + + Creates, updates or removes campaign conversion + goals. Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignConversionGoalsRequest], + Awaitable[~.MutateCampaignConversionGoalsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_conversion_goals" not in self._stubs: + self._stubs["mutate_campaign_conversion_goals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignConversionGoalService/MutateCampaignConversionGoals", + request_serializer=campaign_conversion_goal_service.MutateCampaignConversionGoalsRequest.serialize, + response_deserializer=campaign_conversion_goal_service.MutateCampaignConversionGoalsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_conversion_goals"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_conversion_goals: self._wrap_method( + self.mutate_campaign_conversion_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignConversionGoalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_criterion_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_criterion_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_criterion_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_criterion_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_criterion_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_criterion_service/async_client.py new file mode 100644 index 000000000..685756b23 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_criterion_service/async_client.py @@ -0,0 +1,487 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import campaign_criterion_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CampaignCriterionServiceClient + +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 CampaignCriterionServiceAsyncClient: + """Service to manage campaign criteria.""" + + _client: CampaignCriterionServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignCriterionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CampaignCriterionServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignCriterionServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod(CampaignCriterionServiceClient.campaign_path) + parse_campaign_path = staticmethod( + CampaignCriterionServiceClient.parse_campaign_path + ) + campaign_criterion_path = staticmethod( + CampaignCriterionServiceClient.campaign_criterion_path + ) + parse_campaign_criterion_path = staticmethod( + CampaignCriterionServiceClient.parse_campaign_criterion_path + ) + carrier_constant_path = staticmethod( + CampaignCriterionServiceClient.carrier_constant_path + ) + parse_carrier_constant_path = staticmethod( + CampaignCriterionServiceClient.parse_carrier_constant_path + ) + combined_audience_path = staticmethod( + CampaignCriterionServiceClient.combined_audience_path + ) + parse_combined_audience_path = staticmethod( + CampaignCriterionServiceClient.parse_combined_audience_path + ) + keyword_theme_constant_path = staticmethod( + CampaignCriterionServiceClient.keyword_theme_constant_path + ) + parse_keyword_theme_constant_path = staticmethod( + CampaignCriterionServiceClient.parse_keyword_theme_constant_path + ) + mobile_app_category_constant_path = staticmethod( + CampaignCriterionServiceClient.mobile_app_category_constant_path + ) + parse_mobile_app_category_constant_path = staticmethod( + CampaignCriterionServiceClient.parse_mobile_app_category_constant_path + ) + mobile_device_constant_path = staticmethod( + CampaignCriterionServiceClient.mobile_device_constant_path + ) + parse_mobile_device_constant_path = staticmethod( + CampaignCriterionServiceClient.parse_mobile_device_constant_path + ) + operating_system_version_constant_path = staticmethod( + CampaignCriterionServiceClient.operating_system_version_constant_path + ) + parse_operating_system_version_constant_path = staticmethod( + CampaignCriterionServiceClient.parse_operating_system_version_constant_path + ) + topic_constant_path = staticmethod( + CampaignCriterionServiceClient.topic_constant_path + ) + parse_topic_constant_path = staticmethod( + CampaignCriterionServiceClient.parse_topic_constant_path + ) + common_billing_account_path = staticmethod( + CampaignCriterionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignCriterionServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignCriterionServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignCriterionServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignCriterionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignCriterionServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignCriterionServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignCriterionServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignCriterionServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignCriterionServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCriterionServiceAsyncClient: The constructed client. + """ + return CampaignCriterionServiceClient.from_service_account_info.__func__(CampaignCriterionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCriterionServiceAsyncClient: The constructed client. + """ + return CampaignCriterionServiceClient.from_service_account_file.__func__(CampaignCriterionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignCriterionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignCriterionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignCriterionServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignCriterionServiceTransport, + Callable[..., CampaignCriterionServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign criterion service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignCriterionServiceTransport,Callable[..., CampaignCriterionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignCriterionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignCriterionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignCriterionServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignCriterionService", + "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.ads.googleads.v23.services.CampaignCriterionService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_criteria( + self, + request: Optional[ + Union[ + campaign_criterion_service.MutateCampaignCriteriaRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_criterion_service.CampaignCriterionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_criterion_service.MutateCampaignCriteriaResponse: + r"""Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CampaignCriterionError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `FunctionError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RegionCodeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignCriteriaRequest, dict]]): + The request object. Request message for + [CampaignCriterionService.MutateCampaignCriteria][google.ads.googleads.v23.services.CampaignCriterionService.MutateCampaignCriteria]. + customer_id (:class:`str`): + Required. The ID of the customer + whose criteria are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignCriterionOperation]`): + Required. The list of operations to + perform on individual criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignCriteriaResponse: + Response message for campaign + criterion mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_criterion_service.MutateCampaignCriteriaRequest + ): + request = campaign_criterion_service.MutateCampaignCriteriaRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignCriterionServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignCriterionServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_criterion_service/client.py b/google/ads/googleads/v23/services/services/campaign_criterion_service/client.py new file mode 100644 index 000000000..0ad2ef452 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_criterion_service/client.py @@ -0,0 +1,1063 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import campaign_criterion_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignCriterionServiceGrpcTransport +from .transports.grpc_asyncio import ( + CampaignCriterionServiceGrpcAsyncIOTransport, +) + + +class CampaignCriterionServiceClientMeta(type): + """Metaclass for the CampaignCriterionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignCriterionServiceTransport]] + _transport_registry["grpc"] = CampaignCriterionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignCriterionServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignCriterionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignCriterionServiceClient( + metaclass=CampaignCriterionServiceClientMeta +): + """Service to manage campaign criteria.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignCriterionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_criterion_path( + customer_id: str, + campaign_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_criterion string.""" + return "customers/{customer_id}/campaignCriteria/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_criterion_path(path: str) -> Dict[str, str]: + """Parses a campaign_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def carrier_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified carrier_constant string.""" + return "carrierConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_carrier_constant_path(path: str) -> Dict[str, str]: + """Parses a carrier_constant path into its component segments.""" + m = re.match(r"^carrierConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def combined_audience_path( + customer_id: str, + combined_audience_id: str, + ) -> str: + """Returns a fully-qualified combined_audience string.""" + return "customers/{customer_id}/combinedAudiences/{combined_audience_id}".format( + customer_id=customer_id, + combined_audience_id=combined_audience_id, + ) + + @staticmethod + def parse_combined_audience_path(path: str) -> Dict[str, str]: + """Parses a combined_audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/combinedAudiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_theme_constant_path( + express_category_id: str, + express_sub_category_id: str, + ) -> str: + """Returns a fully-qualified keyword_theme_constant string.""" + return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( + express_category_id=express_category_id, + express_sub_category_id=express_sub_category_id, + ) + + @staticmethod + def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: + """Parses a keyword_theme_constant path into its component segments.""" + m = re.match( + r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_app_category_constant_path( + mobile_app_category_id: str, + ) -> str: + """Returns a fully-qualified mobile_app_category_constant string.""" + return "mobileAppCategoryConstants/{mobile_app_category_id}".format( + mobile_app_category_id=mobile_app_category_id, + ) + + @staticmethod + def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: + """Parses a mobile_app_category_constant path into its component segments.""" + m = re.match( + r"^mobileAppCategoryConstants/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_device_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified mobile_device_constant string.""" + return "mobileDeviceConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_mobile_device_constant_path(path: str) -> Dict[str, str]: + """Parses a mobile_device_constant path into its component segments.""" + m = re.match(r"^mobileDeviceConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def operating_system_version_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified operating_system_version_constant string.""" + return "operatingSystemVersionConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_operating_system_version_constant_path( + path: str, + ) -> Dict[str, str]: + """Parses a operating_system_version_constant path into its component segments.""" + m = re.match( + r"^operatingSystemVersionConstants/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def topic_constant_path( + topic_id: str, + ) -> str: + """Returns a fully-qualified topic_constant string.""" + return "topicConstants/{topic_id}".format( + topic_id=topic_id, + ) + + @staticmethod + def parse_topic_constant_path(path: str) -> Dict[str, str]: + """Parses a topic_constant path into its component segments.""" + m = re.match(r"^topicConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignCriterionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignCriterionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CampaignCriterionServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CampaignCriterionServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = CampaignCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignCriterionServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignCriterionServiceTransport, + Callable[..., CampaignCriterionServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign criterion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignCriterionServiceTransport,Callable[..., CampaignCriterionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignCriterionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignCriterionServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignCriterionServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CampaignCriterionServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignCriterionServiceTransport + ) + if transport_provided: + # transport is a CampaignCriterionServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CampaignCriterionServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignCriterionServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignCriterionServiceTransport], + Callable[..., CampaignCriterionServiceTransport], + ] = ( + CampaignCriterionServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignCriterionServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignCriterionServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignCriterionService", + "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.ads.googleads.v23.services.CampaignCriterionService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_criteria( + self, + request: Optional[ + Union[ + campaign_criterion_service.MutateCampaignCriteriaRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_criterion_service.CampaignCriterionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_criterion_service.MutateCampaignCriteriaResponse: + r"""Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CampaignCriterionError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `FunctionError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RegionCodeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignCriteriaRequest, dict]): + The request object. Request message for + [CampaignCriterionService.MutateCampaignCriteria][google.ads.googleads.v23.services.CampaignCriterionService.MutateCampaignCriteria]. + customer_id (str): + Required. The ID of the customer + whose criteria are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignCriterionOperation]): + Required. The list of operations to + perform on individual criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignCriteriaResponse: + Response message for campaign + criterion mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_criterion_service.MutateCampaignCriteriaRequest + ): + request = campaign_criterion_service.MutateCampaignCriteriaRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignCriterionServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignCriterionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_criterion_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_criterion_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_criterion_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_criterion_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_criterion_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_criterion_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_criterion_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_criterion_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_criterion_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_criterion_service/transports/base.py new file mode 100644 index 000000000..7c5b84bd5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_criterion_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import campaign_criterion_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignCriterionServiceTransport(abc.ABC): + """Abstract transport class for CampaignCriterionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_criteria: gapic_v1.method.wrap_method( + self.mutate_campaign_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_criteria( + self, + ) -> Callable[ + [campaign_criterion_service.MutateCampaignCriteriaRequest], + Union[ + campaign_criterion_service.MutateCampaignCriteriaResponse, + Awaitable[ + campaign_criterion_service.MutateCampaignCriteriaResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignCriterionServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_criterion_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_criterion_service/transports/grpc.py new file mode 100644 index 000000000..5d29b76cb --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_criterion_service/transports/grpc.py @@ -0,0 +1,398 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import campaign_criterion_service +from .base import CampaignCriterionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignCriterionService", + "rpcName": str(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.ads.googleads.v23.services.CampaignCriterionService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignCriterionServiceGrpcTransport(CampaignCriterionServiceTransport): + """gRPC backend transport for CampaignCriterionService. + + Service to manage campaign criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaign_criteria( + self, + ) -> Callable[ + [campaign_criterion_service.MutateCampaignCriteriaRequest], + campaign_criterion_service.MutateCampaignCriteriaResponse, + ]: + r"""Return a callable for the mutate campaign criteria method over gRPC. + + Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CampaignCriterionError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `FunctionError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RegionCodeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignCriteriaRequest], + ~.MutateCampaignCriteriaResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_criteria" not in self._stubs: + self._stubs["mutate_campaign_criteria"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignCriterionService/MutateCampaignCriteria", + request_serializer=campaign_criterion_service.MutateCampaignCriteriaRequest.serialize, + response_deserializer=campaign_criterion_service.MutateCampaignCriteriaResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_criteria"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_criterion_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_criterion_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..50be19aa4 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_criterion_service/transports/grpc_asyncio.py @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import campaign_criterion_service +from .base import CampaignCriterionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignCriterionService", + "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.ads.googleads.v23.services.CampaignCriterionService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignCriterionServiceGrpcAsyncIOTransport( + CampaignCriterionServiceTransport +): + """gRPC AsyncIO backend transport for CampaignCriterionService. + + Service to manage campaign criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaign_criteria( + self, + ) -> Callable[ + [campaign_criterion_service.MutateCampaignCriteriaRequest], + Awaitable[campaign_criterion_service.MutateCampaignCriteriaResponse], + ]: + r"""Return a callable for the mutate campaign criteria method over gRPC. + + Creates, updates, or removes criteria. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CampaignCriterionError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `CriterionError <>`__ `DatabaseError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `FunctionError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperationAccessDeniedError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RegionCodeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignCriteriaRequest], + Awaitable[~.MutateCampaignCriteriaResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_criteria" not in self._stubs: + self._stubs["mutate_campaign_criteria"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignCriterionService/MutateCampaignCriteria", + request_serializer=campaign_criterion_service.MutateCampaignCriteriaRequest.serialize, + response_deserializer=campaign_criterion_service.MutateCampaignCriteriaResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_criteria"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_criteria: self._wrap_method( + self.mutate_campaign_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignCriterionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_customizer_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_customizer_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_customizer_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_customizer_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_customizer_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_customizer_service/async_client.py new file mode 100644 index 000000000..12c729285 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_customizer_service/async_client.py @@ -0,0 +1,445 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import campaign_customizer_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CampaignCustomizerServiceClient + +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 CampaignCustomizerServiceAsyncClient: + """Service to manage campaign customizer""" + + _client: CampaignCustomizerServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignCustomizerServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CampaignCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignCustomizerServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod(CampaignCustomizerServiceClient.campaign_path) + parse_campaign_path = staticmethod( + CampaignCustomizerServiceClient.parse_campaign_path + ) + campaign_customizer_path = staticmethod( + CampaignCustomizerServiceClient.campaign_customizer_path + ) + parse_campaign_customizer_path = staticmethod( + CampaignCustomizerServiceClient.parse_campaign_customizer_path + ) + customizer_attribute_path = staticmethod( + CampaignCustomizerServiceClient.customizer_attribute_path + ) + parse_customizer_attribute_path = staticmethod( + CampaignCustomizerServiceClient.parse_customizer_attribute_path + ) + common_billing_account_path = staticmethod( + CampaignCustomizerServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignCustomizerServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignCustomizerServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignCustomizerServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignCustomizerServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignCustomizerServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignCustomizerServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignCustomizerServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignCustomizerServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignCustomizerServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCustomizerServiceAsyncClient: The constructed client. + """ + return CampaignCustomizerServiceClient.from_service_account_info.__func__(CampaignCustomizerServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCustomizerServiceAsyncClient: The constructed client. + """ + return CampaignCustomizerServiceClient.from_service_account_file.__func__(CampaignCustomizerServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignCustomizerServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignCustomizerServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignCustomizerServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignCustomizerServiceTransport, + Callable[..., CampaignCustomizerServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign customizer service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignCustomizerServiceTransport,Callable[..., CampaignCustomizerServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignCustomizerServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignCustomizerServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignCustomizerServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignCustomizerService", + "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.ads.googleads.v23.services.CampaignCustomizerService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_customizers( + self, + request: Optional[ + Union[ + campaign_customizer_service.MutateCampaignCustomizersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_customizer_service.CampaignCustomizerOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_customizer_service.MutateCampaignCustomizersResponse: + r"""Creates, updates or removes campaign customizers. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignCustomizersRequest, dict]]): + The request object. Request message for + [CampaignCustomizerService.MutateCampaignCustomizers][google.ads.googleads.v23.services.CampaignCustomizerService.MutateCampaignCustomizers]. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaign customizers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignCustomizerOperation]`): + Required. The list of operations to + perform on individual campaign + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignCustomizersResponse: + Response message for a campaign + customizer mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + campaign_customizer_service.MutateCampaignCustomizersRequest, + ): + request = ( + campaign_customizer_service.MutateCampaignCustomizersRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignCustomizerServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignCustomizerServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_customizer_service/client.py b/google/ads/googleads/v23/services/services/campaign_customizer_service/client.py new file mode 100644 index 000000000..aedb0a2d7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_customizer_service/client.py @@ -0,0 +1,957 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import campaign_customizer_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignCustomizerServiceGrpcTransport +from .transports.grpc_asyncio import ( + CampaignCustomizerServiceGrpcAsyncIOTransport, +) + + +class CampaignCustomizerServiceClientMeta(type): + """Metaclass for the CampaignCustomizerService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignCustomizerServiceTransport]] + _transport_registry["grpc"] = CampaignCustomizerServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignCustomizerServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignCustomizerServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignCustomizerServiceClient( + metaclass=CampaignCustomizerServiceClientMeta +): + """Service to manage campaign customizer""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignCustomizerServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_customizer_path( + customer_id: str, + campaign_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified campaign_customizer string.""" + return "customers/{customer_id}/campaignCustomizers/{campaign_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_campaign_customizer_path(path: str) -> Dict[str, str]: + """Parses a campaign_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignCustomizerServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignCustomizerServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CampaignCustomizerServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CampaignCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = CampaignCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignCustomizerServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignCustomizerServiceTransport, + Callable[..., CampaignCustomizerServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign customizer service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignCustomizerServiceTransport,Callable[..., CampaignCustomizerServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignCustomizerServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignCustomizerServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignCustomizerServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CampaignCustomizerServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignCustomizerServiceTransport + ) + if transport_provided: + # transport is a CampaignCustomizerServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CampaignCustomizerServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignCustomizerServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignCustomizerServiceTransport], + Callable[..., CampaignCustomizerServiceTransport], + ] = ( + CampaignCustomizerServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignCustomizerServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignCustomizerServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignCustomizerService", + "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.ads.googleads.v23.services.CampaignCustomizerService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_customizers( + self, + request: Optional[ + Union[ + campaign_customizer_service.MutateCampaignCustomizersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_customizer_service.CampaignCustomizerOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_customizer_service.MutateCampaignCustomizersResponse: + r"""Creates, updates or removes campaign customizers. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignCustomizersRequest, dict]): + The request object. Request message for + [CampaignCustomizerService.MutateCampaignCustomizers][google.ads.googleads.v23.services.CampaignCustomizerService.MutateCampaignCustomizers]. + customer_id (str): + Required. The ID of the customer + whose campaign customizers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignCustomizerOperation]): + Required. The list of operations to + perform on individual campaign + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignCustomizersResponse: + Response message for a campaign + customizer mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + campaign_customizer_service.MutateCampaignCustomizersRequest, + ): + request = ( + campaign_customizer_service.MutateCampaignCustomizersRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignCustomizerServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignCustomizerServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_customizer_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_customizer_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_customizer_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_customizer_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_customizer_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_customizer_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_customizer_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_customizer_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_customizer_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_customizer_service/transports/base.py new file mode 100644 index 000000000..4d12131ca --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_customizer_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import campaign_customizer_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignCustomizerServiceTransport(abc.ABC): + """Abstract transport class for CampaignCustomizerService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_customizers: gapic_v1.method.wrap_method( + self.mutate_campaign_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_customizers( + self, + ) -> Callable[ + [campaign_customizer_service.MutateCampaignCustomizersRequest], + Union[ + campaign_customizer_service.MutateCampaignCustomizersResponse, + Awaitable[ + campaign_customizer_service.MutateCampaignCustomizersResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignCustomizerServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_customizer_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_customizer_service/transports/grpc.py new file mode 100644 index 000000000..8bbc7c64e --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_customizer_service/transports/grpc.py @@ -0,0 +1,386 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import campaign_customizer_service +from .base import CampaignCustomizerServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignCustomizerService", + "rpcName": str(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.ads.googleads.v23.services.CampaignCustomizerService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignCustomizerServiceGrpcTransport( + CampaignCustomizerServiceTransport +): + """gRPC backend transport for CampaignCustomizerService. + + Service to manage campaign customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaign_customizers( + self, + ) -> Callable[ + [campaign_customizer_service.MutateCampaignCustomizersRequest], + campaign_customizer_service.MutateCampaignCustomizersResponse, + ]: + r"""Return a callable for the mutate campaign customizers method over gRPC. + + Creates, updates or removes campaign customizers. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignCustomizersRequest], + ~.MutateCampaignCustomizersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_customizers" not in self._stubs: + self._stubs["mutate_campaign_customizers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignCustomizerService/MutateCampaignCustomizers", + request_serializer=campaign_customizer_service.MutateCampaignCustomizersRequest.serialize, + response_deserializer=campaign_customizer_service.MutateCampaignCustomizersResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_customizers"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_customizer_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_customizer_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..8cc70cb19 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_customizer_service/transports/grpc_asyncio.py @@ -0,0 +1,409 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import campaign_customizer_service +from .base import CampaignCustomizerServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignCustomizerService", + "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.ads.googleads.v23.services.CampaignCustomizerService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignCustomizerServiceGrpcAsyncIOTransport( + CampaignCustomizerServiceTransport +): + """gRPC AsyncIO backend transport for CampaignCustomizerService. + + Service to manage campaign customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaign_customizers( + self, + ) -> Callable[ + [campaign_customizer_service.MutateCampaignCustomizersRequest], + Awaitable[ + campaign_customizer_service.MutateCampaignCustomizersResponse + ], + ]: + r"""Return a callable for the mutate campaign customizers method over gRPC. + + Creates, updates or removes campaign customizers. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignCustomizersRequest], + Awaitable[~.MutateCampaignCustomizersResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_customizers" not in self._stubs: + self._stubs["mutate_campaign_customizers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignCustomizerService/MutateCampaignCustomizers", + request_serializer=campaign_customizer_service.MutateCampaignCustomizersRequest.serialize, + response_deserializer=campaign_customizer_service.MutateCampaignCustomizersResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_customizers"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_customizers: self._wrap_method( + self.mutate_campaign_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignCustomizerServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_draft_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_draft_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_draft_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_draft_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_draft_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_draft_service/async_client.py new file mode 100644 index 000000000..95f68e734 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_draft_service/async_client.py @@ -0,0 +1,681 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.services.campaign_draft_service import ( + pagers, +) +from google.ads.googleads.v23.services.types import campaign_draft_service +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignDraftServiceTransport, DEFAULT_CLIENT_INFO +from .client import CampaignDraftServiceClient + +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 CampaignDraftServiceAsyncClient: + """Service to manage campaign drafts.""" + + _client: CampaignDraftServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignDraftServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CampaignDraftServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignDraftServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignDraftServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod(CampaignDraftServiceClient.campaign_path) + parse_campaign_path = staticmethod( + CampaignDraftServiceClient.parse_campaign_path + ) + campaign_draft_path = staticmethod( + CampaignDraftServiceClient.campaign_draft_path + ) + parse_campaign_draft_path = staticmethod( + CampaignDraftServiceClient.parse_campaign_draft_path + ) + common_billing_account_path = staticmethod( + CampaignDraftServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignDraftServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignDraftServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignDraftServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignDraftServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignDraftServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignDraftServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignDraftServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignDraftServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignDraftServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignDraftServiceAsyncClient: The constructed client. + """ + return CampaignDraftServiceClient.from_service_account_info.__func__(CampaignDraftServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignDraftServiceAsyncClient: The constructed client. + """ + return CampaignDraftServiceClient.from_service_account_file.__func__(CampaignDraftServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignDraftServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignDraftServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignDraftServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignDraftServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignDraftServiceTransport, + Callable[..., CampaignDraftServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign draft service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignDraftServiceTransport,Callable[..., CampaignDraftServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignDraftServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignDraftServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignDraftServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignDraftService", + "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.ads.googleads.v23.services.CampaignDraftService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_drafts( + self, + request: Optional[ + Union[campaign_draft_service.MutateCampaignDraftsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_draft_service.CampaignDraftOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_draft_service.MutateCampaignDraftsResponse: + r"""Creates, updates, or removes campaign drafts. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignDraftsRequest, dict]]): + The request object. Request message for + [CampaignDraftService.MutateCampaignDrafts][google.ads.googleads.v23.services.CampaignDraftService.MutateCampaignDrafts]. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaign drafts are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignDraftOperation]`): + Required. The list of operations to + perform on individual campaign drafts. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignDraftsResponse: + Response message for campaign draft + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_draft_service.MutateCampaignDraftsRequest + ): + request = campaign_draft_service.MutateCampaignDraftsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_drafts + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def promote_campaign_draft( + self, + request: Optional[ + Union[campaign_draft_service.PromoteCampaignDraftRequest, dict] + ] = None, + *, + campaign_draft: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Promotes the changes in a draft back to the base campaign. + + This method returns a Long Running Operation (LRO) indicating if + the Promote is done. Use + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + to poll the LRO until it is done. Only a done status is returned + in the response. See the status in the Campaign Draft resource + to determine if the promotion was successful. If the LRO failed, + use + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v23.services.CampaignDraftService.ListCampaignDraftAsyncErrors] + to view the list of error reasons. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.PromoteCampaignDraftRequest, dict]]): + The request object. Request message for + [CampaignDraftService.PromoteCampaignDraft][google.ads.googleads.v23.services.CampaignDraftService.PromoteCampaignDraft]. + campaign_draft (:class:`str`): + Required. The resource name of the + campaign draft to promote. + + This corresponds to the ``campaign_draft`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [campaign_draft] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_draft_service.PromoteCampaignDraftRequest + ): + request = campaign_draft_service.PromoteCampaignDraftRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if campaign_draft is not None: + request.campaign_draft = campaign_draft + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.promote_campaign_draft + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("campaign_draft", request.campaign_draft),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=empty_pb2.Empty, + ) + + # Done; return the response. + return response + + async def list_campaign_draft_async_errors( + self, + request: Optional[ + Union[ + campaign_draft_service.ListCampaignDraftAsyncErrorsRequest, dict + ] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListCampaignDraftAsyncErrorsAsyncPager: + r"""Returns all errors that occurred during CampaignDraft promote. + Throws an error if called before campaign draft is promoted. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListCampaignDraftAsyncErrorsRequest, dict]]): + The request object. Request message for + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v23.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. + resource_name (:class:`str`): + Required. The name of the campaign + draft from which to retrieve the async + errors. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.campaign_draft_service.pagers.ListCampaignDraftAsyncErrorsAsyncPager: + Response message for + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v23.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_draft_service.ListCampaignDraftAsyncErrorsRequest + ): + request = ( + campaign_draft_service.ListCampaignDraftAsyncErrorsRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_campaign_draft_async_errors + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListCampaignDraftAsyncErrorsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignDraftServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignDraftServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_draft_service/client.py b/google/ads/googleads/v23/services/services/campaign_draft_service/client.py new file mode 100644 index 000000000..49b03f87c --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_draft_service/client.py @@ -0,0 +1,1171 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.services.campaign_draft_service import ( + pagers, +) +from google.ads.googleads.v23.services.types import campaign_draft_service +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignDraftServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignDraftServiceGrpcTransport +from .transports.grpc_asyncio import CampaignDraftServiceGrpcAsyncIOTransport + + +class CampaignDraftServiceClientMeta(type): + """Metaclass for the CampaignDraftService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignDraftServiceTransport]] + _transport_registry["grpc"] = CampaignDraftServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignDraftServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignDraftServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignDraftServiceClient(metaclass=CampaignDraftServiceClientMeta): + """Service to manage campaign drafts.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignDraftServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignDraftServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignDraftServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignDraftServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_draft_path( + customer_id: str, + base_campaign_id: str, + draft_id: str, + ) -> str: + """Returns a fully-qualified campaign_draft string.""" + return "customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}".format( + customer_id=customer_id, + base_campaign_id=base_campaign_id, + draft_id=draft_id, + ) + + @staticmethod + def parse_campaign_draft_path(path: str) -> Dict[str, str]: + """Parses a campaign_draft path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignDrafts/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignDraftServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignDraftServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CampaignDraftServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CampaignDraftServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CampaignDraftServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignDraftServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignDraftServiceTransport, + Callable[..., CampaignDraftServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign draft service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignDraftServiceTransport,Callable[..., CampaignDraftServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignDraftServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignDraftServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignDraftServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = CampaignDraftServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignDraftServiceTransport + ) + if transport_provided: + # transport is a CampaignDraftServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CampaignDraftServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignDraftServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignDraftServiceTransport], + Callable[..., CampaignDraftServiceTransport], + ] = ( + CampaignDraftServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignDraftServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignDraftServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignDraftService", + "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.ads.googleads.v23.services.CampaignDraftService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_drafts( + self, + request: Optional[ + Union[campaign_draft_service.MutateCampaignDraftsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_draft_service.CampaignDraftOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_draft_service.MutateCampaignDraftsResponse: + r"""Creates, updates, or removes campaign drafts. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignDraftsRequest, dict]): + The request object. Request message for + [CampaignDraftService.MutateCampaignDrafts][google.ads.googleads.v23.services.CampaignDraftService.MutateCampaignDrafts]. + customer_id (str): + Required. The ID of the customer + whose campaign drafts are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignDraftOperation]): + Required. The list of operations to + perform on individual campaign drafts. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignDraftsResponse: + Response message for campaign draft + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_draft_service.MutateCampaignDraftsRequest + ): + request = campaign_draft_service.MutateCampaignDraftsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_drafts + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def promote_campaign_draft( + self, + request: Optional[ + Union[campaign_draft_service.PromoteCampaignDraftRequest, dict] + ] = None, + *, + campaign_draft: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Promotes the changes in a draft back to the base campaign. + + This method returns a Long Running Operation (LRO) indicating if + the Promote is done. Use + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + to poll the LRO until it is done. Only a done status is returned + in the response. See the status in the Campaign Draft resource + to determine if the promotion was successful. If the LRO failed, + use + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v23.services.CampaignDraftService.ListCampaignDraftAsyncErrors] + to view the list of error reasons. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.PromoteCampaignDraftRequest, dict]): + The request object. Request message for + [CampaignDraftService.PromoteCampaignDraft][google.ads.googleads.v23.services.CampaignDraftService.PromoteCampaignDraft]. + campaign_draft (str): + Required. The resource name of the + campaign draft to promote. + + This corresponds to the ``campaign_draft`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [campaign_draft] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_draft_service.PromoteCampaignDraftRequest + ): + request = campaign_draft_service.PromoteCampaignDraftRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if campaign_draft is not None: + request.campaign_draft = campaign_draft + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.promote_campaign_draft + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("campaign_draft", request.campaign_draft),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=empty_pb2.Empty, + ) + + # Done; return the response. + return response + + def list_campaign_draft_async_errors( + self, + request: Optional[ + Union[ + campaign_draft_service.ListCampaignDraftAsyncErrorsRequest, dict + ] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListCampaignDraftAsyncErrorsPager: + r"""Returns all errors that occurred during CampaignDraft promote. + Throws an error if called before campaign draft is promoted. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListCampaignDraftAsyncErrorsRequest, dict]): + The request object. Request message for + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v23.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. + resource_name (str): + Required. The name of the campaign + draft from which to retrieve the async + errors. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.campaign_draft_service.pagers.ListCampaignDraftAsyncErrorsPager: + Response message for + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v23.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_draft_service.ListCampaignDraftAsyncErrorsRequest + ): + request = ( + campaign_draft_service.ListCampaignDraftAsyncErrorsRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_campaign_draft_async_errors + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListCampaignDraftAsyncErrorsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignDraftServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignDraftServiceClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_draft_service/pagers.py b/google/ads/googleads/v23/services/services/campaign_draft_service/pagers.py new file mode 100644 index 000000000..ca4bd1b5e --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_draft_service/pagers.py @@ -0,0 +1,213 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Sequence, + Tuple, + Iterator, + Union, +) + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import campaign_draft_service +from google.rpc import status_pb2 # type: ignore + + +class ListCampaignDraftAsyncErrorsPager: + """A pager for iterating through ``list_campaign_draft_async_errors`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.ListCampaignDraftAsyncErrorsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``errors`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListCampaignDraftAsyncErrors`` requests and continue to iterate + through the ``errors`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.ListCampaignDraftAsyncErrorsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., campaign_draft_service.ListCampaignDraftAsyncErrorsResponse + ], + request: campaign_draft_service.ListCampaignDraftAsyncErrorsRequest, + response: campaign_draft_service.ListCampaignDraftAsyncErrorsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.ListCampaignDraftAsyncErrorsRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.ListCampaignDraftAsyncErrorsResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = ( + campaign_draft_service.ListCampaignDraftAsyncErrorsRequest(request) + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[campaign_draft_service.ListCampaignDraftAsyncErrorsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[status_pb2.Status]: + for page in self.pages: + yield from page.errors + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListCampaignDraftAsyncErrorsAsyncPager: + """A pager for iterating through ``list_campaign_draft_async_errors`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.ListCampaignDraftAsyncErrorsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``errors`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListCampaignDraftAsyncErrors`` requests and continue to iterate + through the ``errors`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.ListCampaignDraftAsyncErrorsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., + Awaitable[ + campaign_draft_service.ListCampaignDraftAsyncErrorsResponse + ], + ], + request: campaign_draft_service.ListCampaignDraftAsyncErrorsRequest, + response: campaign_draft_service.ListCampaignDraftAsyncErrorsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.ListCampaignDraftAsyncErrorsRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.ListCampaignDraftAsyncErrorsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = ( + campaign_draft_service.ListCampaignDraftAsyncErrorsRequest(request) + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[ + campaign_draft_service.ListCampaignDraftAsyncErrorsResponse + ]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[status_pb2.Status]: + async def async_generator(): + async for page in self.pages: + for response in page.errors: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/campaign_draft_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_draft_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_draft_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_draft_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_draft_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_draft_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_draft_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_draft_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_draft_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_draft_service/transports/base.py new file mode 100644 index 000000000..5923f9fdc --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_draft_service/transports/base.py @@ -0,0 +1,212 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import campaign_draft_service +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignDraftServiceTransport(abc.ABC): + """Abstract transport class for CampaignDraftService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_drafts: gapic_v1.method.wrap_method( + self.mutate_campaign_drafts, + default_timeout=None, + client_info=client_info, + ), + self.promote_campaign_draft: gapic_v1.method.wrap_method( + self.promote_campaign_draft, + default_timeout=None, + client_info=client_info, + ), + self.list_campaign_draft_async_errors: gapic_v1.method.wrap_method( + self.list_campaign_draft_async_errors, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def mutate_campaign_drafts( + self, + ) -> Callable[ + [campaign_draft_service.MutateCampaignDraftsRequest], + Union[ + campaign_draft_service.MutateCampaignDraftsResponse, + Awaitable[campaign_draft_service.MutateCampaignDraftsResponse], + ], + ]: + raise NotImplementedError() + + @property + def promote_campaign_draft( + self, + ) -> Callable[ + [campaign_draft_service.PromoteCampaignDraftRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def list_campaign_draft_async_errors( + self, + ) -> Callable[ + [campaign_draft_service.ListCampaignDraftAsyncErrorsRequest], + Union[ + campaign_draft_service.ListCampaignDraftAsyncErrorsResponse, + Awaitable[ + campaign_draft_service.ListCampaignDraftAsyncErrorsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignDraftServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_draft_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_draft_service/transports/grpc.py new file mode 100644 index 000000000..14521c12d --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_draft_service/transports/grpc.py @@ -0,0 +1,493 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import campaign_draft_service +from google.longrunning import operations_pb2 # type: ignore +from .base import CampaignDraftServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignDraftService", + "rpcName": str(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.ads.googleads.v23.services.CampaignDraftService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignDraftServiceGrpcTransport(CampaignDraftServiceTransport): + """gRPC backend transport for CampaignDraftService. + + Service to manage campaign drafts. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # 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._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def mutate_campaign_drafts( + self, + ) -> Callable[ + [campaign_draft_service.MutateCampaignDraftsRequest], + campaign_draft_service.MutateCampaignDraftsResponse, + ]: + r"""Return a callable for the mutate campaign drafts method over gRPC. + + Creates, updates, or removes campaign drafts. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCampaignDraftsRequest], + ~.MutateCampaignDraftsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_drafts" not in self._stubs: + self._stubs["mutate_campaign_drafts"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignDraftService/MutateCampaignDrafts", + request_serializer=campaign_draft_service.MutateCampaignDraftsRequest.serialize, + response_deserializer=campaign_draft_service.MutateCampaignDraftsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_drafts"] + + @property + def promote_campaign_draft( + self, + ) -> Callable[ + [campaign_draft_service.PromoteCampaignDraftRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the promote campaign draft method over gRPC. + + Promotes the changes in a draft back to the base campaign. + + This method returns a Long Running Operation (LRO) indicating if + the Promote is done. Use + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + to poll the LRO until it is done. Only a done status is returned + in the response. See the status in the Campaign Draft resource + to determine if the promotion was successful. If the LRO failed, + use + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v23.services.CampaignDraftService.ListCampaignDraftAsyncErrors] + to view the list of error reasons. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.PromoteCampaignDraftRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "promote_campaign_draft" not in self._stubs: + self._stubs["promote_campaign_draft"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignDraftService/PromoteCampaignDraft", + request_serializer=campaign_draft_service.PromoteCampaignDraftRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["promote_campaign_draft"] + + @property + def list_campaign_draft_async_errors( + self, + ) -> Callable[ + [campaign_draft_service.ListCampaignDraftAsyncErrorsRequest], + campaign_draft_service.ListCampaignDraftAsyncErrorsResponse, + ]: + r"""Return a callable for the list campaign draft async + errors method over gRPC. + + Returns all errors that occurred during CampaignDraft promote. + Throws an error if called before campaign draft is promoted. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListCampaignDraftAsyncErrorsRequest], + ~.ListCampaignDraftAsyncErrorsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_campaign_draft_async_errors" not in self._stubs: + self._stubs["list_campaign_draft_async_errors"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignDraftService/ListCampaignDraftAsyncErrors", + request_serializer=campaign_draft_service.ListCampaignDraftAsyncErrorsRequest.serialize, + response_deserializer=campaign_draft_service.ListCampaignDraftAsyncErrorsResponse.deserialize, + ) + ) + return self._stubs["list_campaign_draft_async_errors"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignDraftServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_draft_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_draft_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..7683ca616 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_draft_service/transports/grpc_asyncio.py @@ -0,0 +1,526 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import campaign_draft_service +from google.longrunning import operations_pb2 # type: ignore +from .base import CampaignDraftServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignDraftService", + "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.ads.googleads.v23.services.CampaignDraftService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignDraftServiceGrpcAsyncIOTransport(CampaignDraftServiceTransport): + """gRPC AsyncIO backend transport for CampaignDraftService. + + Service to manage campaign drafts. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[ + operations_v1.OperationsAsyncClient + ] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # 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._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def mutate_campaign_drafts( + self, + ) -> Callable[ + [campaign_draft_service.MutateCampaignDraftsRequest], + Awaitable[campaign_draft_service.MutateCampaignDraftsResponse], + ]: + r"""Return a callable for the mutate campaign drafts method over gRPC. + + Creates, updates, or removes campaign drafts. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCampaignDraftsRequest], + Awaitable[~.MutateCampaignDraftsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_drafts" not in self._stubs: + self._stubs["mutate_campaign_drafts"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignDraftService/MutateCampaignDrafts", + request_serializer=campaign_draft_service.MutateCampaignDraftsRequest.serialize, + response_deserializer=campaign_draft_service.MutateCampaignDraftsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_drafts"] + + @property + def promote_campaign_draft( + self, + ) -> Callable[ + [campaign_draft_service.PromoteCampaignDraftRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the promote campaign draft method over gRPC. + + Promotes the changes in a draft back to the base campaign. + + This method returns a Long Running Operation (LRO) indicating if + the Promote is done. Use + [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] + to poll the LRO until it is done. Only a done status is returned + in the response. See the status in the Campaign Draft resource + to determine if the promotion was successful. If the LRO failed, + use + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v23.services.CampaignDraftService.ListCampaignDraftAsyncErrors] + to view the list of error reasons. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignDraftError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.PromoteCampaignDraftRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "promote_campaign_draft" not in self._stubs: + self._stubs["promote_campaign_draft"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignDraftService/PromoteCampaignDraft", + request_serializer=campaign_draft_service.PromoteCampaignDraftRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["promote_campaign_draft"] + + @property + def list_campaign_draft_async_errors( + self, + ) -> Callable[ + [campaign_draft_service.ListCampaignDraftAsyncErrorsRequest], + Awaitable[campaign_draft_service.ListCampaignDraftAsyncErrorsResponse], + ]: + r"""Return a callable for the list campaign draft async + errors method over gRPC. + + Returns all errors that occurred during CampaignDraft promote. + Throws an error if called before campaign draft is promoted. + Supports standard list paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListCampaignDraftAsyncErrorsRequest], + Awaitable[~.ListCampaignDraftAsyncErrorsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_campaign_draft_async_errors" not in self._stubs: + self._stubs["list_campaign_draft_async_errors"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignDraftService/ListCampaignDraftAsyncErrors", + request_serializer=campaign_draft_service.ListCampaignDraftAsyncErrorsRequest.serialize, + response_deserializer=campaign_draft_service.ListCampaignDraftAsyncErrorsResponse.deserialize, + ) + ) + return self._stubs["list_campaign_draft_async_errors"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_drafts: self._wrap_method( + self.mutate_campaign_drafts, + default_timeout=None, + client_info=client_info, + ), + self.promote_campaign_draft: self._wrap_method( + self.promote_campaign_draft, + default_timeout=None, + client_info=client_info, + ), + self.list_campaign_draft_async_errors: self._wrap_method( + self.list_campaign_draft_async_errors, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignDraftServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_goal_config_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_goal_config_service/__init__.py new file mode 100644 index 000000000..2fb24e867 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_goal_config_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import CampaignGoalConfigServiceClient +from .async_client import CampaignGoalConfigServiceAsyncClient + +__all__ = ( + "CampaignGoalConfigServiceClient", + "CampaignGoalConfigServiceAsyncClient", +) diff --git a/google/ads/googleads/v23/services/services/campaign_goal_config_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_goal_config_service/async_client.py new file mode 100644 index 000000000..065ac7058 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_goal_config_service/async_client.py @@ -0,0 +1,446 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import campaign_goal_config_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignGoalConfigServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CampaignGoalConfigServiceClient + +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 CampaignGoalConfigServiceAsyncClient: + """Service to manage campaign goal configs.""" + + _client: CampaignGoalConfigServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignGoalConfigServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CampaignGoalConfigServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignGoalConfigServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignGoalConfigServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod(CampaignGoalConfigServiceClient.campaign_path) + parse_campaign_path = staticmethod( + CampaignGoalConfigServiceClient.parse_campaign_path + ) + campaign_goal_config_path = staticmethod( + CampaignGoalConfigServiceClient.campaign_goal_config_path + ) + parse_campaign_goal_config_path = staticmethod( + CampaignGoalConfigServiceClient.parse_campaign_goal_config_path + ) + goal_path = staticmethod(CampaignGoalConfigServiceClient.goal_path) + parse_goal_path = staticmethod( + CampaignGoalConfigServiceClient.parse_goal_path + ) + common_billing_account_path = staticmethod( + CampaignGoalConfigServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignGoalConfigServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignGoalConfigServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignGoalConfigServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignGoalConfigServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignGoalConfigServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignGoalConfigServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignGoalConfigServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignGoalConfigServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignGoalConfigServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignGoalConfigServiceAsyncClient: The constructed client. + """ + return CampaignGoalConfigServiceClient.from_service_account_info.__func__(CampaignGoalConfigServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignGoalConfigServiceAsyncClient: The constructed client. + """ + return CampaignGoalConfigServiceClient.from_service_account_file.__func__(CampaignGoalConfigServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignGoalConfigServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignGoalConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignGoalConfigServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignGoalConfigServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignGoalConfigServiceTransport, + Callable[..., CampaignGoalConfigServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign goal config service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignGoalConfigServiceTransport,Callable[..., CampaignGoalConfigServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignGoalConfigServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignGoalConfigServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignGoalConfigServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignGoalConfigService", + "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.ads.googleads.v23.services.CampaignGoalConfigService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_goal_configs( + self, + request: Optional[ + Union[ + campaign_goal_config_service.MutateCampaignGoalConfigsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_goal_config_service.CampaignGoalConfigOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_goal_config_service.MutateCampaignGoalConfigsResponse: + r"""Create or update campaign goal configs. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `CampaignGoalConfigError <>`__ `GoalServicesError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignGoalConfigsRequest, dict]]): + The request object. Request message for + [CampaignGoalConfigService.MutateCampaignGoalConfigs][google.ads.googleads.v23.services.CampaignGoalConfigService.MutateCampaignGoalConfigs]. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaign goal configs are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignGoalConfigOperation]`): + Required. The list of operations to + perform on the campaign goal configs. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignGoalConfigsResponse: + Response message for a campaign goal + config mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + campaign_goal_config_service.MutateCampaignGoalConfigsRequest, + ): + request = ( + campaign_goal_config_service.MutateCampaignGoalConfigsRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_goal_configs + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignGoalConfigServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignGoalConfigServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_goal_config_service/client.py b/google/ads/googleads/v23/services/services/campaign_goal_config_service/client.py new file mode 100644 index 000000000..8e6247d4c --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_goal_config_service/client.py @@ -0,0 +1,960 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import campaign_goal_config_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignGoalConfigServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignGoalConfigServiceGrpcTransport +from .transports.grpc_asyncio import ( + CampaignGoalConfigServiceGrpcAsyncIOTransport, +) + + +class CampaignGoalConfigServiceClientMeta(type): + """Metaclass for the CampaignGoalConfigService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignGoalConfigServiceTransport]] + _transport_registry["grpc"] = CampaignGoalConfigServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignGoalConfigServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignGoalConfigServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignGoalConfigServiceClient( + metaclass=CampaignGoalConfigServiceClientMeta +): + """Service to manage campaign goal configs.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignGoalConfigServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignGoalConfigServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignGoalConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignGoalConfigServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_goal_config_path( + customer_id: str, + campaign_id: str, + unified_goal_id: str, + ) -> str: + """Returns a fully-qualified campaign_goal_config string.""" + return "customers/{customer_id}/campaignGoalConfigs/{campaign_id}~{unified_goal_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + unified_goal_id=unified_goal_id, + ) + + @staticmethod + def parse_campaign_goal_config_path(path: str) -> Dict[str, str]: + """Parses a campaign_goal_config path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignGoalConfigs/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def goal_path( + customer_id: str, + unified_goal_id: str, + ) -> str: + """Returns a fully-qualified goal string.""" + return "customers/{customer_id}/goals/{unified_goal_id}".format( + customer_id=customer_id, + unified_goal_id=unified_goal_id, + ) + + @staticmethod + def parse_goal_path(path: str) -> Dict[str, str]: + """Parses a goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/goals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignGoalConfigServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignGoalConfigServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CampaignGoalConfigServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CampaignGoalConfigServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = CampaignGoalConfigServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignGoalConfigServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignGoalConfigServiceTransport, + Callable[..., CampaignGoalConfigServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign goal config service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignGoalConfigServiceTransport,Callable[..., CampaignGoalConfigServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignGoalConfigServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignGoalConfigServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignGoalConfigServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CampaignGoalConfigServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignGoalConfigServiceTransport + ) + if transport_provided: + # transport is a CampaignGoalConfigServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CampaignGoalConfigServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignGoalConfigServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignGoalConfigServiceTransport], + Callable[..., CampaignGoalConfigServiceTransport], + ] = ( + CampaignGoalConfigServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignGoalConfigServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignGoalConfigServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignGoalConfigService", + "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.ads.googleads.v23.services.CampaignGoalConfigService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_goal_configs( + self, + request: Optional[ + Union[ + campaign_goal_config_service.MutateCampaignGoalConfigsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_goal_config_service.CampaignGoalConfigOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_goal_config_service.MutateCampaignGoalConfigsResponse: + r"""Create or update campaign goal configs. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `CampaignGoalConfigError <>`__ `GoalServicesError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignGoalConfigsRequest, dict]): + The request object. Request message for + [CampaignGoalConfigService.MutateCampaignGoalConfigs][google.ads.googleads.v23.services.CampaignGoalConfigService.MutateCampaignGoalConfigs]. + customer_id (str): + Required. The ID of the customer + whose campaign goal configs are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignGoalConfigOperation]): + Required. The list of operations to + perform on the campaign goal configs. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignGoalConfigsResponse: + Response message for a campaign goal + config mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + campaign_goal_config_service.MutateCampaignGoalConfigsRequest, + ): + request = ( + campaign_goal_config_service.MutateCampaignGoalConfigsRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_goal_configs + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignGoalConfigServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignGoalConfigServiceClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/README.rst new file mode 100644 index 000000000..d1a9b602b --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`CampaignGoalConfigServiceTransport` is the ABC for all transports. +- public child `CampaignGoalConfigServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `CampaignGoalConfigServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseCampaignGoalConfigServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `CampaignGoalConfigServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/__init__.py new file mode 100644 index 000000000..d09fdd235 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict + +from .base import CampaignGoalConfigServiceTransport +from .grpc import CampaignGoalConfigServiceGrpcTransport +from .grpc_asyncio import CampaignGoalConfigServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[CampaignGoalConfigServiceTransport]] +_transport_registry["grpc"] = CampaignGoalConfigServiceGrpcTransport +_transport_registry["grpc_asyncio"] = ( + CampaignGoalConfigServiceGrpcAsyncIOTransport +) + +__all__ = ( + "CampaignGoalConfigServiceTransport", + "CampaignGoalConfigServiceGrpcTransport", + "CampaignGoalConfigServiceGrpcAsyncIOTransport", +) diff --git a/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/base.py new file mode 100644 index 000000000..f89d75ab5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import campaign_goal_config_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignGoalConfigServiceTransport(abc.ABC): + """Abstract transport class for CampaignGoalConfigService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_goal_configs: gapic_v1.method.wrap_method( + self.mutate_campaign_goal_configs, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_goal_configs( + self, + ) -> Callable[ + [campaign_goal_config_service.MutateCampaignGoalConfigsRequest], + Union[ + campaign_goal_config_service.MutateCampaignGoalConfigsResponse, + Awaitable[ + campaign_goal_config_service.MutateCampaignGoalConfigsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignGoalConfigServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/grpc.py new file mode 100644 index 000000000..8e5ee220c --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/grpc.py @@ -0,0 +1,390 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import campaign_goal_config_service +from .base import CampaignGoalConfigServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignGoalConfigService", + "rpcName": str(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.ads.googleads.v23.services.CampaignGoalConfigService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignGoalConfigServiceGrpcTransport( + CampaignGoalConfigServiceTransport +): + """gRPC backend transport for CampaignGoalConfigService. + + Service to manage campaign goal configs. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaign_goal_configs( + self, + ) -> Callable[ + [campaign_goal_config_service.MutateCampaignGoalConfigsRequest], + campaign_goal_config_service.MutateCampaignGoalConfigsResponse, + ]: + r"""Return a callable for the mutate campaign goal configs method over gRPC. + + Create or update campaign goal configs. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `CampaignGoalConfigError <>`__ `GoalServicesError <>`__ + + Returns: + Callable[[~.MutateCampaignGoalConfigsRequest], + ~.MutateCampaignGoalConfigsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_goal_configs" not in self._stubs: + self._stubs["mutate_campaign_goal_configs"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignGoalConfigService/MutateCampaignGoalConfigs", + request_serializer=campaign_goal_config_service.MutateCampaignGoalConfigsRequest.serialize, + response_deserializer=campaign_goal_config_service.MutateCampaignGoalConfigsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_goal_configs"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignGoalConfigServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..44f19ba91 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_goal_config_service/transports/grpc_asyncio.py @@ -0,0 +1,413 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import campaign_goal_config_service +from .base import CampaignGoalConfigServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignGoalConfigService", + "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.ads.googleads.v23.services.CampaignGoalConfigService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignGoalConfigServiceGrpcAsyncIOTransport( + CampaignGoalConfigServiceTransport +): + """gRPC AsyncIO backend transport for CampaignGoalConfigService. + + Service to manage campaign goal configs. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaign_goal_configs( + self, + ) -> Callable[ + [campaign_goal_config_service.MutateCampaignGoalConfigsRequest], + Awaitable[ + campaign_goal_config_service.MutateCampaignGoalConfigsResponse + ], + ]: + r"""Return a callable for the mutate campaign goal configs method over gRPC. + + Create or update campaign goal configs. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `CampaignGoalConfigError <>`__ `GoalServicesError <>`__ + + Returns: + Callable[[~.MutateCampaignGoalConfigsRequest], + Awaitable[~.MutateCampaignGoalConfigsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_goal_configs" not in self._stubs: + self._stubs["mutate_campaign_goal_configs"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignGoalConfigService/MutateCampaignGoalConfigs", + request_serializer=campaign_goal_config_service.MutateCampaignGoalConfigsRequest.serialize, + response_deserializer=campaign_goal_config_service.MutateCampaignGoalConfigsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_goal_configs"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_goal_configs: self._wrap_method( + self.mutate_campaign_goal_configs, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignGoalConfigServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_group_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_group_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_group_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_group_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_group_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_group_service/async_client.py new file mode 100644 index 000000000..ecd7d033c --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_group_service/async_client.py @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import campaign_group_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignGroupServiceTransport, DEFAULT_CLIENT_INFO +from .client import CampaignGroupServiceClient + +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 CampaignGroupServiceAsyncClient: + """Service to manage campaign groups.""" + + _client: CampaignGroupServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignGroupServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CampaignGroupServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignGroupServiceClient._DEFAULT_UNIVERSE + + campaign_group_path = staticmethod( + CampaignGroupServiceClient.campaign_group_path + ) + parse_campaign_group_path = staticmethod( + CampaignGroupServiceClient.parse_campaign_group_path + ) + common_billing_account_path = staticmethod( + CampaignGroupServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignGroupServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignGroupServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignGroupServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignGroupServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignGroupServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignGroupServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignGroupServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignGroupServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignGroupServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignGroupServiceAsyncClient: The constructed client. + """ + return CampaignGroupServiceClient.from_service_account_info.__func__(CampaignGroupServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignGroupServiceAsyncClient: The constructed client. + """ + return CampaignGroupServiceClient.from_service_account_file.__func__(CampaignGroupServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignGroupServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignGroupServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignGroupServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignGroupServiceTransport, + Callable[..., CampaignGroupServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign group service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignGroupServiceTransport,Callable[..., CampaignGroupServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignGroupServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignGroupServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignGroupServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignGroupService", + "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.ads.googleads.v23.services.CampaignGroupService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_groups( + self, + request: Optional[ + Union[campaign_group_service.MutateCampaignGroupsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_group_service.CampaignGroupOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_group_service.MutateCampaignGroupsResponse: + r"""Creates, updates, or removes campaign groups. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignGroupsRequest, dict]]): + The request object. Request message for + [CampaignGroupService.MutateCampaignGroups][google.ads.googleads.v23.services.CampaignGroupService.MutateCampaignGroups]. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaign groups are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignGroupOperation]`): + Required. The list of operations to + perform on individual campaign groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignGroupsResponse: + Response message for campaign group + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_group_service.MutateCampaignGroupsRequest + ): + request = campaign_group_service.MutateCampaignGroupsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_groups + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignGroupServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignGroupServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_group_service/client.py b/google/ads/googleads/v23/services/services/campaign_group_service/client.py new file mode 100644 index 000000000..6a25b7055 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_group_service/client.py @@ -0,0 +1,897 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import campaign_group_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignGroupServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignGroupServiceGrpcTransport +from .transports.grpc_asyncio import CampaignGroupServiceGrpcAsyncIOTransport + + +class CampaignGroupServiceClientMeta(type): + """Metaclass for the CampaignGroupService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignGroupServiceTransport]] + _transport_registry["grpc"] = CampaignGroupServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignGroupServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignGroupServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignGroupServiceClient(metaclass=CampaignGroupServiceClientMeta): + """Service to manage campaign groups.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignGroupServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_group_path( + customer_id: str, + campaign_group_id: str, + ) -> str: + """Returns a fully-qualified campaign_group string.""" + return ( + "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( + customer_id=customer_id, + campaign_group_id=campaign_group_id, + ) + ) + + @staticmethod + def parse_campaign_group_path(path: str) -> Dict[str, str]: + """Parses a campaign_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignGroupServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignGroupServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CampaignGroupServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CampaignGroupServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CampaignGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignGroupServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignGroupServiceTransport, + Callable[..., CampaignGroupServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign group service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignGroupServiceTransport,Callable[..., CampaignGroupServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignGroupServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignGroupServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignGroupServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = CampaignGroupServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignGroupServiceTransport + ) + if transport_provided: + # transport is a CampaignGroupServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CampaignGroupServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignGroupServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignGroupServiceTransport], + Callable[..., CampaignGroupServiceTransport], + ] = ( + CampaignGroupServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignGroupServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignGroupServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignGroupService", + "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.ads.googleads.v23.services.CampaignGroupService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_groups( + self, + request: Optional[ + Union[campaign_group_service.MutateCampaignGroupsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_group_service.CampaignGroupOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_group_service.MutateCampaignGroupsResponse: + r"""Creates, updates, or removes campaign groups. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignGroupsRequest, dict]): + The request object. Request message for + [CampaignGroupService.MutateCampaignGroups][google.ads.googleads.v23.services.CampaignGroupService.MutateCampaignGroups]. + customer_id (str): + Required. The ID of the customer + whose campaign groups are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignGroupOperation]): + Required. The list of operations to + perform on individual campaign groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignGroupsResponse: + Response message for campaign group + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_group_service.MutateCampaignGroupsRequest + ): + request = campaign_group_service.MutateCampaignGroupsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_groups + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignGroupServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignGroupServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_group_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_group_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_group_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_group_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_group_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_group_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_group_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_group_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_group_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_group_service/transports/base.py new file mode 100644 index 000000000..395569e95 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_group_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import campaign_group_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignGroupServiceTransport(abc.ABC): + """Abstract transport class for CampaignGroupService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_groups: gapic_v1.method.wrap_method( + self.mutate_campaign_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_groups( + self, + ) -> Callable[ + [campaign_group_service.MutateCampaignGroupsRequest], + Union[ + campaign_group_service.MutateCampaignGroupsResponse, + Awaitable[campaign_group_service.MutateCampaignGroupsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignGroupServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_group_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_group_service/transports/grpc.py new file mode 100644 index 000000000..3f3aee085 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_group_service/transports/grpc.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import campaign_group_service +from .base import CampaignGroupServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignGroupService", + "rpcName": str(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.ads.googleads.v23.services.CampaignGroupService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignGroupServiceGrpcTransport(CampaignGroupServiceTransport): + """gRPC backend transport for CampaignGroupService. + + Service to manage campaign groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaign_groups( + self, + ) -> Callable[ + [campaign_group_service.MutateCampaignGroupsRequest], + campaign_group_service.MutateCampaignGroupsResponse, + ]: + r"""Return a callable for the mutate campaign groups method over gRPC. + + Creates, updates, or removes campaign groups. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignGroupsRequest], + ~.MutateCampaignGroupsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_groups" not in self._stubs: + self._stubs["mutate_campaign_groups"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignGroupService/MutateCampaignGroups", + request_serializer=campaign_group_service.MutateCampaignGroupsRequest.serialize, + response_deserializer=campaign_group_service.MutateCampaignGroupsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_groups"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_group_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_group_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..be6a24946 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_group_service/transports/grpc_asyncio.py @@ -0,0 +1,405 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import campaign_group_service +from .base import CampaignGroupServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignGroupService", + "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.ads.googleads.v23.services.CampaignGroupService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignGroupServiceGrpcAsyncIOTransport(CampaignGroupServiceTransport): + """gRPC AsyncIO backend transport for CampaignGroupService. + + Service to manage campaign groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaign_groups( + self, + ) -> Callable[ + [campaign_group_service.MutateCampaignGroupsRequest], + Awaitable[campaign_group_service.MutateCampaignGroupsResponse], + ]: + r"""Return a callable for the mutate campaign groups method over gRPC. + + Creates, updates, or removes campaign groups. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCampaignGroupsRequest], + Awaitable[~.MutateCampaignGroupsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_groups" not in self._stubs: + self._stubs["mutate_campaign_groups"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignGroupService/MutateCampaignGroups", + request_serializer=campaign_group_service.MutateCampaignGroupsRequest.serialize, + response_deserializer=campaign_group_service.MutateCampaignGroupsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_groups"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_groups: self._wrap_method( + self.mutate_campaign_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignGroupServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_label_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_label_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_label_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_label_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_label_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_label_service/async_client.py new file mode 100644 index 000000000..dcbd8b049 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_label_service/async_client.py @@ -0,0 +1,433 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import campaign_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignLabelServiceTransport, DEFAULT_CLIENT_INFO +from .client import CampaignLabelServiceClient + +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 CampaignLabelServiceAsyncClient: + """Service to manage labels on campaigns.""" + + _client: CampaignLabelServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignLabelServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CampaignLabelServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignLabelServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod(CampaignLabelServiceClient.campaign_path) + parse_campaign_path = staticmethod( + CampaignLabelServiceClient.parse_campaign_path + ) + campaign_label_path = staticmethod( + CampaignLabelServiceClient.campaign_label_path + ) + parse_campaign_label_path = staticmethod( + CampaignLabelServiceClient.parse_campaign_label_path + ) + label_path = staticmethod(CampaignLabelServiceClient.label_path) + parse_label_path = staticmethod(CampaignLabelServiceClient.parse_label_path) + common_billing_account_path = staticmethod( + CampaignLabelServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignLabelServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignLabelServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignLabelServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignLabelServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignLabelServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignLabelServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignLabelServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignLabelServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignLabelServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignLabelServiceAsyncClient: The constructed client. + """ + return CampaignLabelServiceClient.from_service_account_info.__func__(CampaignLabelServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignLabelServiceAsyncClient: The constructed client. + """ + return CampaignLabelServiceClient.from_service_account_file.__func__(CampaignLabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignLabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignLabelServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignLabelServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignLabelServiceTransport, + Callable[..., CampaignLabelServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign label service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignLabelServiceTransport,Callable[..., CampaignLabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignLabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignLabelServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignLabelServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignLabelService", + "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.ads.googleads.v23.services.CampaignLabelService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_labels( + self, + request: Optional[ + Union[campaign_label_service.MutateCampaignLabelsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_label_service.CampaignLabelOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_label_service.MutateCampaignLabelsResponse: + r"""Creates and removes campaign-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignLabelsRequest, dict]]): + The request object. Request message for + [CampaignLabelService.MutateCampaignLabels][google.ads.googleads.v23.services.CampaignLabelService.MutateCampaignLabels]. + customer_id (:class:`str`): + Required. ID of the customer whose + campaign-label relationships are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignLabelOperation]`): + Required. The list of operations to + perform on campaign-label relationships. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignLabelsResponse: + Response message for a campaign + labels mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_label_service.MutateCampaignLabelsRequest + ): + request = campaign_label_service.MutateCampaignLabelsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignLabelServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignLabelServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_label_service/client.py b/google/ads/googleads/v23/services/services/campaign_label_service/client.py new file mode 100644 index 000000000..38eb950d0 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_label_service/client.py @@ -0,0 +1,942 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import campaign_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignLabelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignLabelServiceGrpcTransport +from .transports.grpc_asyncio import CampaignLabelServiceGrpcAsyncIOTransport + + +class CampaignLabelServiceClientMeta(type): + """Metaclass for the CampaignLabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignLabelServiceTransport]] + _transport_registry["grpc"] = CampaignLabelServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignLabelServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignLabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignLabelServiceClient(metaclass=CampaignLabelServiceClientMeta): + """Service to manage labels on campaigns.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignLabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_label_path( + customer_id: str, + campaign_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified campaign_label string.""" + return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + label_id=label_id, + ) + + @staticmethod + def parse_campaign_label_path(path: str) -> Dict[str, str]: + """Parses a campaign_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path( + customer_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, + label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignLabelServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignLabelServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CampaignLabelServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CampaignLabelServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CampaignLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignLabelServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignLabelServiceTransport, + Callable[..., CampaignLabelServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignLabelServiceTransport,Callable[..., CampaignLabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignLabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignLabelServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignLabelServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = CampaignLabelServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignLabelServiceTransport + ) + if transport_provided: + # transport is a CampaignLabelServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CampaignLabelServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignLabelServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignLabelServiceTransport], + Callable[..., CampaignLabelServiceTransport], + ] = ( + CampaignLabelServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignLabelServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignLabelServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignLabelService", + "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.ads.googleads.v23.services.CampaignLabelService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_labels( + self, + request: Optional[ + Union[campaign_label_service.MutateCampaignLabelsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_label_service.CampaignLabelOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_label_service.MutateCampaignLabelsResponse: + r"""Creates and removes campaign-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignLabelsRequest, dict]): + The request object. Request message for + [CampaignLabelService.MutateCampaignLabels][google.ads.googleads.v23.services.CampaignLabelService.MutateCampaignLabels]. + customer_id (str): + Required. ID of the customer whose + campaign-label relationships are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignLabelOperation]): + Required. The list of operations to + perform on campaign-label relationships. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignLabelsResponse: + Response message for a campaign + labels mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_label_service.MutateCampaignLabelsRequest + ): + request = campaign_label_service.MutateCampaignLabelsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignLabelServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignLabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_label_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_label_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_label_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_label_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_label_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_label_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_label_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_label_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_label_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_label_service/transports/base.py new file mode 100644 index 000000000..d1021b8ca --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_label_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import campaign_label_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignLabelServiceTransport(abc.ABC): + """Abstract transport class for CampaignLabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_labels: gapic_v1.method.wrap_method( + self.mutate_campaign_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_labels( + self, + ) -> Callable[ + [campaign_label_service.MutateCampaignLabelsRequest], + Union[ + campaign_label_service.MutateCampaignLabelsResponse, + Awaitable[campaign_label_service.MutateCampaignLabelsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignLabelServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_label_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_label_service/transports/grpc.py new file mode 100644 index 000000000..216008e9f --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_label_service/transports/grpc.py @@ -0,0 +1,390 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import campaign_label_service +from .base import CampaignLabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignLabelService", + "rpcName": str(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.ads.googleads.v23.services.CampaignLabelService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignLabelServiceGrpcTransport(CampaignLabelServiceTransport): + """gRPC backend transport for CampaignLabelService. + + Service to manage labels on campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaign_labels( + self, + ) -> Callable[ + [campaign_label_service.MutateCampaignLabelsRequest], + campaign_label_service.MutateCampaignLabelsResponse, + ]: + r"""Return a callable for the mutate campaign labels method over gRPC. + + Creates and removes campaign-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCampaignLabelsRequest], + ~.MutateCampaignLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_labels" not in self._stubs: + self._stubs["mutate_campaign_labels"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignLabelService/MutateCampaignLabels", + request_serializer=campaign_label_service.MutateCampaignLabelsRequest.serialize, + response_deserializer=campaign_label_service.MutateCampaignLabelsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_labels"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_label_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_label_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..bad86346c --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_label_service/transports/grpc_asyncio.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import campaign_label_service +from .base import CampaignLabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignLabelService", + "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.ads.googleads.v23.services.CampaignLabelService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignLabelServiceGrpcAsyncIOTransport(CampaignLabelServiceTransport): + """gRPC AsyncIO backend transport for CampaignLabelService. + + Service to manage labels on campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaign_labels( + self, + ) -> Callable[ + [campaign_label_service.MutateCampaignLabelsRequest], + Awaitable[campaign_label_service.MutateCampaignLabelsResponse], + ]: + r"""Return a callable for the mutate campaign labels method over gRPC. + + Creates and removes campaign-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCampaignLabelsRequest], + Awaitable[~.MutateCampaignLabelsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_labels" not in self._stubs: + self._stubs["mutate_campaign_labels"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignLabelService/MutateCampaignLabels", + request_serializer=campaign_label_service.MutateCampaignLabelsRequest.serialize, + response_deserializer=campaign_label_service.MutateCampaignLabelsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_labels"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_labels: self._wrap_method( + self.mutate_campaign_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignLabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/async_client.py new file mode 100644 index 000000000..901c9fb15 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/async_client.py @@ -0,0 +1,442 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + campaign_lifecycle_goal_service, +) +from .transports.base import ( + CampaignLifecycleGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CampaignLifecycleGoalServiceClient + +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 CampaignLifecycleGoalServiceAsyncClient: + """Service to configure campaign lifecycle goals.""" + + _client: CampaignLifecycleGoalServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignLifecycleGoalServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CampaignLifecycleGoalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignLifecycleGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignLifecycleGoalServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod( + CampaignLifecycleGoalServiceClient.campaign_path + ) + parse_campaign_path = staticmethod( + CampaignLifecycleGoalServiceClient.parse_campaign_path + ) + campaign_lifecycle_goal_path = staticmethod( + CampaignLifecycleGoalServiceClient.campaign_lifecycle_goal_path + ) + parse_campaign_lifecycle_goal_path = staticmethod( + CampaignLifecycleGoalServiceClient.parse_campaign_lifecycle_goal_path + ) + common_billing_account_path = staticmethod( + CampaignLifecycleGoalServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignLifecycleGoalServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignLifecycleGoalServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignLifecycleGoalServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignLifecycleGoalServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignLifecycleGoalServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignLifecycleGoalServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignLifecycleGoalServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignLifecycleGoalServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignLifecycleGoalServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignLifecycleGoalServiceAsyncClient: The constructed client. + """ + return CampaignLifecycleGoalServiceClient.from_service_account_info.__func__(CampaignLifecycleGoalServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignLifecycleGoalServiceAsyncClient: The constructed client. + """ + return CampaignLifecycleGoalServiceClient.from_service_account_file.__func__(CampaignLifecycleGoalServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignLifecycleGoalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignLifecycleGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignLifecycleGoalServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignLifecycleGoalServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignLifecycleGoalServiceTransport, + Callable[..., CampaignLifecycleGoalServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign lifecycle goal service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignLifecycleGoalServiceTransport,Callable[..., CampaignLifecycleGoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignLifecycleGoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignLifecycleGoalServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignLifecycleGoalServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignLifecycleGoalService", + "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.ads.googleads.v23.services.CampaignLifecycleGoalService", + "credentialsType": None, + } + ), + ) + + async def configure_campaign_lifecycle_goals( + self, + request: Optional[ + Union[ + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + campaign_lifecycle_goal_service.CampaignLifecycleGoalOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse + ): + r"""Process the given campaign lifecycle configurations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `CampaignLifecycleGoalConfigError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ConfigureCampaignLifecycleGoalsRequest, dict]]): + The request object. Request message for + [CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals][google.ads.googleads.v23.services.CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals]. + customer_id (:class:`str`): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (:class:`google.ads.googleads.v23.services.types.CampaignLifecycleGoalOperation`): + Required. The operation to perform + campaign lifecycle goal update. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ConfigureCampaignLifecycleGoalsResponse: + Response message for + [CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals][google.ads.googleads.v23.services.CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest, + ): + request = campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.configure_campaign_lifecycle_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignLifecycleGoalServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignLifecycleGoalServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/client.py b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/client.py new file mode 100644 index 000000000..4f2253815 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/client.py @@ -0,0 +1,931 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + campaign_lifecycle_goal_service, +) +from .transports.base import ( + CampaignLifecycleGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignLifecycleGoalServiceGrpcTransport +from .transports.grpc_asyncio import ( + CampaignLifecycleGoalServiceGrpcAsyncIOTransport, +) + + +class CampaignLifecycleGoalServiceClientMeta(type): + """Metaclass for the CampaignLifecycleGoalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignLifecycleGoalServiceTransport]] + _transport_registry["grpc"] = CampaignLifecycleGoalServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignLifecycleGoalServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignLifecycleGoalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignLifecycleGoalServiceClient( + metaclass=CampaignLifecycleGoalServiceClientMeta +): + """Service to configure campaign lifecycle goals.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignLifecycleGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignLifecycleGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignLifecycleGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignLifecycleGoalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_lifecycle_goal_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign_lifecycle_goal string.""" + return "customers/{customer_id}/campaignLifecycleGoals/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_lifecycle_goal_path(path: str) -> Dict[str, str]: + """Parses a campaign_lifecycle_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignLifecycleGoals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignLifecycleGoalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignLifecycleGoalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CampaignLifecycleGoalServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + CampaignLifecycleGoalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = CampaignLifecycleGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignLifecycleGoalServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignLifecycleGoalServiceTransport, + Callable[..., CampaignLifecycleGoalServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign lifecycle goal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignLifecycleGoalServiceTransport,Callable[..., CampaignLifecycleGoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignLifecycleGoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignLifecycleGoalServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignLifecycleGoalServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CampaignLifecycleGoalServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignLifecycleGoalServiceTransport + ) + if transport_provided: + # transport is a CampaignLifecycleGoalServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CampaignLifecycleGoalServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignLifecycleGoalServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignLifecycleGoalServiceTransport], + Callable[..., CampaignLifecycleGoalServiceTransport], + ] = ( + CampaignLifecycleGoalServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignLifecycleGoalServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignLifecycleGoalServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignLifecycleGoalService", + "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.ads.googleads.v23.services.CampaignLifecycleGoalService", + "credentialsType": None, + } + ), + ) + + def configure_campaign_lifecycle_goals( + self, + request: Optional[ + Union[ + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + campaign_lifecycle_goal_service.CampaignLifecycleGoalOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse + ): + r"""Process the given campaign lifecycle configurations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `CampaignLifecycleGoalConfigError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ConfigureCampaignLifecycleGoalsRequest, dict]): + The request object. Request message for + [CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals][google.ads.googleads.v23.services.CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals]. + customer_id (str): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v23.services.types.CampaignLifecycleGoalOperation): + Required. The operation to perform + campaign lifecycle goal update. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ConfigureCampaignLifecycleGoalsResponse: + Response message for + [CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals][google.ads.googleads.v23.services.CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest, + ): + request = campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.configure_campaign_lifecycle_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignLifecycleGoalServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignLifecycleGoalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_lifecycle_goal_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/base.py new file mode 100644 index 000000000..acf0a1cdf --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + campaign_lifecycle_goal_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignLifecycleGoalServiceTransport(abc.ABC): + """Abstract transport class for CampaignLifecycleGoalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.configure_campaign_lifecycle_goals: gapic_v1.method.wrap_method( + self.configure_campaign_lifecycle_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def configure_campaign_lifecycle_goals( + self, + ) -> Callable[ + [ + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest + ], + Union[ + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse, + Awaitable[ + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignLifecycleGoalServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/grpc.py new file mode 100644 index 000000000..db47e589d --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/grpc.py @@ -0,0 +1,395 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + campaign_lifecycle_goal_service, +) +from .base import CampaignLifecycleGoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignLifecycleGoalService", + "rpcName": str(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.ads.googleads.v23.services.CampaignLifecycleGoalService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignLifecycleGoalServiceGrpcTransport( + CampaignLifecycleGoalServiceTransport +): + """gRPC backend transport for CampaignLifecycleGoalService. + + Service to configure campaign lifecycle goals. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def configure_campaign_lifecycle_goals( + self, + ) -> Callable[ + [ + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest + ], + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse, + ]: + r"""Return a callable for the configure campaign lifecycle + goals method over gRPC. + + Process the given campaign lifecycle configurations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `CampaignLifecycleGoalConfigError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ConfigureCampaignLifecycleGoalsRequest], + ~.ConfigureCampaignLifecycleGoalsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "configure_campaign_lifecycle_goals" not in self._stubs: + self._stubs["configure_campaign_lifecycle_goals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignLifecycleGoalService/ConfigureCampaignLifecycleGoals", + request_serializer=campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest.serialize, + response_deserializer=campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse.deserialize, + ) + ) + return self._stubs["configure_campaign_lifecycle_goals"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignLifecycleGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..1a2eb8d16 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_lifecycle_goal_service/transports/grpc_asyncio.py @@ -0,0 +1,418 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + campaign_lifecycle_goal_service, +) +from .base import CampaignLifecycleGoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignLifecycleGoalService", + "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.ads.googleads.v23.services.CampaignLifecycleGoalService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignLifecycleGoalServiceGrpcAsyncIOTransport( + CampaignLifecycleGoalServiceTransport +): + """gRPC AsyncIO backend transport for CampaignLifecycleGoalService. + + Service to configure campaign lifecycle goals. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def configure_campaign_lifecycle_goals( + self, + ) -> Callable[ + [ + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest + ], + Awaitable[ + campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse + ], + ]: + r"""Return a callable for the configure campaign lifecycle + goals method over gRPC. + + Process the given campaign lifecycle configurations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `CampaignLifecycleGoalConfigError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ConfigureCampaignLifecycleGoalsRequest], + Awaitable[~.ConfigureCampaignLifecycleGoalsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "configure_campaign_lifecycle_goals" not in self._stubs: + self._stubs["configure_campaign_lifecycle_goals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignLifecycleGoalService/ConfigureCampaignLifecycleGoals", + request_serializer=campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsRequest.serialize, + response_deserializer=campaign_lifecycle_goal_service.ConfigureCampaignLifecycleGoalsResponse.deserialize, + ) + ) + return self._stubs["configure_campaign_lifecycle_goals"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.configure_campaign_lifecycle_goals: self._wrap_method( + self.configure_campaign_lifecycle_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignLifecycleGoalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_service/async_client.py new file mode 100644 index 000000000..0a421d918 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_service/async_client.py @@ -0,0 +1,579 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import campaign_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignServiceTransport, DEFAULT_CLIENT_INFO +from .client import CampaignServiceClient + +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 CampaignServiceAsyncClient: + """Service to manage campaigns.""" + + _client: CampaignServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CampaignServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignServiceClient._DEFAULT_UNIVERSE + + accessible_bidding_strategy_path = staticmethod( + CampaignServiceClient.accessible_bidding_strategy_path + ) + parse_accessible_bidding_strategy_path = staticmethod( + CampaignServiceClient.parse_accessible_bidding_strategy_path + ) + asset_set_path = staticmethod(CampaignServiceClient.asset_set_path) + parse_asset_set_path = staticmethod( + CampaignServiceClient.parse_asset_set_path + ) + bidding_strategy_path = staticmethod( + CampaignServiceClient.bidding_strategy_path + ) + parse_bidding_strategy_path = staticmethod( + CampaignServiceClient.parse_bidding_strategy_path + ) + campaign_path = staticmethod(CampaignServiceClient.campaign_path) + parse_campaign_path = staticmethod( + CampaignServiceClient.parse_campaign_path + ) + campaign_budget_path = staticmethod( + CampaignServiceClient.campaign_budget_path + ) + parse_campaign_budget_path = staticmethod( + CampaignServiceClient.parse_campaign_budget_path + ) + campaign_group_path = staticmethod( + CampaignServiceClient.campaign_group_path + ) + parse_campaign_group_path = staticmethod( + CampaignServiceClient.parse_campaign_group_path + ) + campaign_label_path = staticmethod( + CampaignServiceClient.campaign_label_path + ) + parse_campaign_label_path = staticmethod( + CampaignServiceClient.parse_campaign_label_path + ) + conversion_action_path = staticmethod( + CampaignServiceClient.conversion_action_path + ) + parse_conversion_action_path = staticmethod( + CampaignServiceClient.parse_conversion_action_path + ) + common_billing_account_path = staticmethod( + CampaignServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(CampaignServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + CampaignServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignServiceAsyncClient: The constructed client. + """ + return CampaignServiceClient.from_service_account_info.__func__(CampaignServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignServiceAsyncClient: The constructed client. + """ + return CampaignServiceClient.from_service_account_file.__func__(CampaignServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignServiceTransport, + Callable[..., CampaignServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignServiceTransport,Callable[..., CampaignServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignService", + "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.ads.googleads.v23.services.CampaignService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaigns( + self, + request: Optional[ + Union[campaign_service.MutateCampaignsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_service.CampaignOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_service.MutateCampaignsResponse: + r"""Creates, updates, or removes campaigns. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `CampaignBudgetError <>`__ `CampaignError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DateRangeError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RegionCodeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignsRequest, dict]]): + The request object. Request message for + [CampaignService.MutateCampaigns][google.ads.googleads.v23.services.CampaignService.MutateCampaigns]. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaigns are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignOperation]`): + Required. The list of operations to + perform on individual campaigns. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignsResponse: + Response message for campaign mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, campaign_service.MutateCampaignsRequest): + request = campaign_service.MutateCampaignsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaigns + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def enable_p_max_brand_guidelines( + self, + request: Optional[ + Union[campaign_service.EnablePMaxBrandGuidelinesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_service.EnableOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_service.EnablePMaxBrandGuidelinesResponse: + r"""Enables Brand Guidelines for Performance Max campaigns. + + List of thrown errors: `AuthenticationError <>`__ + `AssetError <>`__ `AssetLinkError <>`__ + `AuthorizationError <>`__ `BrandGuidelinesMigrationError <>`__ + `CampaignError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.EnablePMaxBrandGuidelinesRequest, dict]]): + The request object. Request to enable Brand Guidelines + for a Performance Max campaign. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaigns are being enabled. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.EnableOperation]`): + Required. The list of individual + campaign operations. A maximum of 10 + enable operations can be executed in a + request. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.EnablePMaxBrandGuidelinesResponse: + Brand Guidelines campaign enablement + response. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_service.EnablePMaxBrandGuidelinesRequest + ): + request = campaign_service.EnablePMaxBrandGuidelinesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.enable_p_max_brand_guidelines + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_service/client.py b/google/ads/googleads/v23/services/services/campaign_service/client.py new file mode 100644 index 000000000..ea93ec18a --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_service/client.py @@ -0,0 +1,1148 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import campaign_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CampaignServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CampaignServiceGrpcTransport +from .transports.grpc_asyncio import CampaignServiceGrpcAsyncIOTransport + + +class CampaignServiceClientMeta(type): + """Metaclass for the CampaignService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignServiceTransport]] + _transport_registry["grpc"] = CampaignServiceGrpcTransport + _transport_registry["grpc_asyncio"] = CampaignServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignServiceClient(metaclass=CampaignServiceClientMeta): + """Service to manage campaigns.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def accessible_bidding_strategy_path( + customer_id: str, + bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified accessible_bidding_strategy string.""" + return "customers/{customer_id}/accessibleBiddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, + bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_accessible_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a accessible_bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accessibleBiddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_path( + customer_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_strategy_path( + customer_id: str, + bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified bidding_strategy string.""" + return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, + bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_budget_path( + customer_id: str, + campaign_budget_id: str, + ) -> str: + """Returns a fully-qualified campaign_budget string.""" + return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( + customer_id=customer_id, + campaign_budget_id=campaign_budget_id, + ) + + @staticmethod + def parse_campaign_budget_path(path: str) -> Dict[str, str]: + """Parses a campaign_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_group_path( + customer_id: str, + campaign_group_id: str, + ) -> str: + """Returns a fully-qualified campaign_group string.""" + return ( + "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( + customer_id=customer_id, + campaign_group_id=campaign_group_id, + ) + ) + + @staticmethod + def parse_campaign_group_path(path: str) -> Dict[str, str]: + """Parses a campaign_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_label_path( + customer_id: str, + campaign_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified campaign_label string.""" + return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + label_id=label_id, + ) + + @staticmethod + def parse_campaign_label_path(path: str) -> Dict[str, str]: + """Parses a campaign_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_action_path( + customer_id: str, + conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, + conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = CampaignServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = CampaignServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CampaignServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CampaignServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CampaignServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignServiceTransport, + Callable[..., CampaignServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignServiceTransport,Callable[..., CampaignServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = CampaignServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, CampaignServiceTransport) + if transport_provided: + # transport is a CampaignServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CampaignServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignServiceTransport], + Callable[..., CampaignServiceTransport], + ] = ( + CampaignServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., CampaignServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignService", + "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.ads.googleads.v23.services.CampaignService", + "credentialsType": None, + } + ), + ) + + def mutate_campaigns( + self, + request: Optional[ + Union[campaign_service.MutateCampaignsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_service.CampaignOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_service.MutateCampaignsResponse: + r"""Creates, updates, or removes campaigns. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `CampaignBudgetError <>`__ `CampaignError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DateRangeError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RegionCodeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignsRequest, dict]): + The request object. Request message for + [CampaignService.MutateCampaigns][google.ads.googleads.v23.services.CampaignService.MutateCampaigns]. + customer_id (str): + Required. The ID of the customer + whose campaigns are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignOperation]): + Required. The list of operations to + perform on individual campaigns. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignsResponse: + Response message for campaign mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, campaign_service.MutateCampaignsRequest): + request = campaign_service.MutateCampaignsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_campaigns] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def enable_p_max_brand_guidelines( + self, + request: Optional[ + Union[campaign_service.EnablePMaxBrandGuidelinesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[campaign_service.EnableOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_service.EnablePMaxBrandGuidelinesResponse: + r"""Enables Brand Guidelines for Performance Max campaigns. + + List of thrown errors: `AuthenticationError <>`__ + `AssetError <>`__ `AssetLinkError <>`__ + `AuthorizationError <>`__ `BrandGuidelinesMigrationError <>`__ + `CampaignError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.EnablePMaxBrandGuidelinesRequest, dict]): + The request object. Request to enable Brand Guidelines + for a Performance Max campaign. + customer_id (str): + Required. The ID of the customer + whose campaigns are being enabled. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.EnableOperation]): + Required. The list of individual + campaign operations. A maximum of 10 + enable operations can be executed in a + request. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.EnablePMaxBrandGuidelinesResponse: + Brand Guidelines campaign enablement + response. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_service.EnablePMaxBrandGuidelinesRequest + ): + request = campaign_service.EnablePMaxBrandGuidelinesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.enable_p_max_brand_guidelines + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_service/transports/base.py new file mode 100644 index 000000000..9d0c42edc --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_service/transports/base.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import campaign_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignServiceTransport(abc.ABC): + """Abstract transport class for CampaignService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaigns: gapic_v1.method.wrap_method( + self.mutate_campaigns, + default_timeout=None, + client_info=client_info, + ), + self.enable_p_max_brand_guidelines: gapic_v1.method.wrap_method( + self.enable_p_max_brand_guidelines, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaigns( + self, + ) -> Callable[ + [campaign_service.MutateCampaignsRequest], + Union[ + campaign_service.MutateCampaignsResponse, + Awaitable[campaign_service.MutateCampaignsResponse], + ], + ]: + raise NotImplementedError() + + @property + def enable_p_max_brand_guidelines( + self, + ) -> Callable[ + [campaign_service.EnablePMaxBrandGuidelinesRequest], + Union[ + campaign_service.EnablePMaxBrandGuidelinesResponse, + Awaitable[campaign_service.EnablePMaxBrandGuidelinesResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_service/transports/grpc.py new file mode 100644 index 000000000..2485f596d --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_service/transports/grpc.py @@ -0,0 +1,437 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import campaign_service +from .base import CampaignServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignService", + "rpcName": str(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.ads.googleads.v23.services.CampaignService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignServiceGrpcTransport(CampaignServiceTransport): + """gRPC backend transport for CampaignService. + + Service to manage campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaigns( + self, + ) -> Callable[ + [campaign_service.MutateCampaignsRequest], + campaign_service.MutateCampaignsResponse, + ]: + r"""Return a callable for the mutate campaigns method over gRPC. + + Creates, updates, or removes campaigns. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `CampaignBudgetError <>`__ `CampaignError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DateRangeError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RegionCodeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateCampaignsRequest], + ~.MutateCampaignsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaigns" not in self._stubs: + self._stubs["mutate_campaigns"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignService/MutateCampaigns", + request_serializer=campaign_service.MutateCampaignsRequest.serialize, + response_deserializer=campaign_service.MutateCampaignsResponse.deserialize, + ) + return self._stubs["mutate_campaigns"] + + @property + def enable_p_max_brand_guidelines( + self, + ) -> Callable[ + [campaign_service.EnablePMaxBrandGuidelinesRequest], + campaign_service.EnablePMaxBrandGuidelinesResponse, + ]: + r"""Return a callable for the enable p max brand guidelines method over gRPC. + + Enables Brand Guidelines for Performance Max campaigns. + + List of thrown errors: `AuthenticationError <>`__ + `AssetError <>`__ `AssetLinkError <>`__ + `AuthorizationError <>`__ `BrandGuidelinesMigrationError <>`__ + `CampaignError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.EnablePMaxBrandGuidelinesRequest], + ~.EnablePMaxBrandGuidelinesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "enable_p_max_brand_guidelines" not in self._stubs: + self._stubs["enable_p_max_brand_guidelines"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignService/EnablePMaxBrandGuidelines", + request_serializer=campaign_service.EnablePMaxBrandGuidelinesRequest.serialize, + response_deserializer=campaign_service.EnablePMaxBrandGuidelinesResponse.deserialize, + ) + ) + return self._stubs["enable_p_max_brand_guidelines"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..45f7a1232 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_service/transports/grpc_asyncio.py @@ -0,0 +1,463 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import campaign_service +from .base import CampaignServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignService", + "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.ads.googleads.v23.services.CampaignService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignServiceGrpcAsyncIOTransport(CampaignServiceTransport): + """gRPC AsyncIO backend transport for CampaignService. + + Service to manage campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaigns( + self, + ) -> Callable[ + [campaign_service.MutateCampaignsRequest], + Awaitable[campaign_service.MutateCampaignsResponse], + ]: + r"""Return a callable for the mutate campaigns method over gRPC. + + Creates, updates, or removes campaigns. Operation statuses are + returned. + + List of thrown errors: `AdxError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `BiddingError <>`__ `BiddingStrategyError <>`__ + `CampaignBudgetError <>`__ `CampaignError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DateRangeError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `IdError <>`__ + `InternalError <>`__ `ListOperationError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RegionCodeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateCampaignsRequest], + Awaitable[~.MutateCampaignsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaigns" not in self._stubs: + self._stubs["mutate_campaigns"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignService/MutateCampaigns", + request_serializer=campaign_service.MutateCampaignsRequest.serialize, + response_deserializer=campaign_service.MutateCampaignsResponse.deserialize, + ) + return self._stubs["mutate_campaigns"] + + @property + def enable_p_max_brand_guidelines( + self, + ) -> Callable[ + [campaign_service.EnablePMaxBrandGuidelinesRequest], + Awaitable[campaign_service.EnablePMaxBrandGuidelinesResponse], + ]: + r"""Return a callable for the enable p max brand guidelines method over gRPC. + + Enables Brand Guidelines for Performance Max campaigns. + + List of thrown errors: `AuthenticationError <>`__ + `AssetError <>`__ `AssetLinkError <>`__ + `AuthorizationError <>`__ `BrandGuidelinesMigrationError <>`__ + `CampaignError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.EnablePMaxBrandGuidelinesRequest], + Awaitable[~.EnablePMaxBrandGuidelinesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "enable_p_max_brand_guidelines" not in self._stubs: + self._stubs["enable_p_max_brand_guidelines"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignService/EnablePMaxBrandGuidelines", + request_serializer=campaign_service.EnablePMaxBrandGuidelinesRequest.serialize, + response_deserializer=campaign_service.EnablePMaxBrandGuidelinesResponse.deserialize, + ) + ) + return self._stubs["enable_p_max_brand_guidelines"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaigns: self._wrap_method( + self.mutate_campaigns, + default_timeout=None, + client_info=client_info, + ), + self.enable_p_max_brand_guidelines: self._wrap_method( + self.enable_p_max_brand_guidelines, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/campaign_shared_set_service/__init__.py b/google/ads/googleads/v23/services/services/campaign_shared_set_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_shared_set_service/__init__.py rename to google/ads/googleads/v23/services/services/campaign_shared_set_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_shared_set_service/async_client.py b/google/ads/googleads/v23/services/services/campaign_shared_set_service/async_client.py new file mode 100644 index 000000000..702acbcfa --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_shared_set_service/async_client.py @@ -0,0 +1,452 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import campaign_shared_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignSharedSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CampaignSharedSetServiceClient + +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 CampaignSharedSetServiceAsyncClient: + """Service to manage campaign shared sets.""" + + _client: CampaignSharedSetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CampaignSharedSetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CampaignSharedSetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CampaignSharedSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CampaignSharedSetServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod(CampaignSharedSetServiceClient.campaign_path) + parse_campaign_path = staticmethod( + CampaignSharedSetServiceClient.parse_campaign_path + ) + campaign_shared_set_path = staticmethod( + CampaignSharedSetServiceClient.campaign_shared_set_path + ) + parse_campaign_shared_set_path = staticmethod( + CampaignSharedSetServiceClient.parse_campaign_shared_set_path + ) + shared_set_path = staticmethod( + CampaignSharedSetServiceClient.shared_set_path + ) + parse_shared_set_path = staticmethod( + CampaignSharedSetServiceClient.parse_shared_set_path + ) + common_billing_account_path = staticmethod( + CampaignSharedSetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CampaignSharedSetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CampaignSharedSetServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CampaignSharedSetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CampaignSharedSetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CampaignSharedSetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CampaignSharedSetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CampaignSharedSetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CampaignSharedSetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CampaignSharedSetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignSharedSetServiceAsyncClient: The constructed client. + """ + return CampaignSharedSetServiceClient.from_service_account_info.__func__(CampaignSharedSetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignSharedSetServiceAsyncClient: The constructed client. + """ + return CampaignSharedSetServiceClient.from_service_account_file.__func__(CampaignSharedSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CampaignSharedSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CampaignSharedSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignSharedSetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CampaignSharedSetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignSharedSetServiceTransport, + Callable[..., CampaignSharedSetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign shared set service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignSharedSetServiceTransport,Callable[..., CampaignSharedSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignSharedSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CampaignSharedSetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CampaignSharedSetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignSharedSetService", + "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.ads.googleads.v23.services.CampaignSharedSetService", + "credentialsType": None, + } + ), + ) + + async def mutate_campaign_shared_sets( + self, + request: Optional[ + Union[ + campaign_shared_set_service.MutateCampaignSharedSetsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_shared_set_service.CampaignSharedSetOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_shared_set_service.MutateCampaignSharedSetsResponse: + r"""Creates or removes campaign shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignSharedSetError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCampaignSharedSetsRequest, dict]]): + The request object. Request message for + [CampaignSharedSetService.MutateCampaignSharedSets][google.ads.googleads.v23.services.CampaignSharedSetService.MutateCampaignSharedSets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaign shared sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignSharedSetOperation]`): + Required. The list of operations to + perform on individual campaign shared + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignSharedSetsResponse: + Response message for a campaign + shared set mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_shared_set_service.MutateCampaignSharedSetsRequest + ): + request = ( + campaign_shared_set_service.MutateCampaignSharedSetsRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_campaign_shared_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CampaignSharedSetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CampaignSharedSetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/campaign_shared_set_service/client.py b/google/ads/googleads/v23/services/services/campaign_shared_set_service/client.py new file mode 100644 index 000000000..8480738ec --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_shared_set_service/client.py @@ -0,0 +1,962 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import campaign_shared_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CampaignSharedSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CampaignSharedSetServiceGrpcTransport +from .transports.grpc_asyncio import ( + CampaignSharedSetServiceGrpcAsyncIOTransport, +) + + +class CampaignSharedSetServiceClientMeta(type): + """Metaclass for the CampaignSharedSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CampaignSharedSetServiceTransport]] + _transport_registry["grpc"] = CampaignSharedSetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CampaignSharedSetServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CampaignSharedSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CampaignSharedSetServiceClient( + metaclass=CampaignSharedSetServiceClientMeta +): + """Service to manage campaign shared sets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignSharedSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CampaignSharedSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CampaignSharedSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CampaignSharedSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_shared_set_path( + customer_id: str, + campaign_id: str, + shared_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_shared_set string.""" + return "customers/{customer_id}/campaignSharedSets/{campaign_id}~{shared_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_campaign_shared_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignSharedSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_set_path( + customer_id: str, + shared_set_id: str, + ) -> str: + """Returns a fully-qualified shared_set string.""" + return "customers/{customer_id}/sharedSets/{shared_set_id}".format( + customer_id=customer_id, + shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_shared_set_path(path: str) -> Dict[str, str]: + """Parses a shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CampaignSharedSetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CampaignSharedSetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CampaignSharedSetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CampaignSharedSetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = CampaignSharedSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CampaignSharedSetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CampaignSharedSetServiceTransport, + Callable[..., CampaignSharedSetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the campaign shared set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CampaignSharedSetServiceTransport,Callable[..., CampaignSharedSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CampaignSharedSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CampaignSharedSetServiceClient._read_environment_variables() + self._client_cert_source = ( + CampaignSharedSetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CampaignSharedSetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CampaignSharedSetServiceTransport + ) + if transport_provided: + # transport is a CampaignSharedSetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CampaignSharedSetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CampaignSharedSetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CampaignSharedSetServiceTransport], + Callable[..., CampaignSharedSetServiceTransport], + ] = ( + CampaignSharedSetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CampaignSharedSetServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CampaignSharedSetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CampaignSharedSetService", + "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.ads.googleads.v23.services.CampaignSharedSetService", + "credentialsType": None, + } + ), + ) + + def mutate_campaign_shared_sets( + self, + request: Optional[ + Union[ + campaign_shared_set_service.MutateCampaignSharedSetsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + campaign_shared_set_service.CampaignSharedSetOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> campaign_shared_set_service.MutateCampaignSharedSetsResponse: + r"""Creates or removes campaign shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignSharedSetError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCampaignSharedSetsRequest, dict]): + The request object. Request message for + [CampaignSharedSetService.MutateCampaignSharedSets][google.ads.googleads.v23.services.CampaignSharedSetService.MutateCampaignSharedSets]. + customer_id (str): + Required. The ID of the customer + whose campaign shared sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignSharedSetOperation]): + Required. The list of operations to + perform on individual campaign shared + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCampaignSharedSetsResponse: + Response message for a campaign + shared set mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, campaign_shared_set_service.MutateCampaignSharedSetsRequest + ): + request = ( + campaign_shared_set_service.MutateCampaignSharedSetsRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_campaign_shared_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CampaignSharedSetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CampaignSharedSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/README.rst b/google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/README.rst rename to google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/__init__.py b/google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/campaign_shared_set_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/base.py b/google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/base.py new file mode 100644 index 000000000..75db79a33 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import campaign_shared_set_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CampaignSharedSetServiceTransport(abc.ABC): + """Abstract transport class for CampaignSharedSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_campaign_shared_sets: gapic_v1.method.wrap_method( + self.mutate_campaign_shared_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_campaign_shared_sets( + self, + ) -> Callable[ + [campaign_shared_set_service.MutateCampaignSharedSetsRequest], + Union[ + campaign_shared_set_service.MutateCampaignSharedSetsResponse, + Awaitable[ + campaign_shared_set_service.MutateCampaignSharedSetsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CampaignSharedSetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/grpc.py b/google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/grpc.py new file mode 100644 index 000000000..3701635c0 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/grpc.py @@ -0,0 +1,394 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import campaign_shared_set_service +from .base import CampaignSharedSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CampaignSharedSetService", + "rpcName": str(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.ads.googleads.v23.services.CampaignSharedSetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignSharedSetServiceGrpcTransport(CampaignSharedSetServiceTransport): + """gRPC backend transport for CampaignSharedSetService. + + Service to manage campaign shared sets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_campaign_shared_sets( + self, + ) -> Callable[ + [campaign_shared_set_service.MutateCampaignSharedSetsRequest], + campaign_shared_set_service.MutateCampaignSharedSetsResponse, + ]: + r"""Return a callable for the mutate campaign shared sets method over gRPC. + + Creates or removes campaign shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignSharedSetError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignSharedSetsRequest], + ~.MutateCampaignSharedSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_shared_sets" not in self._stubs: + self._stubs["mutate_campaign_shared_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignSharedSetService/MutateCampaignSharedSets", + request_serializer=campaign_shared_set_service.MutateCampaignSharedSetsRequest.serialize, + response_deserializer=campaign_shared_set_service.MutateCampaignSharedSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_shared_sets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CampaignSharedSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..23435d928 --- /dev/null +++ b/google/ads/googleads/v23/services/services/campaign_shared_set_service/transports/grpc_asyncio.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import campaign_shared_set_service +from .base import CampaignSharedSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CampaignSharedSetService", + "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.ads.googleads.v23.services.CampaignSharedSetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CampaignSharedSetServiceGrpcAsyncIOTransport( + CampaignSharedSetServiceTransport +): + """gRPC AsyncIO backend transport for CampaignSharedSetService. + + Service to manage campaign shared sets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_campaign_shared_sets( + self, + ) -> Callable[ + [campaign_shared_set_service.MutateCampaignSharedSetsRequest], + Awaitable[campaign_shared_set_service.MutateCampaignSharedSetsResponse], + ]: + r"""Return a callable for the mutate campaign shared sets method over gRPC. + + Creates or removes campaign shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CampaignSharedSetError <>`__ + `ContextError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `HeaderError <>`__ + `IdError <>`__ `InternalError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCampaignSharedSetsRequest], + Awaitable[~.MutateCampaignSharedSetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_campaign_shared_sets" not in self._stubs: + self._stubs["mutate_campaign_shared_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CampaignSharedSetService/MutateCampaignSharedSets", + request_serializer=campaign_shared_set_service.MutateCampaignSharedSetsRequest.serialize, + response_deserializer=campaign_shared_set_service.MutateCampaignSharedSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_campaign_shared_sets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_campaign_shared_sets: self._wrap_method( + self.mutate_campaign_shared_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CampaignSharedSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/content_creator_insights_service/__init__.py b/google/ads/googleads/v23/services/services/content_creator_insights_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/content_creator_insights_service/__init__.py rename to google/ads/googleads/v23/services/services/content_creator_insights_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/content_creator_insights_service/async_client.py b/google/ads/googleads/v23/services/services/content_creator_insights_service/async_client.py new file mode 100644 index 000000000..060845469 --- /dev/null +++ b/google/ads/googleads/v23/services/services/content_creator_insights_service/async_client.py @@ -0,0 +1,477 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + content_creator_insights_service, +) +from .transports.base import ( + ContentCreatorInsightsServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import ContentCreatorInsightsServiceClient + +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 ContentCreatorInsightsServiceAsyncClient: + """Content Creator Insights Service helps users find information + about YouTube Creators and their content and how these creators + and their audiences can be reached with Google Ads. Accessible + to allowlisted customers only. + """ + + _client: ContentCreatorInsightsServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ContentCreatorInsightsServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + ContentCreatorInsightsServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + ContentCreatorInsightsServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ContentCreatorInsightsServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod( + ContentCreatorInsightsServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ContentCreatorInsightsServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ContentCreatorInsightsServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ContentCreatorInsightsServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ContentCreatorInsightsServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ContentCreatorInsightsServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ContentCreatorInsightsServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ContentCreatorInsightsServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ContentCreatorInsightsServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ContentCreatorInsightsServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ContentCreatorInsightsServiceAsyncClient: The constructed client. + """ + return ContentCreatorInsightsServiceClient.from_service_account_info.__func__(ContentCreatorInsightsServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ContentCreatorInsightsServiceAsyncClient: The constructed client. + """ + return ContentCreatorInsightsServiceClient.from_service_account_file.__func__(ContentCreatorInsightsServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ContentCreatorInsightsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ContentCreatorInsightsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ContentCreatorInsightsServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + ContentCreatorInsightsServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ContentCreatorInsightsServiceTransport, + Callable[..., ContentCreatorInsightsServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the content creator insights service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ContentCreatorInsightsServiceTransport,Callable[..., ContentCreatorInsightsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ContentCreatorInsightsServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ContentCreatorInsightsServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ContentCreatorInsightsServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ContentCreatorInsightsService", + "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.ads.googleads.v23.services.ContentCreatorInsightsService", + "credentialsType": None, + } + ), + ) + + async def generate_creator_insights( + self, + request: Optional[ + Union[ + content_creator_insights_service.GenerateCreatorInsightsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> content_creator_insights_service.GenerateCreatorInsightsResponse: + r"""Returns insights for a collection of YouTube Creators and + Channels. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateCreatorInsightsRequest, dict]]): + The request object. Request message for + [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateCreatorInsights]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateCreatorInsightsResponse: + Response message for + [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateCreatorInsights]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + content_creator_insights_service.GenerateCreatorInsightsRequest, + ): + request = ( + content_creator_insights_service.GenerateCreatorInsightsRequest( + request + ) + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_creator_insights + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_trending_insights( + self, + request: Optional[ + Union[ + content_creator_insights_service.GenerateTrendingInsightsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> content_creator_insights_service.GenerateTrendingInsightsResponse: + r"""Returns insights for trending content on YouTube. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateTrendingInsightsRequest, dict]]): + The request object. Request message for + [ContentCreatorInsightsService.GenerateTrendingInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateTrendingInsights]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateTrendingInsightsResponse: + Response message for + [ContentCreatorInsightsService.GenerateTrendingInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateTrendingInsights]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + content_creator_insights_service.GenerateTrendingInsightsRequest, + ): + request = content_creator_insights_service.GenerateTrendingInsightsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_trending_insights + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ContentCreatorInsightsServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ContentCreatorInsightsServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/content_creator_insights_service/client.py b/google/ads/googleads/v23/services/services/content_creator_insights_service/client.py new file mode 100644 index 000000000..cf1f52a3e --- /dev/null +++ b/google/ads/googleads/v23/services/services/content_creator_insights_service/client.py @@ -0,0 +1,937 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + content_creator_insights_service, +) +from .transports.base import ( + ContentCreatorInsightsServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ContentCreatorInsightsServiceGrpcTransport +from .transports.grpc_asyncio import ( + ContentCreatorInsightsServiceGrpcAsyncIOTransport, +) + + +class ContentCreatorInsightsServiceClientMeta(type): + """Metaclass for the ContentCreatorInsightsService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ContentCreatorInsightsServiceTransport]] + _transport_registry["grpc"] = ContentCreatorInsightsServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + ContentCreatorInsightsServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ContentCreatorInsightsServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ContentCreatorInsightsServiceClient( + metaclass=ContentCreatorInsightsServiceClientMeta +): + """Content Creator Insights Service helps users find information + about YouTube Creators and their content and how these creators + and their audiences can be reached with Google Ads. Accessible + to allowlisted customers only. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ContentCreatorInsightsServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ContentCreatorInsightsServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ContentCreatorInsightsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ContentCreatorInsightsServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ContentCreatorInsightsServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ContentCreatorInsightsServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + ContentCreatorInsightsServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + ContentCreatorInsightsServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = ContentCreatorInsightsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ContentCreatorInsightsServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ContentCreatorInsightsServiceTransport, + Callable[..., ContentCreatorInsightsServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the content creator insights service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ContentCreatorInsightsServiceTransport,Callable[..., ContentCreatorInsightsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ContentCreatorInsightsServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ContentCreatorInsightsServiceClient._read_environment_variables() + self._client_cert_source = ( + ContentCreatorInsightsServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + ContentCreatorInsightsServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ContentCreatorInsightsServiceTransport + ) + if transport_provided: + # transport is a ContentCreatorInsightsServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + ContentCreatorInsightsServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ContentCreatorInsightsServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ContentCreatorInsightsServiceTransport], + Callable[..., ContentCreatorInsightsServiceTransport], + ] = ( + ContentCreatorInsightsServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ContentCreatorInsightsServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ContentCreatorInsightsServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ContentCreatorInsightsService", + "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.ads.googleads.v23.services.ContentCreatorInsightsService", + "credentialsType": None, + } + ), + ) + + def generate_creator_insights( + self, + request: Optional[ + Union[ + content_creator_insights_service.GenerateCreatorInsightsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> content_creator_insights_service.GenerateCreatorInsightsResponse: + r"""Returns insights for a collection of YouTube Creators and + Channels. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateCreatorInsightsRequest, dict]): + The request object. Request message for + [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateCreatorInsights]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateCreatorInsightsResponse: + Response message for + [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateCreatorInsights]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + content_creator_insights_service.GenerateCreatorInsightsRequest, + ): + request = ( + content_creator_insights_service.GenerateCreatorInsightsRequest( + request + ) + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_creator_insights + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_trending_insights( + self, + request: Optional[ + Union[ + content_creator_insights_service.GenerateTrendingInsightsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> content_creator_insights_service.GenerateTrendingInsightsResponse: + r"""Returns insights for trending content on YouTube. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateTrendingInsightsRequest, dict]): + The request object. Request message for + [ContentCreatorInsightsService.GenerateTrendingInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateTrendingInsights]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateTrendingInsightsResponse: + Response message for + [ContentCreatorInsightsService.GenerateTrendingInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateTrendingInsights]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + content_creator_insights_service.GenerateTrendingInsightsRequest, + ): + request = content_creator_insights_service.GenerateTrendingInsightsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_trending_insights + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ContentCreatorInsightsServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ContentCreatorInsightsServiceClient",) diff --git a/google/ads/googleads/v19/services/services/content_creator_insights_service/transports/README.rst b/google/ads/googleads/v23/services/services/content_creator_insights_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/content_creator_insights_service/transports/README.rst rename to google/ads/googleads/v23/services/services/content_creator_insights_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/content_creator_insights_service/transports/__init__.py b/google/ads/googleads/v23/services/services/content_creator_insights_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/content_creator_insights_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/content_creator_insights_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/content_creator_insights_service/transports/base.py b/google/ads/googleads/v23/services/services/content_creator_insights_service/transports/base.py new file mode 100644 index 000000000..f3d44628f --- /dev/null +++ b/google/ads/googleads/v23/services/services/content_creator_insights_service/transports/base.py @@ -0,0 +1,196 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + content_creator_insights_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ContentCreatorInsightsServiceTransport(abc.ABC): + """Abstract transport class for ContentCreatorInsightsService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.generate_creator_insights: gapic_v1.method.wrap_method( + self.generate_creator_insights, + default_timeout=None, + client_info=client_info, + ), + self.generate_trending_insights: gapic_v1.method.wrap_method( + self.generate_trending_insights, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def generate_creator_insights( + self, + ) -> Callable[ + [content_creator_insights_service.GenerateCreatorInsightsRequest], + Union[ + content_creator_insights_service.GenerateCreatorInsightsResponse, + Awaitable[ + content_creator_insights_service.GenerateCreatorInsightsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def generate_trending_insights( + self, + ) -> Callable[ + [content_creator_insights_service.GenerateTrendingInsightsRequest], + Union[ + content_creator_insights_service.GenerateTrendingInsightsResponse, + Awaitable[ + content_creator_insights_service.GenerateTrendingInsightsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ContentCreatorInsightsServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/content_creator_insights_service/transports/grpc.py b/google/ads/googleads/v23/services/services/content_creator_insights_service/transports/grpc.py new file mode 100644 index 000000000..0d55304cf --- /dev/null +++ b/google/ads/googleads/v23/services/services/content_creator_insights_service/transports/grpc.py @@ -0,0 +1,432 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + content_creator_insights_service, +) +from .base import ContentCreatorInsightsServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ContentCreatorInsightsService", + "rpcName": str(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.ads.googleads.v23.services.ContentCreatorInsightsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ContentCreatorInsightsServiceGrpcTransport( + ContentCreatorInsightsServiceTransport +): + """gRPC backend transport for ContentCreatorInsightsService. + + Content Creator Insights Service helps users find information + about YouTube Creators and their content and how these creators + and their audiences can be reached with Google Ads. Accessible + to allowlisted customers only. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def generate_creator_insights( + self, + ) -> Callable[ + [content_creator_insights_service.GenerateCreatorInsightsRequest], + content_creator_insights_service.GenerateCreatorInsightsResponse, + ]: + r"""Return a callable for the generate creator insights method over gRPC. + + Returns insights for a collection of YouTube Creators and + Channels. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateCreatorInsightsRequest], + ~.GenerateCreatorInsightsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_creator_insights" not in self._stubs: + self._stubs["generate_creator_insights"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ContentCreatorInsightsService/GenerateCreatorInsights", + request_serializer=content_creator_insights_service.GenerateCreatorInsightsRequest.serialize, + response_deserializer=content_creator_insights_service.GenerateCreatorInsightsResponse.deserialize, + ) + ) + return self._stubs["generate_creator_insights"] + + @property + def generate_trending_insights( + self, + ) -> Callable[ + [content_creator_insights_service.GenerateTrendingInsightsRequest], + content_creator_insights_service.GenerateTrendingInsightsResponse, + ]: + r"""Return a callable for the generate trending insights method over gRPC. + + Returns insights for trending content on YouTube. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateTrendingInsightsRequest], + ~.GenerateTrendingInsightsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_trending_insights" not in self._stubs: + self._stubs["generate_trending_insights"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ContentCreatorInsightsService/GenerateTrendingInsights", + request_serializer=content_creator_insights_service.GenerateTrendingInsightsRequest.serialize, + response_deserializer=content_creator_insights_service.GenerateTrendingInsightsResponse.deserialize, + ) + ) + return self._stubs["generate_trending_insights"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ContentCreatorInsightsServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/content_creator_insights_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/content_creator_insights_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..1ef2341d8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/content_creator_insights_service/transports/grpc_asyncio.py @@ -0,0 +1,462 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + content_creator_insights_service, +) +from .base import ContentCreatorInsightsServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ContentCreatorInsightsService", + "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.ads.googleads.v23.services.ContentCreatorInsightsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ContentCreatorInsightsServiceGrpcAsyncIOTransport( + ContentCreatorInsightsServiceTransport +): + """gRPC AsyncIO backend transport for ContentCreatorInsightsService. + + Content Creator Insights Service helps users find information + about YouTube Creators and their content and how these creators + and their audiences can be reached with Google Ads. Accessible + to allowlisted customers only. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def generate_creator_insights( + self, + ) -> Callable[ + [content_creator_insights_service.GenerateCreatorInsightsRequest], + Awaitable[ + content_creator_insights_service.GenerateCreatorInsightsResponse + ], + ]: + r"""Return a callable for the generate creator insights method over gRPC. + + Returns insights for a collection of YouTube Creators and + Channels. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateCreatorInsightsRequest], + Awaitable[~.GenerateCreatorInsightsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_creator_insights" not in self._stubs: + self._stubs["generate_creator_insights"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ContentCreatorInsightsService/GenerateCreatorInsights", + request_serializer=content_creator_insights_service.GenerateCreatorInsightsRequest.serialize, + response_deserializer=content_creator_insights_service.GenerateCreatorInsightsResponse.deserialize, + ) + ) + return self._stubs["generate_creator_insights"] + + @property + def generate_trending_insights( + self, + ) -> Callable[ + [content_creator_insights_service.GenerateTrendingInsightsRequest], + Awaitable[ + content_creator_insights_service.GenerateTrendingInsightsResponse + ], + ]: + r"""Return a callable for the generate trending insights method over gRPC. + + Returns insights for trending content on YouTube. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateTrendingInsightsRequest], + Awaitable[~.GenerateTrendingInsightsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_trending_insights" not in self._stubs: + self._stubs["generate_trending_insights"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ContentCreatorInsightsService/GenerateTrendingInsights", + request_serializer=content_creator_insights_service.GenerateTrendingInsightsRequest.serialize, + response_deserializer=content_creator_insights_service.GenerateTrendingInsightsResponse.deserialize, + ) + ) + return self._stubs["generate_trending_insights"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.generate_creator_insights: self._wrap_method( + self.generate_creator_insights, + default_timeout=None, + client_info=client_info, + ), + self.generate_trending_insights: self._wrap_method( + self.generate_trending_insights, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ContentCreatorInsightsServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_action_service/__init__.py b/google/ads/googleads/v23/services/services/conversion_action_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_action_service/__init__.py rename to google/ads/googleads/v23/services/services/conversion_action_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_action_service/async_client.py b/google/ads/googleads/v23/services/services/conversion_action_service/async_client.py new file mode 100644 index 000000000..13cdf2405 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_action_service/async_client.py @@ -0,0 +1,439 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import conversion_action_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionActionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import ConversionActionServiceClient + +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 ConversionActionServiceAsyncClient: + """Service to manage conversion actions.""" + + _client: ConversionActionServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ConversionActionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ConversionActionServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + ConversionActionServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ConversionActionServiceClient._DEFAULT_UNIVERSE + + conversion_action_path = staticmethod( + ConversionActionServiceClient.conversion_action_path + ) + parse_conversion_action_path = staticmethod( + ConversionActionServiceClient.parse_conversion_action_path + ) + customer_path = staticmethod(ConversionActionServiceClient.customer_path) + parse_customer_path = staticmethod( + ConversionActionServiceClient.parse_customer_path + ) + common_billing_account_path = staticmethod( + ConversionActionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ConversionActionServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ConversionActionServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ConversionActionServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ConversionActionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ConversionActionServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ConversionActionServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ConversionActionServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ConversionActionServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ConversionActionServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionActionServiceAsyncClient: The constructed client. + """ + return ConversionActionServiceClient.from_service_account_info.__func__(ConversionActionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionActionServiceAsyncClient: The constructed client. + """ + return ConversionActionServiceClient.from_service_account_file.__func__(ConversionActionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ConversionActionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ConversionActionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionActionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ConversionActionServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionActionServiceTransport, + Callable[..., ConversionActionServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion action service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionActionServiceTransport,Callable[..., ConversionActionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionActionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ConversionActionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ConversionActionServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionActionService", + "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.ads.googleads.v23.services.ConversionActionService", + "credentialsType": None, + } + ), + ) + + async def mutate_conversion_actions( + self, + request: Optional[ + Union[ + conversion_action_service.MutateConversionActionsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[conversion_action_service.ConversionActionOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> conversion_action_service.MutateConversionActionsResponse: + r"""Creates, updates or removes conversion actions. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `CurrencyCodeError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateConversionActionsRequest, dict]]): + The request object. Request message for + [ConversionActionService.MutateConversionActions][google.ads.googleads.v23.services.ConversionActionService.MutateConversionActions]. + customer_id (:class:`str`): + Required. The ID of the customer + whose conversion actions are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.ConversionActionOperation]`): + Required. The list of operations to + perform on individual conversion + actions. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateConversionActionsResponse: + Response message for + [ConversionActionService.MutateConversionActions][google.ads.googleads.v23.services.ConversionActionService.MutateConversionActions]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, conversion_action_service.MutateConversionActionsRequest + ): + request = conversion_action_service.MutateConversionActionsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_conversion_actions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ConversionActionServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ConversionActionServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/conversion_action_service/client.py b/google/ads/googleads/v23/services/services/conversion_action_service/client.py new file mode 100644 index 000000000..cc160508f --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_action_service/client.py @@ -0,0 +1,928 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import conversion_action_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionActionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionActionServiceGrpcTransport +from .transports.grpc_asyncio import ConversionActionServiceGrpcAsyncIOTransport + + +class ConversionActionServiceClientMeta(type): + """Metaclass for the ConversionActionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionActionServiceTransport]] + _transport_registry["grpc"] = ConversionActionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + ConversionActionServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ConversionActionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionActionServiceClient( + metaclass=ConversionActionServiceClientMeta +): + """Service to manage conversion actions.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionActionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionActionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionActionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionActionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def conversion_action_path( + customer_id: str, + conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, + conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ConversionActionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ConversionActionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ConversionActionServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ConversionActionServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + ConversionActionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ConversionActionServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionActionServiceTransport, + Callable[..., ConversionActionServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion action service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionActionServiceTransport,Callable[..., ConversionActionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionActionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ConversionActionServiceClient._read_environment_variables() + self._client_cert_source = ( + ConversionActionServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + ConversionActionServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ConversionActionServiceTransport + ) + if transport_provided: + # transport is a ConversionActionServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(ConversionActionServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ConversionActionServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ConversionActionServiceTransport], + Callable[..., ConversionActionServiceTransport], + ] = ( + ConversionActionServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ConversionActionServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ConversionActionServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionActionService", + "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.ads.googleads.v23.services.ConversionActionService", + "credentialsType": None, + } + ), + ) + + def mutate_conversion_actions( + self, + request: Optional[ + Union[ + conversion_action_service.MutateConversionActionsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[conversion_action_service.ConversionActionOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> conversion_action_service.MutateConversionActionsResponse: + r"""Creates, updates or removes conversion actions. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `CurrencyCodeError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateConversionActionsRequest, dict]): + The request object. Request message for + [ConversionActionService.MutateConversionActions][google.ads.googleads.v23.services.ConversionActionService.MutateConversionActions]. + customer_id (str): + Required. The ID of the customer + whose conversion actions are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.ConversionActionOperation]): + Required. The list of operations to + perform on individual conversion + actions. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateConversionActionsResponse: + Response message for + [ConversionActionService.MutateConversionActions][google.ads.googleads.v23.services.ConversionActionService.MutateConversionActions]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, conversion_action_service.MutateConversionActionsRequest + ): + request = conversion_action_service.MutateConversionActionsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_conversion_actions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ConversionActionServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ConversionActionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_action_service/transports/README.rst b/google/ads/googleads/v23/services/services/conversion_action_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_action_service/transports/README.rst rename to google/ads/googleads/v23/services/services/conversion_action_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/conversion_action_service/transports/__init__.py b/google/ads/googleads/v23/services/services/conversion_action_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_action_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/conversion_action_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_action_service/transports/base.py b/google/ads/googleads/v23/services/services/conversion_action_service/transports/base.py new file mode 100644 index 000000000..e5b05f8ad --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_action_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import conversion_action_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ConversionActionServiceTransport(abc.ABC): + """Abstract transport class for ConversionActionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_conversion_actions: gapic_v1.method.wrap_method( + self.mutate_conversion_actions, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_conversion_actions( + self, + ) -> Callable[ + [conversion_action_service.MutateConversionActionsRequest], + Union[ + conversion_action_service.MutateConversionActionsResponse, + Awaitable[ + conversion_action_service.MutateConversionActionsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ConversionActionServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_action_service/transports/grpc.py b/google/ads/googleads/v23/services/services/conversion_action_service/transports/grpc.py new file mode 100644 index 000000000..36a0424de --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_action_service/transports/grpc.py @@ -0,0 +1,392 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import conversion_action_service +from .base import ConversionActionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ConversionActionService", + "rpcName": str(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.ads.googleads.v23.services.ConversionActionService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionActionServiceGrpcTransport(ConversionActionServiceTransport): + """gRPC backend transport for ConversionActionService. + + Service to manage conversion actions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_conversion_actions( + self, + ) -> Callable[ + [conversion_action_service.MutateConversionActionsRequest], + conversion_action_service.MutateConversionActionsResponse, + ]: + r"""Return a callable for the mutate conversion actions method over gRPC. + + Creates, updates or removes conversion actions. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `CurrencyCodeError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateConversionActionsRequest], + ~.MutateConversionActionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_actions" not in self._stubs: + self._stubs["mutate_conversion_actions"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionActionService/MutateConversionActions", + request_serializer=conversion_action_service.MutateConversionActionsRequest.serialize, + response_deserializer=conversion_action_service.MutateConversionActionsResponse.deserialize, + ) + ) + return self._stubs["mutate_conversion_actions"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ConversionActionServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_action_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/conversion_action_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..a88902af8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_action_service/transports/grpc_asyncio.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import conversion_action_service +from .base import ConversionActionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ConversionActionService", + "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.ads.googleads.v23.services.ConversionActionService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionActionServiceGrpcAsyncIOTransport( + ConversionActionServiceTransport +): + """gRPC AsyncIO backend transport for ConversionActionService. + + Service to manage conversion actions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_conversion_actions( + self, + ) -> Callable[ + [conversion_action_service.MutateConversionActionsRequest], + Awaitable[conversion_action_service.MutateConversionActionsResponse], + ]: + r"""Return a callable for the mutate conversion actions method over gRPC. + + Creates, updates or removes conversion actions. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `CurrencyCodeError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateConversionActionsRequest], + Awaitable[~.MutateConversionActionsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_actions" not in self._stubs: + self._stubs["mutate_conversion_actions"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionActionService/MutateConversionActions", + request_serializer=conversion_action_service.MutateConversionActionsRequest.serialize, + response_deserializer=conversion_action_service.MutateConversionActionsResponse.deserialize, + ) + ) + return self._stubs["mutate_conversion_actions"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_conversion_actions: self._wrap_method( + self.mutate_conversion_actions, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ConversionActionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/__init__.py b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/__init__.py rename to google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/async_client.py b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/async_client.py new file mode 100644 index 000000000..3750409c2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/async_client.py @@ -0,0 +1,462 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + conversion_adjustment_upload_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionAdjustmentUploadServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import ConversionAdjustmentUploadServiceClient + +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 ConversionAdjustmentUploadServiceAsyncClient: + """Service to upload conversion adjustments.""" + + _client: ConversionAdjustmentUploadServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ConversionAdjustmentUploadServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + ConversionAdjustmentUploadServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + ConversionAdjustmentUploadServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ( + ConversionAdjustmentUploadServiceClient._DEFAULT_UNIVERSE + ) + + common_billing_account_path = staticmethod( + ConversionAdjustmentUploadServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ConversionAdjustmentUploadServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ConversionAdjustmentUploadServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ConversionAdjustmentUploadServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ConversionAdjustmentUploadServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ConversionAdjustmentUploadServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ConversionAdjustmentUploadServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ConversionAdjustmentUploadServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ConversionAdjustmentUploadServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ConversionAdjustmentUploadServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionAdjustmentUploadServiceAsyncClient: The constructed client. + """ + return ConversionAdjustmentUploadServiceClient.from_service_account_info.__func__(ConversionAdjustmentUploadServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionAdjustmentUploadServiceAsyncClient: The constructed client. + """ + return ConversionAdjustmentUploadServiceClient.from_service_account_file.__func__(ConversionAdjustmentUploadServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ConversionAdjustmentUploadServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ConversionAdjustmentUploadServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionAdjustmentUploadServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + ConversionAdjustmentUploadServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionAdjustmentUploadServiceTransport, + Callable[..., ConversionAdjustmentUploadServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion adjustment upload service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionAdjustmentUploadServiceTransport,Callable[..., ConversionAdjustmentUploadServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionAdjustmentUploadServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ConversionAdjustmentUploadServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ConversionAdjustmentUploadServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionAdjustmentUploadService", + "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.ads.googleads.v23.services.ConversionAdjustmentUploadService", + "credentialsType": None, + } + ), + ) + + async def upload_conversion_adjustments( + self, + request: Optional[ + Union[ + conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + conversion_adjustments: Optional[ + MutableSequence[ + conversion_adjustment_upload_service.ConversionAdjustment + ] + ] = None, + partial_failure: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse + ): + r"""Processes the given conversion adjustments. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.UploadConversionAdjustmentsRequest, dict]]): + The request object. Request message for + [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v23.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. + customer_id (:class:`str`): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + conversion_adjustments (:class:`MutableSequence[google.ads.googleads.v23.services.types.ConversionAdjustment]`): + Required. The conversion adjustments + that are being uploaded. + + This corresponds to the ``conversion_adjustments`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + partial_failure (:class:`bool`): + Required. If true, successful + operations will be carried out and + invalid operations will return errors. + If false, all operations will be carried + out in one transaction if and only if + they are all valid. This should always + be set to true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial + failure. + + This corresponds to the ``partial_failure`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UploadConversionAdjustmentsResponse: + Response message for + [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v23.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + conversion_adjustments, + partial_failure, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest, + ): + request = conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if partial_failure is not None: + request.partial_failure = partial_failure + if conversion_adjustments: + request.conversion_adjustments.extend(conversion_adjustments) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.upload_conversion_adjustments + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__( + self, + ) -> "ConversionAdjustmentUploadServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ConversionAdjustmentUploadServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/client.py b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/client.py new file mode 100644 index 000000000..c5bf870a6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/client.py @@ -0,0 +1,931 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + conversion_adjustment_upload_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionAdjustmentUploadServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionAdjustmentUploadServiceGrpcTransport +from .transports.grpc_asyncio import ( + ConversionAdjustmentUploadServiceGrpcAsyncIOTransport, +) + + +class ConversionAdjustmentUploadServiceClientMeta(type): + """Metaclass for the ConversionAdjustmentUploadService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionAdjustmentUploadServiceTransport]] + _transport_registry["grpc"] = ConversionAdjustmentUploadServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + ConversionAdjustmentUploadServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ConversionAdjustmentUploadServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionAdjustmentUploadServiceClient( + metaclass=ConversionAdjustmentUploadServiceClientMeta +): + """Service to upload conversion adjustments.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionAdjustmentUploadServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionAdjustmentUploadServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionAdjustmentUploadServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionAdjustmentUploadServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ConversionAdjustmentUploadServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ConversionAdjustmentUploadServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + ConversionAdjustmentUploadServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + ConversionAdjustmentUploadServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = ConversionAdjustmentUploadServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + ConversionAdjustmentUploadServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionAdjustmentUploadServiceTransport, + Callable[..., ConversionAdjustmentUploadServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion adjustment upload service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionAdjustmentUploadServiceTransport,Callable[..., ConversionAdjustmentUploadServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionAdjustmentUploadServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ( + ConversionAdjustmentUploadServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + ConversionAdjustmentUploadServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + ConversionAdjustmentUploadServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ConversionAdjustmentUploadServiceTransport + ) + if transport_provided: + # transport is a ConversionAdjustmentUploadServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + ConversionAdjustmentUploadServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ConversionAdjustmentUploadServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ConversionAdjustmentUploadServiceTransport], + Callable[..., ConversionAdjustmentUploadServiceTransport], + ] = ( + ConversionAdjustmentUploadServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ConversionAdjustmentUploadServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ConversionAdjustmentUploadServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionAdjustmentUploadService", + "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.ads.googleads.v23.services.ConversionAdjustmentUploadService", + "credentialsType": None, + } + ), + ) + + def upload_conversion_adjustments( + self, + request: Optional[ + Union[ + conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + conversion_adjustments: Optional[ + MutableSequence[ + conversion_adjustment_upload_service.ConversionAdjustment + ] + ] = None, + partial_failure: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse + ): + r"""Processes the given conversion adjustments. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.UploadConversionAdjustmentsRequest, dict]): + The request object. Request message for + [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v23.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. + customer_id (str): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + conversion_adjustments (MutableSequence[google.ads.googleads.v23.services.types.ConversionAdjustment]): + Required. The conversion adjustments + that are being uploaded. + + This corresponds to the ``conversion_adjustments`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + partial_failure (bool): + Required. If true, successful + operations will be carried out and + invalid operations will return errors. + If false, all operations will be carried + out in one transaction if and only if + they are all valid. This should always + be set to true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial + failure. + + This corresponds to the ``partial_failure`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UploadConversionAdjustmentsResponse: + Response message for + [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v23.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + conversion_adjustments, + partial_failure, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest, + ): + request = conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if conversion_adjustments is not None: + request.conversion_adjustments = conversion_adjustments + if partial_failure is not None: + request.partial_failure = partial_failure + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.upload_conversion_adjustments + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ConversionAdjustmentUploadServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ConversionAdjustmentUploadServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/README.rst b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/README.rst rename to google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/__init__.py b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_adjustment_upload_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/base.py b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/base.py new file mode 100644 index 000000000..466a2ec57 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + conversion_adjustment_upload_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ConversionAdjustmentUploadServiceTransport(abc.ABC): + """Abstract transport class for ConversionAdjustmentUploadService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.upload_conversion_adjustments: gapic_v1.method.wrap_method( + self.upload_conversion_adjustments, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def upload_conversion_adjustments( + self, + ) -> Callable[ + [ + conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest + ], + Union[ + conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse, + Awaitable[ + conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ConversionAdjustmentUploadServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/grpc.py b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/grpc.py new file mode 100644 index 000000000..dcde62c59 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/grpc.py @@ -0,0 +1,397 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + conversion_adjustment_upload_service, +) +from .base import ( + ConversionAdjustmentUploadServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ConversionAdjustmentUploadService", + "rpcName": str(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.ads.googleads.v23.services.ConversionAdjustmentUploadService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionAdjustmentUploadServiceGrpcTransport( + ConversionAdjustmentUploadServiceTransport +): + """gRPC backend transport for ConversionAdjustmentUploadService. + + Service to upload conversion adjustments. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def upload_conversion_adjustments( + self, + ) -> Callable[ + [ + conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest + ], + conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse, + ]: + r"""Return a callable for the upload conversion adjustments method over gRPC. + + Processes the given conversion adjustments. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.UploadConversionAdjustmentsRequest], + ~.UploadConversionAdjustmentsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_conversion_adjustments" not in self._stubs: + self._stubs["upload_conversion_adjustments"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionAdjustmentUploadService/UploadConversionAdjustments", + request_serializer=conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest.serialize, + response_deserializer=conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse.deserialize, + ) + ) + return self._stubs["upload_conversion_adjustments"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ConversionAdjustmentUploadServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..2d4a08517 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_adjustment_upload_service/transports/grpc_asyncio.py @@ -0,0 +1,420 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + conversion_adjustment_upload_service, +) +from .base import ( + ConversionAdjustmentUploadServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ConversionAdjustmentUploadService", + "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.ads.googleads.v23.services.ConversionAdjustmentUploadService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionAdjustmentUploadServiceGrpcAsyncIOTransport( + ConversionAdjustmentUploadServiceTransport +): + """gRPC AsyncIO backend transport for ConversionAdjustmentUploadService. + + Service to upload conversion adjustments. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def upload_conversion_adjustments( + self, + ) -> Callable[ + [ + conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest + ], + Awaitable[ + conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse + ], + ]: + r"""Return a callable for the upload conversion adjustments method over gRPC. + + Processes the given conversion adjustments. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.UploadConversionAdjustmentsRequest], + Awaitable[~.UploadConversionAdjustmentsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_conversion_adjustments" not in self._stubs: + self._stubs["upload_conversion_adjustments"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionAdjustmentUploadService/UploadConversionAdjustments", + request_serializer=conversion_adjustment_upload_service.UploadConversionAdjustmentsRequest.serialize, + response_deserializer=conversion_adjustment_upload_service.UploadConversionAdjustmentsResponse.deserialize, + ) + ) + return self._stubs["upload_conversion_adjustments"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.upload_conversion_adjustments: self._wrap_method( + self.upload_conversion_adjustments, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ConversionAdjustmentUploadServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/__init__.py b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_custom_variable_service/__init__.py rename to google/ads/googleads/v23/services/services/conversion_custom_variable_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_custom_variable_service/async_client.py b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/async_client.py new file mode 100644 index 000000000..fe5a484dc --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/async_client.py @@ -0,0 +1,450 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + conversion_custom_variable_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionCustomVariableServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import ConversionCustomVariableServiceClient + +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 ConversionCustomVariableServiceAsyncClient: + """Service to manage conversion custom variables.""" + + _client: ConversionCustomVariableServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ConversionCustomVariableServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + ConversionCustomVariableServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + ConversionCustomVariableServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ConversionCustomVariableServiceClient._DEFAULT_UNIVERSE + + conversion_custom_variable_path = staticmethod( + ConversionCustomVariableServiceClient.conversion_custom_variable_path + ) + parse_conversion_custom_variable_path = staticmethod( + ConversionCustomVariableServiceClient.parse_conversion_custom_variable_path + ) + customer_path = staticmethod( + ConversionCustomVariableServiceClient.customer_path + ) + parse_customer_path = staticmethod( + ConversionCustomVariableServiceClient.parse_customer_path + ) + common_billing_account_path = staticmethod( + ConversionCustomVariableServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ConversionCustomVariableServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ConversionCustomVariableServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ConversionCustomVariableServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ConversionCustomVariableServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ConversionCustomVariableServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ConversionCustomVariableServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ConversionCustomVariableServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ConversionCustomVariableServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ConversionCustomVariableServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionCustomVariableServiceAsyncClient: The constructed client. + """ + return ConversionCustomVariableServiceClient.from_service_account_info.__func__(ConversionCustomVariableServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionCustomVariableServiceAsyncClient: The constructed client. + """ + return ConversionCustomVariableServiceClient.from_service_account_file.__func__(ConversionCustomVariableServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ConversionCustomVariableServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ConversionCustomVariableServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionCustomVariableServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + ConversionCustomVariableServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionCustomVariableServiceTransport, + Callable[..., ConversionCustomVariableServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion custom variable service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionCustomVariableServiceTransport,Callable[..., ConversionCustomVariableServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionCustomVariableServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ConversionCustomVariableServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ConversionCustomVariableServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionCustomVariableService", + "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.ads.googleads.v23.services.ConversionCustomVariableService", + "credentialsType": None, + } + ), + ) + + async def mutate_conversion_custom_variables( + self, + request: Optional[ + Union[ + conversion_custom_variable_service.MutateConversionCustomVariablesRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + conversion_custom_variable_service.ConversionCustomVariableOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + conversion_custom_variable_service.MutateConversionCustomVariablesResponse + ): + r"""Creates or updates conversion custom variables. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionCustomVariableError <>`__ + `DatabaseError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateConversionCustomVariablesRequest, dict]]): + The request object. Request message for + [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v23.services.ConversionCustomVariableService.MutateConversionCustomVariables]. + customer_id (:class:`str`): + Required. The ID of the customer + whose conversion custom variables are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.ConversionCustomVariableOperation]`): + Required. The list of operations to + perform on individual conversion custom + variables. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateConversionCustomVariablesResponse: + Response message for + [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v23.services.ConversionCustomVariableService.MutateConversionCustomVariables]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + conversion_custom_variable_service.MutateConversionCustomVariablesRequest, + ): + request = conversion_custom_variable_service.MutateConversionCustomVariablesRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_conversion_custom_variables + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ConversionCustomVariableServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ConversionCustomVariableServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/conversion_custom_variable_service/client.py b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/client.py new file mode 100644 index 000000000..c5b9dbb85 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/client.py @@ -0,0 +1,944 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + conversion_custom_variable_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionCustomVariableServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionCustomVariableServiceGrpcTransport +from .transports.grpc_asyncio import ( + ConversionCustomVariableServiceGrpcAsyncIOTransport, +) + + +class ConversionCustomVariableServiceClientMeta(type): + """Metaclass for the ConversionCustomVariableService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionCustomVariableServiceTransport]] + _transport_registry["grpc"] = ConversionCustomVariableServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + ConversionCustomVariableServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ConversionCustomVariableServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionCustomVariableServiceClient( + metaclass=ConversionCustomVariableServiceClientMeta +): + """Service to manage conversion custom variables.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionCustomVariableServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionCustomVariableServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionCustomVariableServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionCustomVariableServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def conversion_custom_variable_path( + customer_id: str, + conversion_custom_variable_id: str, + ) -> str: + """Returns a fully-qualified conversion_custom_variable string.""" + return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( + customer_id=customer_id, + conversion_custom_variable_id=conversion_custom_variable_id, + ) + + @staticmethod + def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: + """Parses a conversion_custom_variable path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ConversionCustomVariableServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ConversionCustomVariableServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + ConversionCustomVariableServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + ConversionCustomVariableServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = ConversionCustomVariableServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + ConversionCustomVariableServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionCustomVariableServiceTransport, + Callable[..., ConversionCustomVariableServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion custom variable service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionCustomVariableServiceTransport,Callable[..., ConversionCustomVariableServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionCustomVariableServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ConversionCustomVariableServiceClient._read_environment_variables() + self._client_cert_source = ( + ConversionCustomVariableServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + ConversionCustomVariableServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ConversionCustomVariableServiceTransport + ) + if transport_provided: + # transport is a ConversionCustomVariableServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + ConversionCustomVariableServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ConversionCustomVariableServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ConversionCustomVariableServiceTransport], + Callable[..., ConversionCustomVariableServiceTransport], + ] = ( + ConversionCustomVariableServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ConversionCustomVariableServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ConversionCustomVariableServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionCustomVariableService", + "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.ads.googleads.v23.services.ConversionCustomVariableService", + "credentialsType": None, + } + ), + ) + + def mutate_conversion_custom_variables( + self, + request: Optional[ + Union[ + conversion_custom_variable_service.MutateConversionCustomVariablesRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + conversion_custom_variable_service.ConversionCustomVariableOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + conversion_custom_variable_service.MutateConversionCustomVariablesResponse + ): + r"""Creates or updates conversion custom variables. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionCustomVariableError <>`__ + `DatabaseError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateConversionCustomVariablesRequest, dict]): + The request object. Request message for + [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v23.services.ConversionCustomVariableService.MutateConversionCustomVariables]. + customer_id (str): + Required. The ID of the customer + whose conversion custom variables are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.ConversionCustomVariableOperation]): + Required. The list of operations to + perform on individual conversion custom + variables. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateConversionCustomVariablesResponse: + Response message for + [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v23.services.ConversionCustomVariableService.MutateConversionCustomVariables]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + conversion_custom_variable_service.MutateConversionCustomVariablesRequest, + ): + request = conversion_custom_variable_service.MutateConversionCustomVariablesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_conversion_custom_variables + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ConversionCustomVariableServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ConversionCustomVariableServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/README.rst b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/README.rst rename to google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/__init__.py b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_custom_variable_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/base.py b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/base.py new file mode 100644 index 000000000..099e2d48a --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + conversion_custom_variable_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ConversionCustomVariableServiceTransport(abc.ABC): + """Abstract transport class for ConversionCustomVariableService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_conversion_custom_variables: gapic_v1.method.wrap_method( + self.mutate_conversion_custom_variables, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_conversion_custom_variables( + self, + ) -> Callable[ + [ + conversion_custom_variable_service.MutateConversionCustomVariablesRequest + ], + Union[ + conversion_custom_variable_service.MutateConversionCustomVariablesResponse, + Awaitable[ + conversion_custom_variable_service.MutateConversionCustomVariablesResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ConversionCustomVariableServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/grpc.py b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/grpc.py new file mode 100644 index 000000000..d883c907e --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/grpc.py @@ -0,0 +1,396 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + conversion_custom_variable_service, +) +from .base import ConversionCustomVariableServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ConversionCustomVariableService", + "rpcName": str(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.ads.googleads.v23.services.ConversionCustomVariableService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionCustomVariableServiceGrpcTransport( + ConversionCustomVariableServiceTransport +): + """gRPC backend transport for ConversionCustomVariableService. + + Service to manage conversion custom variables. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_conversion_custom_variables( + self, + ) -> Callable[ + [ + conversion_custom_variable_service.MutateConversionCustomVariablesRequest + ], + conversion_custom_variable_service.MutateConversionCustomVariablesResponse, + ]: + r"""Return a callable for the mutate conversion custom + variables method over gRPC. + + Creates or updates conversion custom variables. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionCustomVariableError <>`__ + `DatabaseError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateConversionCustomVariablesRequest], + ~.MutateConversionCustomVariablesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_custom_variables" not in self._stubs: + self._stubs["mutate_conversion_custom_variables"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionCustomVariableService/MutateConversionCustomVariables", + request_serializer=conversion_custom_variable_service.MutateConversionCustomVariablesRequest.serialize, + response_deserializer=conversion_custom_variable_service.MutateConversionCustomVariablesResponse.deserialize, + ) + ) + return self._stubs["mutate_conversion_custom_variables"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ConversionCustomVariableServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..a5078eeb4 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_custom_variable_service/transports/grpc_asyncio.py @@ -0,0 +1,419 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + conversion_custom_variable_service, +) +from .base import ConversionCustomVariableServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ConversionCustomVariableService", + "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.ads.googleads.v23.services.ConversionCustomVariableService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionCustomVariableServiceGrpcAsyncIOTransport( + ConversionCustomVariableServiceTransport +): + """gRPC AsyncIO backend transport for ConversionCustomVariableService. + + Service to manage conversion custom variables. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_conversion_custom_variables( + self, + ) -> Callable[ + [ + conversion_custom_variable_service.MutateConversionCustomVariablesRequest + ], + Awaitable[ + conversion_custom_variable_service.MutateConversionCustomVariablesResponse + ], + ]: + r"""Return a callable for the mutate conversion custom + variables method over gRPC. + + Creates or updates conversion custom variables. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionCustomVariableError <>`__ + `DatabaseError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateConversionCustomVariablesRequest], + Awaitable[~.MutateConversionCustomVariablesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_custom_variables" not in self._stubs: + self._stubs["mutate_conversion_custom_variables"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionCustomVariableService/MutateConversionCustomVariables", + request_serializer=conversion_custom_variable_service.MutateConversionCustomVariablesRequest.serialize, + response_deserializer=conversion_custom_variable_service.MutateConversionCustomVariablesResponse.deserialize, + ) + ) + return self._stubs["mutate_conversion_custom_variables"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_conversion_custom_variables: self._wrap_method( + self.mutate_conversion_custom_variables, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ConversionCustomVariableServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/__init__.py b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/__init__.py rename to google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/async_client.py b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/async_client.py new file mode 100644 index 000000000..445bbede1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/async_client.py @@ -0,0 +1,456 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + conversion_goal_campaign_config_service, +) +from .transports.base import ( + ConversionGoalCampaignConfigServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import ConversionGoalCampaignConfigServiceClient + +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 ConversionGoalCampaignConfigServiceAsyncClient: + """Service to manage conversion goal campaign config.""" + + _client: ConversionGoalCampaignConfigServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ( + ConversionGoalCampaignConfigServiceClient.DEFAULT_ENDPOINT + ) + DEFAULT_MTLS_ENDPOINT = ( + ConversionGoalCampaignConfigServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + ConversionGoalCampaignConfigServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ( + ConversionGoalCampaignConfigServiceClient._DEFAULT_UNIVERSE + ) + + campaign_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.campaign_path + ) + parse_campaign_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.parse_campaign_path + ) + conversion_goal_campaign_config_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.conversion_goal_campaign_config_path + ) + parse_conversion_goal_campaign_config_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.parse_conversion_goal_campaign_config_path + ) + custom_conversion_goal_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.custom_conversion_goal_path + ) + parse_custom_conversion_goal_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.parse_custom_conversion_goal_path + ) + common_billing_account_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ConversionGoalCampaignConfigServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionGoalCampaignConfigServiceAsyncClient: The constructed client. + """ + return ConversionGoalCampaignConfigServiceClient.from_service_account_info.__func__(ConversionGoalCampaignConfigServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionGoalCampaignConfigServiceAsyncClient: The constructed client. + """ + return ConversionGoalCampaignConfigServiceClient.from_service_account_file.__func__(ConversionGoalCampaignConfigServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ConversionGoalCampaignConfigServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ConversionGoalCampaignConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionGoalCampaignConfigServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + ConversionGoalCampaignConfigServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionGoalCampaignConfigServiceTransport, + Callable[..., ConversionGoalCampaignConfigServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion goal campaign config service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionGoalCampaignConfigServiceTransport,Callable[..., ConversionGoalCampaignConfigServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionGoalCampaignConfigServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ConversionGoalCampaignConfigServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ConversionGoalCampaignConfigServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionGoalCampaignConfigService", + "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.ads.googleads.v23.services.ConversionGoalCampaignConfigService", + "credentialsType": None, + } + ), + ) + + async def mutate_conversion_goal_campaign_configs( + self, + request: Optional[ + Union[ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + conversion_goal_campaign_config_service.ConversionGoalCampaignConfigOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse + ): + r"""Creates, updates or removes conversion goal campaign + config. Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateConversionGoalCampaignConfigsRequest, dict]]): + The request object. Request message for + [ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs][google.ads.googleads.v23.services.ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs]. + customer_id (:class:`str`): + Required. The ID of the customer + whose custom conversion goals are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.ConversionGoalCampaignConfigOperation]`): + Required. The list of operations to + perform on individual conversion goal + campaign config. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateConversionGoalCampaignConfigsResponse: + Response message for a conversion + goal campaign config mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest, + ): + request = conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_conversion_goal_campaign_configs + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__( + self, + ) -> "ConversionGoalCampaignConfigServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ConversionGoalCampaignConfigServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/client.py b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/client.py new file mode 100644 index 000000000..9cbdad266 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/client.py @@ -0,0 +1,967 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + conversion_goal_campaign_config_service, +) +from .transports.base import ( + ConversionGoalCampaignConfigServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionGoalCampaignConfigServiceGrpcTransport +from .transports.grpc_asyncio import ( + ConversionGoalCampaignConfigServiceGrpcAsyncIOTransport, +) + + +class ConversionGoalCampaignConfigServiceClientMeta(type): + """Metaclass for the ConversionGoalCampaignConfigService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionGoalCampaignConfigServiceTransport]] + _transport_registry["grpc"] = ( + ConversionGoalCampaignConfigServiceGrpcTransport + ) + _transport_registry["grpc_asyncio"] = ( + ConversionGoalCampaignConfigServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ConversionGoalCampaignConfigServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionGoalCampaignConfigServiceClient( + metaclass=ConversionGoalCampaignConfigServiceClientMeta +): + """Service to manage conversion goal campaign config.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionGoalCampaignConfigServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionGoalCampaignConfigServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionGoalCampaignConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionGoalCampaignConfigServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_goal_campaign_config_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified conversion_goal_campaign_config string.""" + return "customers/{customer_id}/conversionGoalCampaignConfigs/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_conversion_goal_campaign_config_path(path: str) -> Dict[str, str]: + """Parses a conversion_goal_campaign_config path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionGoalCampaignConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def custom_conversion_goal_path( + customer_id: str, + goal_id: str, + ) -> str: + """Returns a fully-qualified custom_conversion_goal string.""" + return "customers/{customer_id}/customConversionGoals/{goal_id}".format( + customer_id=customer_id, + goal_id=goal_id, + ) + + @staticmethod + def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a custom_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ConversionGoalCampaignConfigServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ConversionGoalCampaignConfigServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + ConversionGoalCampaignConfigServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + ConversionGoalCampaignConfigServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = ConversionGoalCampaignConfigServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + ConversionGoalCampaignConfigServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionGoalCampaignConfigServiceTransport, + Callable[..., ConversionGoalCampaignConfigServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion goal campaign config service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionGoalCampaignConfigServiceTransport,Callable[..., ConversionGoalCampaignConfigServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionGoalCampaignConfigServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ( + ConversionGoalCampaignConfigServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + ConversionGoalCampaignConfigServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + ConversionGoalCampaignConfigServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ConversionGoalCampaignConfigServiceTransport + ) + if transport_provided: + # transport is a ConversionGoalCampaignConfigServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + ConversionGoalCampaignConfigServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ConversionGoalCampaignConfigServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ConversionGoalCampaignConfigServiceTransport], + Callable[..., ConversionGoalCampaignConfigServiceTransport], + ] = ( + ConversionGoalCampaignConfigServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ConversionGoalCampaignConfigServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ConversionGoalCampaignConfigServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionGoalCampaignConfigService", + "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.ads.googleads.v23.services.ConversionGoalCampaignConfigService", + "credentialsType": None, + } + ), + ) + + def mutate_conversion_goal_campaign_configs( + self, + request: Optional[ + Union[ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + conversion_goal_campaign_config_service.ConversionGoalCampaignConfigOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse + ): + r"""Creates, updates or removes conversion goal campaign + config. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateConversionGoalCampaignConfigsRequest, dict]): + The request object. Request message for + [ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs][google.ads.googleads.v23.services.ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs]. + customer_id (str): + Required. The ID of the customer + whose custom conversion goals are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.ConversionGoalCampaignConfigOperation]): + Required. The list of operations to + perform on individual conversion goal + campaign config. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateConversionGoalCampaignConfigsResponse: + Response message for a conversion + goal campaign config mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest, + ): + request = conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_conversion_goal_campaign_configs + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ConversionGoalCampaignConfigServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ConversionGoalCampaignConfigServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/README.rst b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/README.rst rename to google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/__init__.py b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_goal_campaign_config_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/base.py b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/base.py new file mode 100644 index 000000000..02e841d0e --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + conversion_goal_campaign_config_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ConversionGoalCampaignConfigServiceTransport(abc.ABC): + """Abstract transport class for ConversionGoalCampaignConfigService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_conversion_goal_campaign_configs: gapic_v1.method.wrap_method( + self.mutate_conversion_goal_campaign_configs, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_conversion_goal_campaign_configs( + self, + ) -> Callable[ + [ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest + ], + Union[ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse, + Awaitable[ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ConversionGoalCampaignConfigServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/grpc.py b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/grpc.py new file mode 100644 index 000000000..06d0552ac --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/grpc.py @@ -0,0 +1,394 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + conversion_goal_campaign_config_service, +) +from .base import ( + ConversionGoalCampaignConfigServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ConversionGoalCampaignConfigService", + "rpcName": str(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.ads.googleads.v23.services.ConversionGoalCampaignConfigService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionGoalCampaignConfigServiceGrpcTransport( + ConversionGoalCampaignConfigServiceTransport +): + """gRPC backend transport for ConversionGoalCampaignConfigService. + + Service to manage conversion goal campaign config. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_conversion_goal_campaign_configs( + self, + ) -> Callable[ + [ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest + ], + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse, + ]: + r"""Return a callable for the mutate conversion goal + campaign configs method over gRPC. + + Creates, updates or removes conversion goal campaign + config. Operation statuses are returned. + + Returns: + Callable[[~.MutateConversionGoalCampaignConfigsRequest], + ~.MutateConversionGoalCampaignConfigsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_goal_campaign_configs" not in self._stubs: + self._stubs["mutate_conversion_goal_campaign_configs"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionGoalCampaignConfigService/MutateConversionGoalCampaignConfigs", + request_serializer=conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest.serialize, + response_deserializer=conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse.deserialize, + ) + ) + return self._stubs["mutate_conversion_goal_campaign_configs"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ConversionGoalCampaignConfigServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..7030276b1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_goal_campaign_config_service/transports/grpc_asyncio.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + conversion_goal_campaign_config_service, +) +from .base import ( + ConversionGoalCampaignConfigServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ConversionGoalCampaignConfigService", + "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.ads.googleads.v23.services.ConversionGoalCampaignConfigService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionGoalCampaignConfigServiceGrpcAsyncIOTransport( + ConversionGoalCampaignConfigServiceTransport +): + """gRPC AsyncIO backend transport for ConversionGoalCampaignConfigService. + + Service to manage conversion goal campaign config. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_conversion_goal_campaign_configs( + self, + ) -> Callable[ + [ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest + ], + Awaitable[ + conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse + ], + ]: + r"""Return a callable for the mutate conversion goal + campaign configs method over gRPC. + + Creates, updates or removes conversion goal campaign + config. Operation statuses are returned. + + Returns: + Callable[[~.MutateConversionGoalCampaignConfigsRequest], + Awaitable[~.MutateConversionGoalCampaignConfigsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_goal_campaign_configs" not in self._stubs: + self._stubs["mutate_conversion_goal_campaign_configs"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionGoalCampaignConfigService/MutateConversionGoalCampaignConfigs", + request_serializer=conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsRequest.serialize, + response_deserializer=conversion_goal_campaign_config_service.MutateConversionGoalCampaignConfigsResponse.deserialize, + ) + ) + return self._stubs["mutate_conversion_goal_campaign_configs"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_conversion_goal_campaign_configs: self._wrap_method( + self.mutate_conversion_goal_campaign_configs, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ConversionGoalCampaignConfigServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_upload_service/__init__.py b/google/ads/googleads/v23/services/services/conversion_upload_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_upload_service/__init__.py rename to google/ads/googleads/v23/services/services/conversion_upload_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_upload_service/async_client.py b/google/ads/googleads/v23/services/services/conversion_upload_service/async_client.py new file mode 100644 index 000000000..48fef401b --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_upload_service/async_client.py @@ -0,0 +1,575 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import conversion_upload_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionUploadServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import ConversionUploadServiceClient + +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 ConversionUploadServiceAsyncClient: + """Service to upload conversions.""" + + _client: ConversionUploadServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ConversionUploadServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ConversionUploadServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + ConversionUploadServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ConversionUploadServiceClient._DEFAULT_UNIVERSE + + conversion_custom_variable_path = staticmethod( + ConversionUploadServiceClient.conversion_custom_variable_path + ) + parse_conversion_custom_variable_path = staticmethod( + ConversionUploadServiceClient.parse_conversion_custom_variable_path + ) + common_billing_account_path = staticmethod( + ConversionUploadServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ConversionUploadServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ConversionUploadServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ConversionUploadServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ConversionUploadServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ConversionUploadServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ConversionUploadServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ConversionUploadServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ConversionUploadServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ConversionUploadServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionUploadServiceAsyncClient: The constructed client. + """ + return ConversionUploadServiceClient.from_service_account_info.__func__(ConversionUploadServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionUploadServiceAsyncClient: The constructed client. + """ + return ConversionUploadServiceClient.from_service_account_file.__func__(ConversionUploadServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ConversionUploadServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ConversionUploadServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionUploadServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ConversionUploadServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionUploadServiceTransport, + Callable[..., ConversionUploadServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion upload service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionUploadServiceTransport,Callable[..., ConversionUploadServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionUploadServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ConversionUploadServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ConversionUploadServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionUploadService", + "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.ads.googleads.v23.services.ConversionUploadService", + "credentialsType": None, + } + ), + ) + + async def upload_click_conversions( + self, + request: Optional[ + Union[conversion_upload_service.UploadClickConversionsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + conversions: Optional[ + MutableSequence[conversion_upload_service.ClickConversion] + ] = None, + partial_failure: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> conversion_upload_service.UploadClickConversionsResponse: + r"""Processes the given click conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionUploadError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.UploadClickConversionsRequest, dict]]): + The request object. Request message for + [ConversionUploadService.UploadClickConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadClickConversions]. + customer_id (:class:`str`): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + conversions (:class:`MutableSequence[google.ads.googleads.v23.services.types.ClickConversion]`): + Required. The conversions that are + being uploaded. + + This corresponds to the ``conversions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + partial_failure (:class:`bool`): + Required. If true, successful + operations will be carried out and + invalid operations will return errors. + If false, all operations will be carried + out in one transaction if and only if + they are all valid. This should always + be set to true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial + failure. + + This corresponds to the ``partial_failure`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UploadClickConversionsResponse: + Response message for + [ConversionUploadService.UploadClickConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadClickConversions]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, conversions, partial_failure] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, conversion_upload_service.UploadClickConversionsRequest + ): + request = conversion_upload_service.UploadClickConversionsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if partial_failure is not None: + request.partial_failure = partial_failure + if conversions: + request.conversions.extend(conversions) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.upload_click_conversions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def upload_call_conversions( + self, + request: Optional[ + Union[conversion_upload_service.UploadCallConversionsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + conversions: Optional[ + MutableSequence[conversion_upload_service.CallConversion] + ] = None, + partial_failure: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> conversion_upload_service.UploadCallConversionsResponse: + r"""Processes the given call conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.UploadCallConversionsRequest, dict]]): + The request object. Request message for + [ConversionUploadService.UploadCallConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadCallConversions]. + customer_id (:class:`str`): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + conversions (:class:`MutableSequence[google.ads.googleads.v23.services.types.CallConversion]`): + Required. The conversions that are + being uploaded. + + This corresponds to the ``conversions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + partial_failure (:class:`bool`): + Required. If true, successful + operations will be carried out and + invalid operations will return errors. + If false, all operations will be carried + out in one transaction if and only if + they are all valid. This should always + be set to true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial + failure. + + This corresponds to the ``partial_failure`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UploadCallConversionsResponse: + Response message for + [ConversionUploadService.UploadCallConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadCallConversions]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, conversions, partial_failure] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, conversion_upload_service.UploadCallConversionsRequest + ): + request = conversion_upload_service.UploadCallConversionsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if partial_failure is not None: + request.partial_failure = partial_failure + if conversions: + request.conversions.extend(conversions) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.upload_call_conversions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ConversionUploadServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ConversionUploadServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/conversion_upload_service/client.py b/google/ads/googleads/v23/services/services/conversion_upload_service/client.py new file mode 100644 index 000000000..6de9c1d09 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_upload_service/client.py @@ -0,0 +1,1052 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import conversion_upload_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionUploadServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionUploadServiceGrpcTransport +from .transports.grpc_asyncio import ConversionUploadServiceGrpcAsyncIOTransport + + +class ConversionUploadServiceClientMeta(type): + """Metaclass for the ConversionUploadService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionUploadServiceTransport]] + _transport_registry["grpc"] = ConversionUploadServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + ConversionUploadServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ConversionUploadServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionUploadServiceClient( + metaclass=ConversionUploadServiceClientMeta +): + """Service to upload conversions.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionUploadServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionUploadServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionUploadServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionUploadServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def conversion_custom_variable_path( + customer_id: str, + conversion_custom_variable_id: str, + ) -> str: + """Returns a fully-qualified conversion_custom_variable string.""" + return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( + customer_id=customer_id, + conversion_custom_variable_id=conversion_custom_variable_id, + ) + + @staticmethod + def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: + """Parses a conversion_custom_variable path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ConversionUploadServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ConversionUploadServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ConversionUploadServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ConversionUploadServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + ConversionUploadServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ConversionUploadServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionUploadServiceTransport, + Callable[..., ConversionUploadServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion upload service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionUploadServiceTransport,Callable[..., ConversionUploadServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionUploadServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ConversionUploadServiceClient._read_environment_variables() + self._client_cert_source = ( + ConversionUploadServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + ConversionUploadServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ConversionUploadServiceTransport + ) + if transport_provided: + # transport is a ConversionUploadServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(ConversionUploadServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ConversionUploadServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ConversionUploadServiceTransport], + Callable[..., ConversionUploadServiceTransport], + ] = ( + ConversionUploadServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ConversionUploadServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ConversionUploadServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionUploadService", + "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.ads.googleads.v23.services.ConversionUploadService", + "credentialsType": None, + } + ), + ) + + def upload_click_conversions( + self, + request: Optional[ + Union[conversion_upload_service.UploadClickConversionsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + conversions: Optional[ + MutableSequence[conversion_upload_service.ClickConversion] + ] = None, + partial_failure: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> conversion_upload_service.UploadClickConversionsResponse: + r"""Processes the given click conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionUploadError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.UploadClickConversionsRequest, dict]): + The request object. Request message for + [ConversionUploadService.UploadClickConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadClickConversions]. + customer_id (str): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + conversions (MutableSequence[google.ads.googleads.v23.services.types.ClickConversion]): + Required. The conversions that are + being uploaded. + + This corresponds to the ``conversions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + partial_failure (bool): + Required. If true, successful + operations will be carried out and + invalid operations will return errors. + If false, all operations will be carried + out in one transaction if and only if + they are all valid. This should always + be set to true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial + failure. + + This corresponds to the ``partial_failure`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UploadClickConversionsResponse: + Response message for + [ConversionUploadService.UploadClickConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadClickConversions]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, conversions, partial_failure] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, conversion_upload_service.UploadClickConversionsRequest + ): + request = conversion_upload_service.UploadClickConversionsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if conversions is not None: + request.conversions = conversions + if partial_failure is not None: + request.partial_failure = partial_failure + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.upload_click_conversions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def upload_call_conversions( + self, + request: Optional[ + Union[conversion_upload_service.UploadCallConversionsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + conversions: Optional[ + MutableSequence[conversion_upload_service.CallConversion] + ] = None, + partial_failure: Optional[bool] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> conversion_upload_service.UploadCallConversionsResponse: + r"""Processes the given call conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.UploadCallConversionsRequest, dict]): + The request object. Request message for + [ConversionUploadService.UploadCallConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadCallConversions]. + customer_id (str): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + conversions (MutableSequence[google.ads.googleads.v23.services.types.CallConversion]): + Required. The conversions that are + being uploaded. + + This corresponds to the ``conversions`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + partial_failure (bool): + Required. If true, successful + operations will be carried out and + invalid operations will return errors. + If false, all operations will be carried + out in one transaction if and only if + they are all valid. This should always + be set to true. + See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial + failure. + + This corresponds to the ``partial_failure`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UploadCallConversionsResponse: + Response message for + [ConversionUploadService.UploadCallConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadCallConversions]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, conversions, partial_failure] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, conversion_upload_service.UploadCallConversionsRequest + ): + request = conversion_upload_service.UploadCallConversionsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if conversions is not None: + request.conversions = conversions + if partial_failure is not None: + request.partial_failure = partial_failure + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.upload_call_conversions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ConversionUploadServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ConversionUploadServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_upload_service/transports/README.rst b/google/ads/googleads/v23/services/services/conversion_upload_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_upload_service/transports/README.rst rename to google/ads/googleads/v23/services/services/conversion_upload_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/conversion_upload_service/transports/__init__.py b/google/ads/googleads/v23/services/services/conversion_upload_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_upload_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/conversion_upload_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_upload_service/transports/base.py b/google/ads/googleads/v23/services/services/conversion_upload_service/transports/base.py new file mode 100644 index 000000000..dd99520e9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_upload_service/transports/base.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import conversion_upload_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ConversionUploadServiceTransport(abc.ABC): + """Abstract transport class for ConversionUploadService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.upload_click_conversions: gapic_v1.method.wrap_method( + self.upload_click_conversions, + default_timeout=None, + client_info=client_info, + ), + self.upload_call_conversions: gapic_v1.method.wrap_method( + self.upload_call_conversions, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def upload_click_conversions( + self, + ) -> Callable[ + [conversion_upload_service.UploadClickConversionsRequest], + Union[ + conversion_upload_service.UploadClickConversionsResponse, + Awaitable[conversion_upload_service.UploadClickConversionsResponse], + ], + ]: + raise NotImplementedError() + + @property + def upload_call_conversions( + self, + ) -> Callable[ + [conversion_upload_service.UploadCallConversionsRequest], + Union[ + conversion_upload_service.UploadCallConversionsResponse, + Awaitable[conversion_upload_service.UploadCallConversionsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ConversionUploadServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_upload_service/transports/grpc.py b/google/ads/googleads/v23/services/services/conversion_upload_service/transports/grpc.py new file mode 100644 index 000000000..ed9bb367c --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_upload_service/transports/grpc.py @@ -0,0 +1,424 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import conversion_upload_service +from .base import ConversionUploadServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ConversionUploadService", + "rpcName": str(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.ads.googleads.v23.services.ConversionUploadService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionUploadServiceGrpcTransport(ConversionUploadServiceTransport): + """gRPC backend transport for ConversionUploadService. + + Service to upload conversions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def upload_click_conversions( + self, + ) -> Callable[ + [conversion_upload_service.UploadClickConversionsRequest], + conversion_upload_service.UploadClickConversionsResponse, + ]: + r"""Return a callable for the upload click conversions method over gRPC. + + Processes the given click conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionUploadError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.UploadClickConversionsRequest], + ~.UploadClickConversionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_click_conversions" not in self._stubs: + self._stubs["upload_click_conversions"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionUploadService/UploadClickConversions", + request_serializer=conversion_upload_service.UploadClickConversionsRequest.serialize, + response_deserializer=conversion_upload_service.UploadClickConversionsResponse.deserialize, + ) + ) + return self._stubs["upload_click_conversions"] + + @property + def upload_call_conversions( + self, + ) -> Callable[ + [conversion_upload_service.UploadCallConversionsRequest], + conversion_upload_service.UploadCallConversionsResponse, + ]: + r"""Return a callable for the upload call conversions method over gRPC. + + Processes the given call conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.UploadCallConversionsRequest], + ~.UploadCallConversionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_call_conversions" not in self._stubs: + self._stubs["upload_call_conversions"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionUploadService/UploadCallConversions", + request_serializer=conversion_upload_service.UploadCallConversionsRequest.serialize, + response_deserializer=conversion_upload_service.UploadCallConversionsResponse.deserialize, + ) + ) + return self._stubs["upload_call_conversions"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ConversionUploadServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_upload_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/conversion_upload_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..a7000b1e1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_upload_service/transports/grpc_asyncio.py @@ -0,0 +1,452 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import conversion_upload_service +from .base import ConversionUploadServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ConversionUploadService", + "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.ads.googleads.v23.services.ConversionUploadService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionUploadServiceGrpcAsyncIOTransport( + ConversionUploadServiceTransport +): + """gRPC AsyncIO backend transport for ConversionUploadService. + + Service to upload conversions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def upload_click_conversions( + self, + ) -> Callable[ + [conversion_upload_service.UploadClickConversionsRequest], + Awaitable[conversion_upload_service.UploadClickConversionsResponse], + ]: + r"""Return a callable for the upload click conversions method over gRPC. + + Processes the given click conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionUploadError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `PartialFailureError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.UploadClickConversionsRequest], + Awaitable[~.UploadClickConversionsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_click_conversions" not in self._stubs: + self._stubs["upload_click_conversions"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionUploadService/UploadClickConversions", + request_serializer=conversion_upload_service.UploadClickConversionsRequest.serialize, + response_deserializer=conversion_upload_service.UploadClickConversionsResponse.deserialize, + ) + ) + return self._stubs["upload_click_conversions"] + + @property + def upload_call_conversions( + self, + ) -> Callable[ + [conversion_upload_service.UploadCallConversionsRequest], + Awaitable[conversion_upload_service.UploadCallConversionsResponse], + ]: + r"""Return a callable for the upload call conversions method over gRPC. + + Processes the given call conversions. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PartialFailureError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.UploadCallConversionsRequest], + Awaitable[~.UploadCallConversionsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_call_conversions" not in self._stubs: + self._stubs["upload_call_conversions"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionUploadService/UploadCallConversions", + request_serializer=conversion_upload_service.UploadCallConversionsRequest.serialize, + response_deserializer=conversion_upload_service.UploadCallConversionsResponse.deserialize, + ) + ) + return self._stubs["upload_call_conversions"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.upload_click_conversions: self._wrap_method( + self.upload_click_conversions, + default_timeout=None, + client_info=client_info, + ), + self.upload_call_conversions: self._wrap_method( + self.upload_call_conversions, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ConversionUploadServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_service/__init__.py b/google/ads/googleads/v23/services/services/conversion_value_rule_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_value_rule_service/__init__.py rename to google/ads/googleads/v23/services/services/conversion_value_rule_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_value_rule_service/async_client.py b/google/ads/googleads/v23/services/services/conversion_value_rule_service/async_client.py new file mode 100644 index 000000000..2fe9850ab --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_value_rule_service/async_client.py @@ -0,0 +1,459 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + conversion_value_rule_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionValueRuleServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import ConversionValueRuleServiceClient + +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 ConversionValueRuleServiceAsyncClient: + """Service to manage conversion value rules.""" + + _client: ConversionValueRuleServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ConversionValueRuleServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + ConversionValueRuleServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + ConversionValueRuleServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ConversionValueRuleServiceClient._DEFAULT_UNIVERSE + + conversion_value_rule_path = staticmethod( + ConversionValueRuleServiceClient.conversion_value_rule_path + ) + parse_conversion_value_rule_path = staticmethod( + ConversionValueRuleServiceClient.parse_conversion_value_rule_path + ) + customer_path = staticmethod(ConversionValueRuleServiceClient.customer_path) + parse_customer_path = staticmethod( + ConversionValueRuleServiceClient.parse_customer_path + ) + geo_target_constant_path = staticmethod( + ConversionValueRuleServiceClient.geo_target_constant_path + ) + parse_geo_target_constant_path = staticmethod( + ConversionValueRuleServiceClient.parse_geo_target_constant_path + ) + user_interest_path = staticmethod( + ConversionValueRuleServiceClient.user_interest_path + ) + parse_user_interest_path = staticmethod( + ConversionValueRuleServiceClient.parse_user_interest_path + ) + user_list_path = staticmethod( + ConversionValueRuleServiceClient.user_list_path + ) + parse_user_list_path = staticmethod( + ConversionValueRuleServiceClient.parse_user_list_path + ) + common_billing_account_path = staticmethod( + ConversionValueRuleServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ConversionValueRuleServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ConversionValueRuleServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ConversionValueRuleServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ConversionValueRuleServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ConversionValueRuleServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ConversionValueRuleServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ConversionValueRuleServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ConversionValueRuleServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ConversionValueRuleServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleServiceAsyncClient: The constructed client. + """ + return ConversionValueRuleServiceClient.from_service_account_info.__func__(ConversionValueRuleServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleServiceAsyncClient: The constructed client. + """ + return ConversionValueRuleServiceClient.from_service_account_file.__func__(ConversionValueRuleServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ConversionValueRuleServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ConversionValueRuleServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionValueRuleServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ConversionValueRuleServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionValueRuleServiceTransport, + Callable[..., ConversionValueRuleServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion value rule service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionValueRuleServiceTransport,Callable[..., ConversionValueRuleServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionValueRuleServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ConversionValueRuleServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ConversionValueRuleServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionValueRuleService", + "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.ads.googleads.v23.services.ConversionValueRuleService", + "credentialsType": None, + } + ), + ) + + async def mutate_conversion_value_rules( + self, + request: Optional[ + Union[ + conversion_value_rule_service.MutateConversionValueRulesRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + conversion_value_rule_service.ConversionValueRuleOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> conversion_value_rule_service.MutateConversionValueRulesResponse: + r"""Creates, updates, or removes conversion value rules. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateConversionValueRulesRequest, dict]]): + The request object. Request message for + [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v23.services.ConversionValueRuleService.MutateConversionValueRules]. + customer_id (:class:`str`): + Required. The ID of the customer + whose conversion value rules are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.ConversionValueRuleOperation]`): + Required. The list of operations to + perform on individual conversion value + rules. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateConversionValueRulesResponse: + Response message for + [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v23.services.ConversionValueRuleService.MutateConversionValueRules]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + conversion_value_rule_service.MutateConversionValueRulesRequest, + ): + request = ( + conversion_value_rule_service.MutateConversionValueRulesRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_conversion_value_rules + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ConversionValueRuleServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ConversionValueRuleServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/conversion_value_rule_service/client.py b/google/ads/googleads/v23/services/services/conversion_value_rule_service/client.py new file mode 100644 index 000000000..357e0036e --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_value_rule_service/client.py @@ -0,0 +1,992 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + conversion_value_rule_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionValueRuleServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionValueRuleServiceGrpcTransport +from .transports.grpc_asyncio import ( + ConversionValueRuleServiceGrpcAsyncIOTransport, +) + + +class ConversionValueRuleServiceClientMeta(type): + """Metaclass for the ConversionValueRuleService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionValueRuleServiceTransport]] + _transport_registry["grpc"] = ConversionValueRuleServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + ConversionValueRuleServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ConversionValueRuleServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionValueRuleServiceClient( + metaclass=ConversionValueRuleServiceClientMeta +): + """Service to manage conversion value rules.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionValueRuleServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionValueRuleServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def conversion_value_rule_path( + customer_id: str, + conversion_value_rule_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule string.""" + return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( + customer_id=customer_id, + conversion_value_rule_id=conversion_value_rule_id, + ) + + @staticmethod + def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def geo_target_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def user_interest_path( + customer_id: str, + user_interest_id: str, + ) -> str: + """Returns a fully-qualified user_interest string.""" + return ( + "customers/{customer_id}/userInterests/{user_interest_id}".format( + customer_id=customer_id, + user_interest_id=user_interest_id, + ) + ) + + @staticmethod + def parse_user_interest_path(path: str) -> Dict[str, str]: + """Parses a user_interest path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userInterests/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_list_path( + customer_id: str, + user_list_id: str, + ) -> str: + """Returns a fully-qualified user_list string.""" + return "customers/{customer_id}/userLists/{user_list_id}".format( + customer_id=customer_id, + user_list_id=user_list_id, + ) + + @staticmethod + def parse_user_list_path(path: str) -> Dict[str, str]: + """Parses a user_list path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userLists/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ConversionValueRuleServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ConversionValueRuleServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + ConversionValueRuleServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + ConversionValueRuleServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = ConversionValueRuleServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ConversionValueRuleServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionValueRuleServiceTransport, + Callable[..., ConversionValueRuleServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion value rule service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionValueRuleServiceTransport,Callable[..., ConversionValueRuleServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionValueRuleServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ConversionValueRuleServiceClient._read_environment_variables() + self._client_cert_source = ( + ConversionValueRuleServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + ConversionValueRuleServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ConversionValueRuleServiceTransport + ) + if transport_provided: + # transport is a ConversionValueRuleServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + ConversionValueRuleServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ConversionValueRuleServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ConversionValueRuleServiceTransport], + Callable[..., ConversionValueRuleServiceTransport], + ] = ( + ConversionValueRuleServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ConversionValueRuleServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ConversionValueRuleServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionValueRuleService", + "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.ads.googleads.v23.services.ConversionValueRuleService", + "credentialsType": None, + } + ), + ) + + def mutate_conversion_value_rules( + self, + request: Optional[ + Union[ + conversion_value_rule_service.MutateConversionValueRulesRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + conversion_value_rule_service.ConversionValueRuleOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> conversion_value_rule_service.MutateConversionValueRulesResponse: + r"""Creates, updates, or removes conversion value rules. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateConversionValueRulesRequest, dict]): + The request object. Request message for + [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v23.services.ConversionValueRuleService.MutateConversionValueRules]. + customer_id (str): + Required. The ID of the customer + whose conversion value rules are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.ConversionValueRuleOperation]): + Required. The list of operations to + perform on individual conversion value + rules. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateConversionValueRulesResponse: + Response message for + [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v23.services.ConversionValueRuleService.MutateConversionValueRules]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + conversion_value_rule_service.MutateConversionValueRulesRequest, + ): + request = ( + conversion_value_rule_service.MutateConversionValueRulesRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_conversion_value_rules + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ConversionValueRuleServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ConversionValueRuleServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/README.rst b/google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/README.rst rename to google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/__init__.py b/google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_value_rule_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/base.py b/google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/base.py new file mode 100644 index 000000000..5056dfe7f --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + conversion_value_rule_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ConversionValueRuleServiceTransport(abc.ABC): + """Abstract transport class for ConversionValueRuleService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_conversion_value_rules: gapic_v1.method.wrap_method( + self.mutate_conversion_value_rules, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_conversion_value_rules( + self, + ) -> Callable[ + [conversion_value_rule_service.MutateConversionValueRulesRequest], + Union[ + conversion_value_rule_service.MutateConversionValueRulesResponse, + Awaitable[ + conversion_value_rule_service.MutateConversionValueRulesResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ConversionValueRuleServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/grpc.py b/google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/grpc.py new file mode 100644 index 000000000..707445713 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/grpc.py @@ -0,0 +1,388 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + conversion_value_rule_service, +) +from .base import ConversionValueRuleServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ConversionValueRuleService", + "rpcName": str(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.ads.googleads.v23.services.ConversionValueRuleService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionValueRuleServiceGrpcTransport( + ConversionValueRuleServiceTransport +): + """gRPC backend transport for ConversionValueRuleService. + + Service to manage conversion value rules. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_conversion_value_rules( + self, + ) -> Callable[ + [conversion_value_rule_service.MutateConversionValueRulesRequest], + conversion_value_rule_service.MutateConversionValueRulesResponse, + ]: + r"""Return a callable for the mutate conversion value rules method over gRPC. + + Creates, updates, or removes conversion value rules. + Operation statuses are returned. + + Returns: + Callable[[~.MutateConversionValueRulesRequest], + ~.MutateConversionValueRulesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_value_rules" not in self._stubs: + self._stubs["mutate_conversion_value_rules"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionValueRuleService/MutateConversionValueRules", + request_serializer=conversion_value_rule_service.MutateConversionValueRulesRequest.serialize, + response_deserializer=conversion_value_rule_service.MutateConversionValueRulesResponse.deserialize, + ) + ) + return self._stubs["mutate_conversion_value_rules"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ConversionValueRuleServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..15e827673 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_value_rule_service/transports/grpc_asyncio.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + conversion_value_rule_service, +) +from .base import ConversionValueRuleServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ConversionValueRuleService", + "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.ads.googleads.v23.services.ConversionValueRuleService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionValueRuleServiceGrpcAsyncIOTransport( + ConversionValueRuleServiceTransport +): + """gRPC AsyncIO backend transport for ConversionValueRuleService. + + Service to manage conversion value rules. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_conversion_value_rules( + self, + ) -> Callable[ + [conversion_value_rule_service.MutateConversionValueRulesRequest], + Awaitable[ + conversion_value_rule_service.MutateConversionValueRulesResponse + ], + ]: + r"""Return a callable for the mutate conversion value rules method over gRPC. + + Creates, updates, or removes conversion value rules. + Operation statuses are returned. + + Returns: + Callable[[~.MutateConversionValueRulesRequest], + Awaitable[~.MutateConversionValueRulesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_value_rules" not in self._stubs: + self._stubs["mutate_conversion_value_rules"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionValueRuleService/MutateConversionValueRules", + request_serializer=conversion_value_rule_service.MutateConversionValueRulesRequest.serialize, + response_deserializer=conversion_value_rule_service.MutateConversionValueRulesResponse.deserialize, + ) + ) + return self._stubs["mutate_conversion_value_rules"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_conversion_value_rules: self._wrap_method( + self.mutate_conversion_value_rules, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ConversionValueRuleServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/__init__.py b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_value_rule_set_service/__init__.py rename to google/ads/googleads/v23/services/services/conversion_value_rule_set_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/async_client.py b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/async_client.py new file mode 100644 index 000000000..6429d8ec8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/async_client.py @@ -0,0 +1,457 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + conversion_value_rule_set_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionValueRuleSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import ConversionValueRuleSetServiceClient + +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 ConversionValueRuleSetServiceAsyncClient: + """Service to manage conversion value rule sets.""" + + _client: ConversionValueRuleSetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ConversionValueRuleSetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + ConversionValueRuleSetServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + ConversionValueRuleSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ConversionValueRuleSetServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod( + ConversionValueRuleSetServiceClient.campaign_path + ) + parse_campaign_path = staticmethod( + ConversionValueRuleSetServiceClient.parse_campaign_path + ) + conversion_value_rule_path = staticmethod( + ConversionValueRuleSetServiceClient.conversion_value_rule_path + ) + parse_conversion_value_rule_path = staticmethod( + ConversionValueRuleSetServiceClient.parse_conversion_value_rule_path + ) + conversion_value_rule_set_path = staticmethod( + ConversionValueRuleSetServiceClient.conversion_value_rule_set_path + ) + parse_conversion_value_rule_set_path = staticmethod( + ConversionValueRuleSetServiceClient.parse_conversion_value_rule_set_path + ) + customer_path = staticmethod( + ConversionValueRuleSetServiceClient.customer_path + ) + parse_customer_path = staticmethod( + ConversionValueRuleSetServiceClient.parse_customer_path + ) + common_billing_account_path = staticmethod( + ConversionValueRuleSetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ConversionValueRuleSetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ConversionValueRuleSetServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ConversionValueRuleSetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ConversionValueRuleSetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ConversionValueRuleSetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ConversionValueRuleSetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ConversionValueRuleSetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ConversionValueRuleSetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ConversionValueRuleSetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleSetServiceAsyncClient: The constructed client. + """ + return ConversionValueRuleSetServiceClient.from_service_account_info.__func__(ConversionValueRuleSetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleSetServiceAsyncClient: The constructed client. + """ + return ConversionValueRuleSetServiceClient.from_service_account_file.__func__(ConversionValueRuleSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ConversionValueRuleSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ConversionValueRuleSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionValueRuleSetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + ConversionValueRuleSetServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionValueRuleSetServiceTransport, + Callable[..., ConversionValueRuleSetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion value rule set service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionValueRuleSetServiceTransport,Callable[..., ConversionValueRuleSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionValueRuleSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ConversionValueRuleSetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ConversionValueRuleSetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionValueRuleSetService", + "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.ads.googleads.v23.services.ConversionValueRuleSetService", + "credentialsType": None, + } + ), + ) + + async def mutate_conversion_value_rule_sets( + self, + request: Optional[ + Union[ + conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + conversion_value_rule_set_service.ConversionValueRuleSetOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse + ): + r"""Creates, updates or removes conversion value rule + sets. Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateConversionValueRuleSetsRequest, dict]]): + The request object. Request message for + [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v23.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose conversion value rule sets are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.ConversionValueRuleSetOperation]`): + Required. The list of operations to + perform on individual conversion value + rule sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateConversionValueRuleSetsResponse: + Response message for + [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v23.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest, + ): + request = conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_conversion_value_rule_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ConversionValueRuleSetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ConversionValueRuleSetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/client.py b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/client.py new file mode 100644 index 000000000..e6a913172 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/client.py @@ -0,0 +1,977 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + conversion_value_rule_set_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + ConversionValueRuleSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ConversionValueRuleSetServiceGrpcTransport +from .transports.grpc_asyncio import ( + ConversionValueRuleSetServiceGrpcAsyncIOTransport, +) + + +class ConversionValueRuleSetServiceClientMeta(type): + """Metaclass for the ConversionValueRuleSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ConversionValueRuleSetServiceTransport]] + _transport_registry["grpc"] = ConversionValueRuleSetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + ConversionValueRuleSetServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ConversionValueRuleSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ConversionValueRuleSetServiceClient( + metaclass=ConversionValueRuleSetServiceClientMeta +): + """Service to manage conversion value rule sets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ConversionValueRuleSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ConversionValueRuleSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ConversionValueRuleSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_path( + customer_id: str, + conversion_value_rule_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule string.""" + return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( + customer_id=customer_id, + conversion_value_rule_id=conversion_value_rule_id, + ) + + @staticmethod + def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_set_path( + customer_id: str, + conversion_value_rule_set_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule_set string.""" + return "customers/{customer_id}/conversionValueRuleSets/{conversion_value_rule_set_id}".format( + customer_id=customer_id, + conversion_value_rule_set_id=conversion_value_rule_set_id, + ) + + @staticmethod + def parse_conversion_value_rule_set_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRuleSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ConversionValueRuleSetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ConversionValueRuleSetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + ConversionValueRuleSetServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + ConversionValueRuleSetServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = ConversionValueRuleSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ConversionValueRuleSetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ConversionValueRuleSetServiceTransport, + Callable[..., ConversionValueRuleSetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the conversion value rule set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ConversionValueRuleSetServiceTransport,Callable[..., ConversionValueRuleSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ConversionValueRuleSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ConversionValueRuleSetServiceClient._read_environment_variables() + self._client_cert_source = ( + ConversionValueRuleSetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + ConversionValueRuleSetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ConversionValueRuleSetServiceTransport + ) + if transport_provided: + # transport is a ConversionValueRuleSetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + ConversionValueRuleSetServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ConversionValueRuleSetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ConversionValueRuleSetServiceTransport], + Callable[..., ConversionValueRuleSetServiceTransport], + ] = ( + ConversionValueRuleSetServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ConversionValueRuleSetServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ConversionValueRuleSetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ConversionValueRuleSetService", + "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.ads.googleads.v23.services.ConversionValueRuleSetService", + "credentialsType": None, + } + ), + ) + + def mutate_conversion_value_rule_sets( + self, + request: Optional[ + Union[ + conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + conversion_value_rule_set_service.ConversionValueRuleSetOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse + ): + r"""Creates, updates or removes conversion value rule + sets. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateConversionValueRuleSetsRequest, dict]): + The request object. Request message for + [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v23.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. + customer_id (str): + Required. The ID of the customer + whose conversion value rule sets are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.ConversionValueRuleSetOperation]): + Required. The list of operations to + perform on individual conversion value + rule sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateConversionValueRuleSetsResponse: + Response message for + [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v23.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest, + ): + request = conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_conversion_value_rule_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ConversionValueRuleSetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ConversionValueRuleSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/README.rst b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/README.rst rename to google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/__init__.py b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/conversion_value_rule_set_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/base.py b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/base.py new file mode 100644 index 000000000..313219647 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + conversion_value_rule_set_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ConversionValueRuleSetServiceTransport(abc.ABC): + """Abstract transport class for ConversionValueRuleSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_conversion_value_rule_sets: gapic_v1.method.wrap_method( + self.mutate_conversion_value_rule_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_conversion_value_rule_sets( + self, + ) -> Callable[ + [ + conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest + ], + Union[ + conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse, + Awaitable[ + conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ConversionValueRuleSetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/grpc.py b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/grpc.py new file mode 100644 index 000000000..1ef9d605d --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/grpc.py @@ -0,0 +1,391 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + conversion_value_rule_set_service, +) +from .base import ConversionValueRuleSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ConversionValueRuleSetService", + "rpcName": str(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.ads.googleads.v23.services.ConversionValueRuleSetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionValueRuleSetServiceGrpcTransport( + ConversionValueRuleSetServiceTransport +): + """gRPC backend transport for ConversionValueRuleSetService. + + Service to manage conversion value rule sets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_conversion_value_rule_sets( + self, + ) -> Callable[ + [ + conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest + ], + conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse, + ]: + r"""Return a callable for the mutate conversion value rule + sets method over gRPC. + + Creates, updates or removes conversion value rule + sets. Operation statuses are returned. + + Returns: + Callable[[~.MutateConversionValueRuleSetsRequest], + ~.MutateConversionValueRuleSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_value_rule_sets" not in self._stubs: + self._stubs["mutate_conversion_value_rule_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionValueRuleSetService/MutateConversionValueRuleSets", + request_serializer=conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest.serialize, + response_deserializer=conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_conversion_value_rule_sets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ConversionValueRuleSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..86eb86392 --- /dev/null +++ b/google/ads/googleads/v23/services/services/conversion_value_rule_set_service/transports/grpc_asyncio.py @@ -0,0 +1,414 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + conversion_value_rule_set_service, +) +from .base import ConversionValueRuleSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ConversionValueRuleSetService", + "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.ads.googleads.v23.services.ConversionValueRuleSetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ConversionValueRuleSetServiceGrpcAsyncIOTransport( + ConversionValueRuleSetServiceTransport +): + """gRPC AsyncIO backend transport for ConversionValueRuleSetService. + + Service to manage conversion value rule sets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_conversion_value_rule_sets( + self, + ) -> Callable[ + [ + conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest + ], + Awaitable[ + conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse + ], + ]: + r"""Return a callable for the mutate conversion value rule + sets method over gRPC. + + Creates, updates or removes conversion value rule + sets. Operation statuses are returned. + + Returns: + Callable[[~.MutateConversionValueRuleSetsRequest], + Awaitable[~.MutateConversionValueRuleSetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_conversion_value_rule_sets" not in self._stubs: + self._stubs["mutate_conversion_value_rule_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ConversionValueRuleSetService/MutateConversionValueRuleSets", + request_serializer=conversion_value_rule_set_service.MutateConversionValueRuleSetsRequest.serialize, + response_deserializer=conversion_value_rule_set_service.MutateConversionValueRuleSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_conversion_value_rule_sets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_conversion_value_rule_sets: self._wrap_method( + self.mutate_conversion_value_rule_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ConversionValueRuleSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_audience_service/__init__.py b/google/ads/googleads/v23/services/services/custom_audience_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/custom_audience_service/__init__.py rename to google/ads/googleads/v23/services/services/custom_audience_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/custom_audience_service/async_client.py b/google/ads/googleads/v23/services/services/custom_audience_service/async_client.py new file mode 100644 index 000000000..4fe77ca15 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_audience_service/async_client.py @@ -0,0 +1,428 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import custom_audience_service +from .transports.base import CustomAudienceServiceTransport, DEFAULT_CLIENT_INFO +from .client import CustomAudienceServiceClient + +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 CustomAudienceServiceAsyncClient: + """Service to manage custom audiences.""" + + _client: CustomAudienceServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomAudienceServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CustomAudienceServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomAudienceServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomAudienceServiceClient._DEFAULT_UNIVERSE + + custom_audience_path = staticmethod( + CustomAudienceServiceClient.custom_audience_path + ) + parse_custom_audience_path = staticmethod( + CustomAudienceServiceClient.parse_custom_audience_path + ) + common_billing_account_path = staticmethod( + CustomAudienceServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomAudienceServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomAudienceServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomAudienceServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomAudienceServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomAudienceServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomAudienceServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomAudienceServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomAudienceServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomAudienceServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomAudienceServiceAsyncClient: The constructed client. + """ + return CustomAudienceServiceClient.from_service_account_info.__func__(CustomAudienceServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomAudienceServiceAsyncClient: The constructed client. + """ + return CustomAudienceServiceClient.from_service_account_file.__func__(CustomAudienceServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomAudienceServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomAudienceServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomAudienceServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomAudienceServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomAudienceServiceTransport, + Callable[..., CustomAudienceServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the custom audience service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomAudienceServiceTransport,Callable[..., CustomAudienceServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomAudienceServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomAudienceServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomAudienceServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomAudienceService", + "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.ads.googleads.v23.services.CustomAudienceService", + "credentialsType": None, + } + ), + ) + + async def mutate_custom_audiences( + self, + request: Optional[ + Union[custom_audience_service.MutateCustomAudiencesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[custom_audience_service.CustomAudienceOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_audience_service.MutateCustomAudiencesResponse: + r"""Creates or updates custom audiences. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomAudienceError <>`__ + `CustomInterestError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OperationAccessDeniedError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomAudiencesRequest, dict]]): + The request object. Request message for + [CustomAudienceService.MutateCustomAudiences][google.ads.googleads.v23.services.CustomAudienceService.MutateCustomAudiences]. + customer_id (:class:`str`): + Required. The ID of the customer + whose custom audiences are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CustomAudienceOperation]`): + Required. The list of operations to + perform on individual custom audiences. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomAudiencesResponse: + Response message for custom audience + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, custom_audience_service.MutateCustomAudiencesRequest + ): + request = custom_audience_service.MutateCustomAudiencesRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_custom_audiences + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomAudienceServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomAudienceServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/custom_audience_service/client.py b/google/ads/googleads/v23/services/services/custom_audience_service/client.py new file mode 100644 index 000000000..5fc8a0c67 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_audience_service/client.py @@ -0,0 +1,904 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import custom_audience_service +from .transports.base import CustomAudienceServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CustomAudienceServiceGrpcTransport +from .transports.grpc_asyncio import CustomAudienceServiceGrpcAsyncIOTransport + + +class CustomAudienceServiceClientMeta(type): + """Metaclass for the CustomAudienceService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomAudienceServiceTransport]] + _transport_registry["grpc"] = CustomAudienceServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomAudienceServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomAudienceServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomAudienceServiceClient(metaclass=CustomAudienceServiceClientMeta): + """Service to manage custom audiences.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomAudienceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomAudienceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomAudienceServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomAudienceServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def custom_audience_path( + customer_id: str, + custom_audience_id: str, + ) -> str: + """Returns a fully-qualified custom_audience string.""" + return "customers/{customer_id}/customAudiences/{custom_audience_id}".format( + customer_id=customer_id, + custom_audience_id=custom_audience_id, + ) + + @staticmethod + def parse_custom_audience_path(path: str) -> Dict[str, str]: + """Parses a custom_audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customAudiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomAudienceServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomAudienceServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CustomAudienceServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CustomAudienceServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CustomAudienceServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomAudienceServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomAudienceServiceTransport, + Callable[..., CustomAudienceServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the custom audience service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomAudienceServiceTransport,Callable[..., CustomAudienceServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomAudienceServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomAudienceServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomAudienceServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomAudienceServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomAudienceServiceTransport + ) + if transport_provided: + # transport is a CustomAudienceServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CustomAudienceServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomAudienceServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomAudienceServiceTransport], + Callable[..., CustomAudienceServiceTransport], + ] = ( + CustomAudienceServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomAudienceServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomAudienceServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomAudienceService", + "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.ads.googleads.v23.services.CustomAudienceService", + "credentialsType": None, + } + ), + ) + + def mutate_custom_audiences( + self, + request: Optional[ + Union[custom_audience_service.MutateCustomAudiencesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[custom_audience_service.CustomAudienceOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_audience_service.MutateCustomAudiencesResponse: + r"""Creates or updates custom audiences. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomAudienceError <>`__ + `CustomInterestError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OperationAccessDeniedError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomAudiencesRequest, dict]): + The request object. Request message for + [CustomAudienceService.MutateCustomAudiences][google.ads.googleads.v23.services.CustomAudienceService.MutateCustomAudiences]. + customer_id (str): + Required. The ID of the customer + whose custom audiences are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomAudienceOperation]): + Required. The list of operations to + perform on individual custom audiences. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomAudiencesResponse: + Response message for custom audience + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, custom_audience_service.MutateCustomAudiencesRequest + ): + request = custom_audience_service.MutateCustomAudiencesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_custom_audiences + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomAudienceServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomAudienceServiceClient",) diff --git a/google/ads/googleads/v19/services/services/custom_audience_service/transports/README.rst b/google/ads/googleads/v23/services/services/custom_audience_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/custom_audience_service/transports/README.rst rename to google/ads/googleads/v23/services/services/custom_audience_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/custom_audience_service/transports/__init__.py b/google/ads/googleads/v23/services/services/custom_audience_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/custom_audience_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/custom_audience_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/custom_audience_service/transports/base.py b/google/ads/googleads/v23/services/services/custom_audience_service/transports/base.py new file mode 100644 index 000000000..4ea712d17 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_audience_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import custom_audience_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomAudienceServiceTransport(abc.ABC): + """Abstract transport class for CustomAudienceService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_custom_audiences: gapic_v1.method.wrap_method( + self.mutate_custom_audiences, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_custom_audiences( + self, + ) -> Callable[ + [custom_audience_service.MutateCustomAudiencesRequest], + Union[ + custom_audience_service.MutateCustomAudiencesResponse, + Awaitable[custom_audience_service.MutateCustomAudiencesResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomAudienceServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/custom_audience_service/transports/grpc.py b/google/ads/googleads/v23/services/services/custom_audience_service/transports/grpc.py new file mode 100644 index 000000000..252fb3faf --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_audience_service/transports/grpc.py @@ -0,0 +1,392 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import custom_audience_service +from .base import CustomAudienceServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomAudienceService", + "rpcName": str(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.ads.googleads.v23.services.CustomAudienceService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomAudienceServiceGrpcTransport(CustomAudienceServiceTransport): + """gRPC backend transport for CustomAudienceService. + + Service to manage custom audiences. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_custom_audiences( + self, + ) -> Callable[ + [custom_audience_service.MutateCustomAudiencesRequest], + custom_audience_service.MutateCustomAudiencesResponse, + ]: + r"""Return a callable for the mutate custom audiences method over gRPC. + + Creates or updates custom audiences. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomAudienceError <>`__ + `CustomInterestError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OperationAccessDeniedError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomAudiencesRequest], + ~.MutateCustomAudiencesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_custom_audiences" not in self._stubs: + self._stubs["mutate_custom_audiences"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomAudienceService/MutateCustomAudiences", + request_serializer=custom_audience_service.MutateCustomAudiencesRequest.serialize, + response_deserializer=custom_audience_service.MutateCustomAudiencesResponse.deserialize, + ) + ) + return self._stubs["mutate_custom_audiences"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomAudienceServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/custom_audience_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/custom_audience_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..a2cae6f7b --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_audience_service/transports/grpc_asyncio.py @@ -0,0 +1,413 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import custom_audience_service +from .base import CustomAudienceServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomAudienceService", + "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.ads.googleads.v23.services.CustomAudienceService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomAudienceServiceGrpcAsyncIOTransport(CustomAudienceServiceTransport): + """gRPC AsyncIO backend transport for CustomAudienceService. + + Service to manage custom audiences. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_custom_audiences( + self, + ) -> Callable[ + [custom_audience_service.MutateCustomAudiencesRequest], + Awaitable[custom_audience_service.MutateCustomAudiencesResponse], + ]: + r"""Return a callable for the mutate custom audiences method over gRPC. + + Creates or updates custom audiences. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomAudienceError <>`__ + `CustomInterestError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OperationAccessDeniedError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomAudiencesRequest], + Awaitable[~.MutateCustomAudiencesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_custom_audiences" not in self._stubs: + self._stubs["mutate_custom_audiences"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomAudienceService/MutateCustomAudiences", + request_serializer=custom_audience_service.MutateCustomAudiencesRequest.serialize, + response_deserializer=custom_audience_service.MutateCustomAudiencesResponse.deserialize, + ) + ) + return self._stubs["mutate_custom_audiences"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_custom_audiences: self._wrap_method( + self.mutate_custom_audiences, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomAudienceServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/__init__.py b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/custom_conversion_goal_service/__init__.py rename to google/ads/googleads/v23/services/services/custom_conversion_goal_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/custom_conversion_goal_service/async_client.py b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/async_client.py new file mode 100644 index 000000000..5ba347017 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/async_client.py @@ -0,0 +1,440 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + custom_conversion_goal_service, +) +from .transports.base import ( + CustomConversionGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomConversionGoalServiceClient + +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 CustomConversionGoalServiceAsyncClient: + """Service to manage custom conversion goal.""" + + _client: CustomConversionGoalServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomConversionGoalServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CustomConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomConversionGoalServiceClient._DEFAULT_UNIVERSE + + conversion_action_path = staticmethod( + CustomConversionGoalServiceClient.conversion_action_path + ) + parse_conversion_action_path = staticmethod( + CustomConversionGoalServiceClient.parse_conversion_action_path + ) + custom_conversion_goal_path = staticmethod( + CustomConversionGoalServiceClient.custom_conversion_goal_path + ) + parse_custom_conversion_goal_path = staticmethod( + CustomConversionGoalServiceClient.parse_custom_conversion_goal_path + ) + common_billing_account_path = staticmethod( + CustomConversionGoalServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomConversionGoalServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomConversionGoalServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomConversionGoalServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomConversionGoalServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomConversionGoalServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomConversionGoalServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomConversionGoalServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomConversionGoalServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomConversionGoalServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomConversionGoalServiceAsyncClient: The constructed client. + """ + return CustomConversionGoalServiceClient.from_service_account_info.__func__(CustomConversionGoalServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomConversionGoalServiceAsyncClient: The constructed client. + """ + return CustomConversionGoalServiceClient.from_service_account_file.__func__(CustomConversionGoalServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomConversionGoalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomConversionGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomConversionGoalServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomConversionGoalServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomConversionGoalServiceTransport, + Callable[..., CustomConversionGoalServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the custom conversion goal service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomConversionGoalServiceTransport,Callable[..., CustomConversionGoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomConversionGoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomConversionGoalServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomConversionGoalServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomConversionGoalService", + "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.ads.googleads.v23.services.CustomConversionGoalService", + "credentialsType": None, + } + ), + ) + + async def mutate_custom_conversion_goals( + self, + request: Optional[ + Union[ + custom_conversion_goal_service.MutateCustomConversionGoalsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + custom_conversion_goal_service.CustomConversionGoalOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_conversion_goal_service.MutateCustomConversionGoalsResponse: + r"""Creates, updates or removes custom conversion goals. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomConversionGoalsRequest, dict]]): + The request object. Request message for + [CustomConversionGoalService.MutateCustomConversionGoals][google.ads.googleads.v23.services.CustomConversionGoalService.MutateCustomConversionGoals]. + customer_id (:class:`str`): + Required. The ID of the customer + whose custom conversion goals are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CustomConversionGoalOperation]`): + Required. The list of operations to + perform on individual custom conversion + goal. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomConversionGoalsResponse: + Response message for a custom + conversion goal mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + custom_conversion_goal_service.MutateCustomConversionGoalsRequest, + ): + request = custom_conversion_goal_service.MutateCustomConversionGoalsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_custom_conversion_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomConversionGoalServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomConversionGoalServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/custom_conversion_goal_service/client.py b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/client.py new file mode 100644 index 000000000..b789adde8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/client.py @@ -0,0 +1,937 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + custom_conversion_goal_service, +) +from .transports.base import ( + CustomConversionGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomConversionGoalServiceGrpcTransport +from .transports.grpc_asyncio import ( + CustomConversionGoalServiceGrpcAsyncIOTransport, +) + + +class CustomConversionGoalServiceClientMeta(type): + """Metaclass for the CustomConversionGoalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomConversionGoalServiceTransport]] + _transport_registry["grpc"] = CustomConversionGoalServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomConversionGoalServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomConversionGoalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomConversionGoalServiceClient( + metaclass=CustomConversionGoalServiceClientMeta +): + """Service to manage custom conversion goal.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomConversionGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomConversionGoalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def conversion_action_path( + customer_id: str, + conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, + conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def custom_conversion_goal_path( + customer_id: str, + goal_id: str, + ) -> str: + """Returns a fully-qualified custom_conversion_goal string.""" + return "customers/{customer_id}/customConversionGoals/{goal_id}".format( + customer_id=customer_id, + goal_id=goal_id, + ) + + @staticmethod + def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a custom_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomConversionGoalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomConversionGoalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CustomConversionGoalServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + CustomConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = CustomConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomConversionGoalServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomConversionGoalServiceTransport, + Callable[..., CustomConversionGoalServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the custom conversion goal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomConversionGoalServiceTransport,Callable[..., CustomConversionGoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomConversionGoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomConversionGoalServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomConversionGoalServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomConversionGoalServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomConversionGoalServiceTransport + ) + if transport_provided: + # transport is a CustomConversionGoalServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CustomConversionGoalServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomConversionGoalServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomConversionGoalServiceTransport], + Callable[..., CustomConversionGoalServiceTransport], + ] = ( + CustomConversionGoalServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomConversionGoalServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomConversionGoalServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomConversionGoalService", + "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.ads.googleads.v23.services.CustomConversionGoalService", + "credentialsType": None, + } + ), + ) + + def mutate_custom_conversion_goals( + self, + request: Optional[ + Union[ + custom_conversion_goal_service.MutateCustomConversionGoalsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + custom_conversion_goal_service.CustomConversionGoalOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_conversion_goal_service.MutateCustomConversionGoalsResponse: + r"""Creates, updates or removes custom conversion goals. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomConversionGoalsRequest, dict]): + The request object. Request message for + [CustomConversionGoalService.MutateCustomConversionGoals][google.ads.googleads.v23.services.CustomConversionGoalService.MutateCustomConversionGoals]. + customer_id (str): + Required. The ID of the customer + whose custom conversion goals are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomConversionGoalOperation]): + Required. The list of operations to + perform on individual custom conversion + goal. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomConversionGoalsResponse: + Response message for a custom + conversion goal mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + custom_conversion_goal_service.MutateCustomConversionGoalsRequest, + ): + request = custom_conversion_goal_service.MutateCustomConversionGoalsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_custom_conversion_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomConversionGoalServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomConversionGoalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/README.rst b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/README.rst rename to google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/__init__.py b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/custom_conversion_goal_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/base.py b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/base.py new file mode 100644 index 000000000..05b6c2df5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + custom_conversion_goal_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomConversionGoalServiceTransport(abc.ABC): + """Abstract transport class for CustomConversionGoalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_custom_conversion_goals: gapic_v1.method.wrap_method( + self.mutate_custom_conversion_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_custom_conversion_goals( + self, + ) -> Callable[ + [custom_conversion_goal_service.MutateCustomConversionGoalsRequest], + Union[ + custom_conversion_goal_service.MutateCustomConversionGoalsResponse, + Awaitable[ + custom_conversion_goal_service.MutateCustomConversionGoalsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomConversionGoalServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/grpc.py b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/grpc.py new file mode 100644 index 000000000..b2ccf7139 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/grpc.py @@ -0,0 +1,388 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + custom_conversion_goal_service, +) +from .base import CustomConversionGoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomConversionGoalService", + "rpcName": str(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.ads.googleads.v23.services.CustomConversionGoalService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomConversionGoalServiceGrpcTransport( + CustomConversionGoalServiceTransport +): + """gRPC backend transport for CustomConversionGoalService. + + Service to manage custom conversion goal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_custom_conversion_goals( + self, + ) -> Callable[ + [custom_conversion_goal_service.MutateCustomConversionGoalsRequest], + custom_conversion_goal_service.MutateCustomConversionGoalsResponse, + ]: + r"""Return a callable for the mutate custom conversion goals method over gRPC. + + Creates, updates or removes custom conversion goals. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomConversionGoalsRequest], + ~.MutateCustomConversionGoalsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_custom_conversion_goals" not in self._stubs: + self._stubs["mutate_custom_conversion_goals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomConversionGoalService/MutateCustomConversionGoals", + request_serializer=custom_conversion_goal_service.MutateCustomConversionGoalsRequest.serialize, + response_deserializer=custom_conversion_goal_service.MutateCustomConversionGoalsResponse.deserialize, + ) + ) + return self._stubs["mutate_custom_conversion_goals"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomConversionGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..f60a33410 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_conversion_goal_service/transports/grpc_asyncio.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + custom_conversion_goal_service, +) +from .base import CustomConversionGoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomConversionGoalService", + "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.ads.googleads.v23.services.CustomConversionGoalService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomConversionGoalServiceGrpcAsyncIOTransport( + CustomConversionGoalServiceTransport +): + """gRPC AsyncIO backend transport for CustomConversionGoalService. + + Service to manage custom conversion goal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_custom_conversion_goals( + self, + ) -> Callable[ + [custom_conversion_goal_service.MutateCustomConversionGoalsRequest], + Awaitable[ + custom_conversion_goal_service.MutateCustomConversionGoalsResponse + ], + ]: + r"""Return a callable for the mutate custom conversion goals method over gRPC. + + Creates, updates or removes custom conversion goals. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomConversionGoalsRequest], + Awaitable[~.MutateCustomConversionGoalsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_custom_conversion_goals" not in self._stubs: + self._stubs["mutate_custom_conversion_goals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomConversionGoalService/MutateCustomConversionGoals", + request_serializer=custom_conversion_goal_service.MutateCustomConversionGoalsRequest.serialize, + response_deserializer=custom_conversion_goal_service.MutateCustomConversionGoalsResponse.deserialize, + ) + ) + return self._stubs["mutate_custom_conversion_goals"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_custom_conversion_goals: self._wrap_method( + self.mutate_custom_conversion_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomConversionGoalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/custom_interest_service/__init__.py b/google/ads/googleads/v23/services/services/custom_interest_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/custom_interest_service/__init__.py rename to google/ads/googleads/v23/services/services/custom_interest_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/custom_interest_service/async_client.py b/google/ads/googleads/v23/services/services/custom_interest_service/async_client.py new file mode 100644 index 000000000..6db7bdc39 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_interest_service/async_client.py @@ -0,0 +1,427 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import custom_interest_service +from .transports.base import CustomInterestServiceTransport, DEFAULT_CLIENT_INFO +from .client import CustomInterestServiceClient + +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 CustomInterestServiceAsyncClient: + """Service to manage custom interests.""" + + _client: CustomInterestServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomInterestServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CustomInterestServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomInterestServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomInterestServiceClient._DEFAULT_UNIVERSE + + custom_interest_path = staticmethod( + CustomInterestServiceClient.custom_interest_path + ) + parse_custom_interest_path = staticmethod( + CustomInterestServiceClient.parse_custom_interest_path + ) + common_billing_account_path = staticmethod( + CustomInterestServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomInterestServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomInterestServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomInterestServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomInterestServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomInterestServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomInterestServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomInterestServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomInterestServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomInterestServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomInterestServiceAsyncClient: The constructed client. + """ + return CustomInterestServiceClient.from_service_account_info.__func__(CustomInterestServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomInterestServiceAsyncClient: The constructed client. + """ + return CustomInterestServiceClient.from_service_account_file.__func__(CustomInterestServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomInterestServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomInterestServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomInterestServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomInterestServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomInterestServiceTransport, + Callable[..., CustomInterestServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the custom interest service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomInterestServiceTransport,Callable[..., CustomInterestServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomInterestServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomInterestServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomInterestServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomInterestService", + "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.ads.googleads.v23.services.CustomInterestService", + "credentialsType": None, + } + ), + ) + + async def mutate_custom_interests( + self, + request: Optional[ + Union[custom_interest_service.MutateCustomInterestsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[custom_interest_service.CustomInterestOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_interest_service.MutateCustomInterestsResponse: + r"""Creates or updates custom interests. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `CustomInterestError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomInterestsRequest, dict]]): + The request object. Request message for + [CustomInterestService.MutateCustomInterests][google.ads.googleads.v23.services.CustomInterestService.MutateCustomInterests]. + customer_id (:class:`str`): + Required. The ID of the customer + whose custom interests are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CustomInterestOperation]`): + Required. The list of operations to + perform on individual custom interests. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomInterestsResponse: + Response message for custom interest + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, custom_interest_service.MutateCustomInterestsRequest + ): + request = custom_interest_service.MutateCustomInterestsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_custom_interests + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomInterestServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomInterestServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/custom_interest_service/client.py b/google/ads/googleads/v23/services/services/custom_interest_service/client.py new file mode 100644 index 000000000..b2aa2ad14 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_interest_service/client.py @@ -0,0 +1,903 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import custom_interest_service +from .transports.base import CustomInterestServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CustomInterestServiceGrpcTransport +from .transports.grpc_asyncio import CustomInterestServiceGrpcAsyncIOTransport + + +class CustomInterestServiceClientMeta(type): + """Metaclass for the CustomInterestService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomInterestServiceTransport]] + _transport_registry["grpc"] = CustomInterestServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomInterestServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomInterestServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomInterestServiceClient(metaclass=CustomInterestServiceClientMeta): + """Service to manage custom interests.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomInterestServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomInterestServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomInterestServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomInterestServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def custom_interest_path( + customer_id: str, + custom_interest_id: str, + ) -> str: + """Returns a fully-qualified custom_interest string.""" + return "customers/{customer_id}/customInterests/{custom_interest_id}".format( + customer_id=customer_id, + custom_interest_id=custom_interest_id, + ) + + @staticmethod + def parse_custom_interest_path(path: str) -> Dict[str, str]: + """Parses a custom_interest path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customInterests/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomInterestServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomInterestServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CustomInterestServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CustomInterestServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CustomInterestServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomInterestServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomInterestServiceTransport, + Callable[..., CustomInterestServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the custom interest service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomInterestServiceTransport,Callable[..., CustomInterestServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomInterestServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomInterestServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomInterestServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomInterestServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomInterestServiceTransport + ) + if transport_provided: + # transport is a CustomInterestServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CustomInterestServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomInterestServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomInterestServiceTransport], + Callable[..., CustomInterestServiceTransport], + ] = ( + CustomInterestServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomInterestServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomInterestServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomInterestService", + "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.ads.googleads.v23.services.CustomInterestService", + "credentialsType": None, + } + ), + ) + + def mutate_custom_interests( + self, + request: Optional[ + Union[custom_interest_service.MutateCustomInterestsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[custom_interest_service.CustomInterestOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> custom_interest_service.MutateCustomInterestsResponse: + r"""Creates or updates custom interests. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `CustomInterestError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomInterestsRequest, dict]): + The request object. Request message for + [CustomInterestService.MutateCustomInterests][google.ads.googleads.v23.services.CustomInterestService.MutateCustomInterests]. + customer_id (str): + Required. The ID of the customer + whose custom interests are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomInterestOperation]): + Required. The list of operations to + perform on individual custom interests. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomInterestsResponse: + Response message for custom interest + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, custom_interest_service.MutateCustomInterestsRequest + ): + request = custom_interest_service.MutateCustomInterestsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_custom_interests + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomInterestServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomInterestServiceClient",) diff --git a/google/ads/googleads/v19/services/services/custom_interest_service/transports/README.rst b/google/ads/googleads/v23/services/services/custom_interest_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/custom_interest_service/transports/README.rst rename to google/ads/googleads/v23/services/services/custom_interest_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/custom_interest_service/transports/__init__.py b/google/ads/googleads/v23/services/services/custom_interest_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/custom_interest_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/custom_interest_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/custom_interest_service/transports/base.py b/google/ads/googleads/v23/services/services/custom_interest_service/transports/base.py new file mode 100644 index 000000000..b8ce38964 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_interest_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import custom_interest_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomInterestServiceTransport(abc.ABC): + """Abstract transport class for CustomInterestService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_custom_interests: gapic_v1.method.wrap_method( + self.mutate_custom_interests, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_custom_interests( + self, + ) -> Callable[ + [custom_interest_service.MutateCustomInterestsRequest], + Union[ + custom_interest_service.MutateCustomInterestsResponse, + Awaitable[custom_interest_service.MutateCustomInterestsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomInterestServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/custom_interest_service/transports/grpc.py b/google/ads/googleads/v23/services/services/custom_interest_service/transports/grpc.py new file mode 100644 index 000000000..3d8891592 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_interest_service/transports/grpc.py @@ -0,0 +1,391 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import custom_interest_service +from .base import CustomInterestServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomInterestService", + "rpcName": str(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.ads.googleads.v23.services.CustomInterestService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomInterestServiceGrpcTransport(CustomInterestServiceTransport): + """gRPC backend transport for CustomInterestService. + + Service to manage custom interests. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_custom_interests( + self, + ) -> Callable[ + [custom_interest_service.MutateCustomInterestsRequest], + custom_interest_service.MutateCustomInterestsResponse, + ]: + r"""Return a callable for the mutate custom interests method over gRPC. + + Creates or updates custom interests. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `CustomInterestError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCustomInterestsRequest], + ~.MutateCustomInterestsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_custom_interests" not in self._stubs: + self._stubs["mutate_custom_interests"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomInterestService/MutateCustomInterests", + request_serializer=custom_interest_service.MutateCustomInterestsRequest.serialize, + response_deserializer=custom_interest_service.MutateCustomInterestsResponse.deserialize, + ) + ) + return self._stubs["mutate_custom_interests"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomInterestServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/custom_interest_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/custom_interest_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..ffb4786a1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/custom_interest_service/transports/grpc_asyncio.py @@ -0,0 +1,412 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import custom_interest_service +from .base import CustomInterestServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomInterestService", + "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.ads.googleads.v23.services.CustomInterestService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomInterestServiceGrpcAsyncIOTransport(CustomInterestServiceTransport): + """gRPC AsyncIO backend transport for CustomInterestService. + + Service to manage custom interests. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_custom_interests( + self, + ) -> Callable[ + [custom_interest_service.MutateCustomInterestsRequest], + Awaitable[custom_interest_service.MutateCustomInterestsResponse], + ]: + r"""Return a callable for the mutate custom interests method over gRPC. + + Creates or updates custom interests. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `CustomInterestError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ + `RequestError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateCustomInterestsRequest], + Awaitable[~.MutateCustomInterestsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_custom_interests" not in self._stubs: + self._stubs["mutate_custom_interests"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomInterestService/MutateCustomInterests", + request_serializer=custom_interest_service.MutateCustomInterestsRequest.serialize, + response_deserializer=custom_interest_service.MutateCustomInterestsResponse.deserialize, + ) + ) + return self._stubs["mutate_custom_interests"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_custom_interests: self._wrap_method( + self.mutate_custom_interests, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomInterestServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_service/__init__.py b/google/ads/googleads/v23/services/services/customer_asset_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_asset_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_asset_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_asset_service/async_client.py b/google/ads/googleads/v23/services/services/customer_asset_service/async_client.py new file mode 100644 index 000000000..086f5e796 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_asset_service/async_client.py @@ -0,0 +1,428 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import customer_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CustomerAssetServiceTransport, DEFAULT_CLIENT_INFO +from .client import CustomerAssetServiceClient + +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 CustomerAssetServiceAsyncClient: + """Service to manage customer assets.""" + + _client: CustomerAssetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomerAssetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CustomerAssetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomerAssetServiceClient._DEFAULT_UNIVERSE + + asset_path = staticmethod(CustomerAssetServiceClient.asset_path) + parse_asset_path = staticmethod(CustomerAssetServiceClient.parse_asset_path) + customer_asset_path = staticmethod( + CustomerAssetServiceClient.customer_asset_path + ) + parse_customer_asset_path = staticmethod( + CustomerAssetServiceClient.parse_customer_asset_path + ) + common_billing_account_path = staticmethod( + CustomerAssetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerAssetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerAssetServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerAssetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerAssetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerAssetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerAssetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerAssetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerAssetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerAssetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetServiceAsyncClient: The constructed client. + """ + return CustomerAssetServiceClient.from_service_account_info.__func__(CustomerAssetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetServiceAsyncClient: The constructed client. + """ + return CustomerAssetServiceClient.from_service_account_file.__func__(CustomerAssetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerAssetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerAssetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomerAssetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerAssetServiceTransport, + Callable[..., CustomerAssetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer asset service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerAssetServiceTransport,Callable[..., CustomerAssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerAssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerAssetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerAssetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerAssetService", + "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.ads.googleads.v23.services.CustomerAssetService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer_assets( + self, + request: Optional[ + Union[customer_asset_service.MutateCustomerAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[customer_asset_service.CustomerAssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_asset_service.MutateCustomerAssetsResponse: + r"""Creates, updates, or removes customer assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerAssetsRequest, dict]]): + The request object. Request message for + [CustomerAssetService.MutateCustomerAssets][google.ads.googleads.v23.services.CustomerAssetService.MutateCustomerAssets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose customer assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CustomerAssetOperation]`): + Required. The list of operations to + perform on individual customer assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerAssetsResponse: + Response message for a customer asset + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_asset_service.MutateCustomerAssetsRequest + ): + request = customer_asset_service.MutateCustomerAssetsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomerAssetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerAssetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_asset_service/client.py b/google/ads/googleads/v23/services/services/customer_asset_service/client.py new file mode 100644 index 000000000..779ac7129 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_asset_service/client.py @@ -0,0 +1,921 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import customer_asset_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CustomerAssetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CustomerAssetServiceGrpcTransport +from .transports.grpc_asyncio import CustomerAssetServiceGrpcAsyncIOTransport + + +class CustomerAssetServiceClientMeta(type): + """Metaclass for the CustomerAssetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerAssetServiceTransport]] + _transport_registry["grpc"] = CustomerAssetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomerAssetServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerAssetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerAssetServiceClient(metaclass=CustomerAssetServiceClientMeta): + """Service to manage customer assets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerAssetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerAssetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_path( + customer_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_asset_path( + customer_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified customer_asset string.""" + return "customers/{customer_id}/customerAssets/{asset_id}~{field_type}".format( + customer_id=customer_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_customer_asset_path(path: str) -> Dict[str, str]: + """Parses a customer_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerAssetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerAssetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CustomerAssetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CustomerAssetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CustomerAssetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomerAssetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerAssetServiceTransport, + Callable[..., CustomerAssetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer asset service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerAssetServiceTransport,Callable[..., CustomerAssetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerAssetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomerAssetServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomerAssetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = CustomerAssetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerAssetServiceTransport + ) + if transport_provided: + # transport is a CustomerAssetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CustomerAssetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerAssetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerAssetServiceTransport], + Callable[..., CustomerAssetServiceTransport], + ] = ( + CustomerAssetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomerAssetServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerAssetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerAssetService", + "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.ads.googleads.v23.services.CustomerAssetService", + "credentialsType": None, + } + ), + ) + + def mutate_customer_assets( + self, + request: Optional[ + Union[customer_asset_service.MutateCustomerAssetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[customer_asset_service.CustomerAssetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_asset_service.MutateCustomerAssetsResponse: + r"""Creates, updates, or removes customer assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerAssetsRequest, dict]): + The request object. Request message for + [CustomerAssetService.MutateCustomerAssets][google.ads.googleads.v23.services.CustomerAssetService.MutateCustomerAssets]. + customer_id (str): + Required. The ID of the customer + whose customer assets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerAssetOperation]): + Required. The list of operations to + perform on individual customer assets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerAssetsResponse: + Response message for a customer asset + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_asset_service.MutateCustomerAssetsRequest + ): + request = customer_asset_service.MutateCustomerAssetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerAssetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerAssetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_asset_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_asset_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_asset_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_asset_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_asset_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_asset_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_asset_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_asset_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_asset_service/transports/base.py new file mode 100644 index 000000000..d97839e7f --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_asset_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import customer_asset_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerAssetServiceTransport(abc.ABC): + """Abstract transport class for CustomerAssetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_assets: gapic_v1.method.wrap_method( + self.mutate_customer_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_assets( + self, + ) -> Callable[ + [customer_asset_service.MutateCustomerAssetsRequest], + Union[ + customer_asset_service.MutateCustomerAssetsResponse, + Awaitable[customer_asset_service.MutateCustomerAssetsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerAssetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_asset_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_asset_service/transports/grpc.py new file mode 100644 index 000000000..4e46cb0ed --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_asset_service/transports/grpc.py @@ -0,0 +1,389 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import customer_asset_service +from .base import CustomerAssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerAssetService", + "rpcName": str(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.ads.googleads.v23.services.CustomerAssetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerAssetServiceGrpcTransport(CustomerAssetServiceTransport): + """gRPC backend transport for CustomerAssetService. + + Service to manage customer assets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer_assets( + self, + ) -> Callable[ + [customer_asset_service.MutateCustomerAssetsRequest], + customer_asset_service.MutateCustomerAssetsResponse, + ]: + r"""Return a callable for the mutate customer assets method over gRPC. + + Creates, updates, or removes customer assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerAssetsRequest], + ~.MutateCustomerAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_assets" not in self._stubs: + self._stubs["mutate_customer_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerAssetService/MutateCustomerAssets", + request_serializer=customer_asset_service.MutateCustomerAssetsRequest.serialize, + response_deserializer=customer_asset_service.MutateCustomerAssetsResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_assets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerAssetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_asset_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_asset_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..fa6d6e3c9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_asset_service/transports/grpc_asyncio.py @@ -0,0 +1,410 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import customer_asset_service +from .base import CustomerAssetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerAssetService", + "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.ads.googleads.v23.services.CustomerAssetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerAssetServiceGrpcAsyncIOTransport(CustomerAssetServiceTransport): + """gRPC AsyncIO backend transport for CustomerAssetService. + + Service to manage customer assets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer_assets( + self, + ) -> Callable[ + [customer_asset_service.MutateCustomerAssetsRequest], + Awaitable[customer_asset_service.MutateCustomerAssetsResponse], + ]: + r"""Return a callable for the mutate customer assets method over gRPC. + + Creates, updates, or removes customer assets. Operation statuses + are returned. + + List of thrown errors: `AssetLinkError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerAssetsRequest], + Awaitable[~.MutateCustomerAssetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_assets" not in self._stubs: + self._stubs["mutate_customer_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerAssetService/MutateCustomerAssets", + request_serializer=customer_asset_service.MutateCustomerAssetsRequest.serialize, + response_deserializer=customer_asset_service.MutateCustomerAssetsResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_assets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer_assets: self._wrap_method( + self.mutate_customer_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerAssetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_set_service/__init__.py b/google/ads/googleads/v23/services/services/customer_asset_set_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_asset_set_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_asset_set_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_asset_set_service/async_client.py b/google/ads/googleads/v23/services/services/customer_asset_set_service/async_client.py new file mode 100644 index 000000000..3e68cd157 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_asset_set_service/async_client.py @@ -0,0 +1,437 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import customer_asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerAssetSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomerAssetSetServiceClient + +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 CustomerAssetSetServiceAsyncClient: + """Service to manage customer asset set""" + + _client: CustomerAssetSetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomerAssetSetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CustomerAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomerAssetSetServiceClient._DEFAULT_UNIVERSE + + asset_set_path = staticmethod(CustomerAssetSetServiceClient.asset_set_path) + parse_asset_set_path = staticmethod( + CustomerAssetSetServiceClient.parse_asset_set_path + ) + customer_path = staticmethod(CustomerAssetSetServiceClient.customer_path) + parse_customer_path = staticmethod( + CustomerAssetSetServiceClient.parse_customer_path + ) + customer_asset_set_path = staticmethod( + CustomerAssetSetServiceClient.customer_asset_set_path + ) + parse_customer_asset_set_path = staticmethod( + CustomerAssetSetServiceClient.parse_customer_asset_set_path + ) + common_billing_account_path = staticmethod( + CustomerAssetSetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerAssetSetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerAssetSetServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerAssetSetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerAssetSetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerAssetSetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerAssetSetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerAssetSetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerAssetSetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerAssetSetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetSetServiceAsyncClient: The constructed client. + """ + return CustomerAssetSetServiceClient.from_service_account_info.__func__(CustomerAssetSetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetSetServiceAsyncClient: The constructed client. + """ + return CustomerAssetSetServiceClient.from_service_account_file.__func__(CustomerAssetSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerAssetSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerAssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerAssetSetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomerAssetSetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerAssetSetServiceTransport, + Callable[..., CustomerAssetSetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer asset set service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerAssetSetServiceTransport,Callable[..., CustomerAssetSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerAssetSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerAssetSetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerAssetSetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerAssetSetService", + "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.ads.googleads.v23.services.CustomerAssetSetService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer_asset_sets( + self, + request: Optional[ + Union[ + customer_asset_set_service.MutateCustomerAssetSetsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customer_asset_set_service.CustomerAssetSetOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_asset_set_service.MutateCustomerAssetSetsResponse: + r"""Creates, or removes customer asset sets. Operation + statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerAssetSetsRequest, dict]]): + The request object. Request message for + [CustomerAssetSetService.MutateCustomerAssetSets][google.ads.googleads.v23.services.CustomerAssetSetService.MutateCustomerAssetSets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose customer asset sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CustomerAssetSetOperation]`): + Required. The list of operations to + perform on individual customer asset + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerAssetSetsResponse: + Response message for a customer asset + set mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_asset_set_service.MutateCustomerAssetSetsRequest + ): + request = customer_asset_set_service.MutateCustomerAssetSetsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomerAssetSetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerAssetSetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_asset_set_service/client.py b/google/ads/googleads/v23/services/services/customer_asset_set_service/client.py new file mode 100644 index 000000000..f9658017d --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_asset_set_service/client.py @@ -0,0 +1,944 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import customer_asset_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerAssetSetServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerAssetSetServiceGrpcTransport +from .transports.grpc_asyncio import CustomerAssetSetServiceGrpcAsyncIOTransport + + +class CustomerAssetSetServiceClientMeta(type): + """Metaclass for the CustomerAssetSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerAssetSetServiceTransport]] + _transport_registry["grpc"] = CustomerAssetSetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomerAssetSetServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerAssetSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerAssetSetServiceClient( + metaclass=CustomerAssetSetServiceClientMeta +): + """Service to manage customer asset set""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerAssetSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerAssetSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerAssetSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def asset_set_path( + customer_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_asset_set_path( + customer_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified customer_asset_set string.""" + return ( + "customers/{customer_id}/customerAssetSets/{asset_set_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + ) + ) + + @staticmethod + def parse_customer_asset_set_path(path: str) -> Dict[str, str]: + """Parses a customer_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerAssetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerAssetSetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerAssetSetServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CustomerAssetSetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CustomerAssetSetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CustomerAssetSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomerAssetSetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerAssetSetServiceTransport, + Callable[..., CustomerAssetSetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer asset set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerAssetSetServiceTransport,Callable[..., CustomerAssetSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerAssetSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomerAssetSetServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomerAssetSetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomerAssetSetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerAssetSetServiceTransport + ) + if transport_provided: + # transport is a CustomerAssetSetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CustomerAssetSetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerAssetSetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerAssetSetServiceTransport], + Callable[..., CustomerAssetSetServiceTransport], + ] = ( + CustomerAssetSetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomerAssetSetServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerAssetSetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerAssetSetService", + "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.ads.googleads.v23.services.CustomerAssetSetService", + "credentialsType": None, + } + ), + ) + + def mutate_customer_asset_sets( + self, + request: Optional[ + Union[ + customer_asset_set_service.MutateCustomerAssetSetsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customer_asset_set_service.CustomerAssetSetOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_asset_set_service.MutateCustomerAssetSetsResponse: + r"""Creates, or removes customer asset sets. Operation + statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerAssetSetsRequest, dict]): + The request object. Request message for + [CustomerAssetSetService.MutateCustomerAssetSets][google.ads.googleads.v23.services.CustomerAssetSetService.MutateCustomerAssetSets]. + customer_id (str): + Required. The ID of the customer + whose customer asset sets are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerAssetSetOperation]): + Required. The list of operations to + perform on individual customer asset + sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerAssetSetsResponse: + Response message for a customer asset + set mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_asset_set_service.MutateCustomerAssetSetsRequest + ): + request = customer_asset_set_service.MutateCustomerAssetSetsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_asset_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerAssetSetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerAssetSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_asset_set_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_asset_set_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_asset_set_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_asset_set_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_asset_set_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_asset_set_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_asset_set_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_asset_set_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_asset_set_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_asset_set_service/transports/base.py new file mode 100644 index 000000000..1eed502f9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_asset_set_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import customer_asset_set_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerAssetSetServiceTransport(abc.ABC): + """Abstract transport class for CustomerAssetSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_asset_sets: gapic_v1.method.wrap_method( + self.mutate_customer_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_asset_sets( + self, + ) -> Callable[ + [customer_asset_set_service.MutateCustomerAssetSetsRequest], + Union[ + customer_asset_set_service.MutateCustomerAssetSetsResponse, + Awaitable[ + customer_asset_set_service.MutateCustomerAssetSetsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerAssetSetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_asset_set_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_asset_set_service/transports/grpc.py new file mode 100644 index 000000000..6ae99ded1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_asset_set_service/transports/grpc.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import customer_asset_set_service +from .base import CustomerAssetSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerAssetSetService", + "rpcName": str(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.ads.googleads.v23.services.CustomerAssetSetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerAssetSetServiceGrpcTransport(CustomerAssetSetServiceTransport): + """gRPC backend transport for CustomerAssetSetService. + + Service to manage customer asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer_asset_sets( + self, + ) -> Callable[ + [customer_asset_set_service.MutateCustomerAssetSetsRequest], + customer_asset_set_service.MutateCustomerAssetSetsResponse, + ]: + r"""Return a callable for the mutate customer asset sets method over gRPC. + + Creates, or removes customer asset sets. Operation + statuses are returned. + + Returns: + Callable[[~.MutateCustomerAssetSetsRequest], + ~.MutateCustomerAssetSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_asset_sets" not in self._stubs: + self._stubs["mutate_customer_asset_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerAssetSetService/MutateCustomerAssetSets", + request_serializer=customer_asset_set_service.MutateCustomerAssetSetsRequest.serialize, + response_deserializer=customer_asset_set_service.MutateCustomerAssetSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_asset_sets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerAssetSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_asset_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_asset_set_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..e7e010b26 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_asset_set_service/transports/grpc_asyncio.py @@ -0,0 +1,407 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import customer_asset_set_service +from .base import CustomerAssetSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerAssetSetService", + "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.ads.googleads.v23.services.CustomerAssetSetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerAssetSetServiceGrpcAsyncIOTransport( + CustomerAssetSetServiceTransport +): + """gRPC AsyncIO backend transport for CustomerAssetSetService. + + Service to manage customer asset set + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer_asset_sets( + self, + ) -> Callable[ + [customer_asset_set_service.MutateCustomerAssetSetsRequest], + Awaitable[customer_asset_set_service.MutateCustomerAssetSetsResponse], + ]: + r"""Return a callable for the mutate customer asset sets method over gRPC. + + Creates, or removes customer asset sets. Operation + statuses are returned. + + Returns: + Callable[[~.MutateCustomerAssetSetsRequest], + Awaitable[~.MutateCustomerAssetSetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_asset_sets" not in self._stubs: + self._stubs["mutate_customer_asset_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerAssetSetService/MutateCustomerAssetSets", + request_serializer=customer_asset_set_service.MutateCustomerAssetSetsRequest.serialize, + response_deserializer=customer_asset_set_service.MutateCustomerAssetSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_asset_sets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer_asset_sets: self._wrap_method( + self.mutate_customer_asset_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerAssetSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_client_link_service/__init__.py b/google/ads/googleads/v23/services/services/customer_client_link_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_client_link_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_client_link_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_client_link_service/async_client.py b/google/ads/googleads/v23/services/services/customer_client_link_service/async_client.py new file mode 100644 index 000000000..a6fd3b7aa --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_client_link_service/async_client.py @@ -0,0 +1,441 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import customer_client_link_service +from .transports.base import ( + CustomerClientLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomerClientLinkServiceClient + +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 CustomerClientLinkServiceAsyncClient: + """Service to manage customer client links.""" + + _client: CustomerClientLinkServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomerClientLinkServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CustomerClientLinkServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerClientLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomerClientLinkServiceClient._DEFAULT_UNIVERSE + + customer_path = staticmethod(CustomerClientLinkServiceClient.customer_path) + parse_customer_path = staticmethod( + CustomerClientLinkServiceClient.parse_customer_path + ) + customer_client_link_path = staticmethod( + CustomerClientLinkServiceClient.customer_client_link_path + ) + parse_customer_client_link_path = staticmethod( + CustomerClientLinkServiceClient.parse_customer_client_link_path + ) + common_billing_account_path = staticmethod( + CustomerClientLinkServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerClientLinkServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerClientLinkServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerClientLinkServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerClientLinkServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerClientLinkServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerClientLinkServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerClientLinkServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerClientLinkServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerClientLinkServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerClientLinkServiceAsyncClient: The constructed client. + """ + return CustomerClientLinkServiceClient.from_service_account_info.__func__(CustomerClientLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerClientLinkServiceAsyncClient: The constructed client. + """ + return CustomerClientLinkServiceClient.from_service_account_file.__func__(CustomerClientLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerClientLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerClientLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerClientLinkServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomerClientLinkServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerClientLinkServiceTransport, + Callable[..., CustomerClientLinkServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer client link service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerClientLinkServiceTransport,Callable[..., CustomerClientLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerClientLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerClientLinkServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerClientLinkServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerClientLinkService", + "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.ads.googleads.v23.services.CustomerClientLinkService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer_client_link( + self, + request: Optional[ + Union[ + customer_client_link_service.MutateCustomerClientLinkRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + customer_client_link_service.CustomerClientLinkOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_client_link_service.MutateCustomerClientLinkResponse: + r"""Creates or updates a customer client link. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerClientLinkRequest, dict]]): + The request object. Request message for + [CustomerClientLinkService.MutateCustomerClientLink][google.ads.googleads.v23.services.CustomerClientLinkService.MutateCustomerClientLink]. + customer_id (:class:`str`): + Required. The ID of the customer + whose customer link are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (:class:`google.ads.googleads.v23.services.types.CustomerClientLinkOperation`): + Required. The operation to perform on + the individual CustomerClientLink. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerClientLinkResponse: + Response message for a + CustomerClientLink mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_client_link_service.MutateCustomerClientLinkRequest, + ): + request = ( + customer_client_link_service.MutateCustomerClientLinkRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer_client_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomerClientLinkServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerClientLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_client_link_service/client.py b/google/ads/googleads/v23/services/services/customer_client_link_service/client.py new file mode 100644 index 000000000..409c8e0e0 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_client_link_service/client.py @@ -0,0 +1,924 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import customer_client_link_service +from .transports.base import ( + CustomerClientLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerClientLinkServiceGrpcTransport +from .transports.grpc_asyncio import ( + CustomerClientLinkServiceGrpcAsyncIOTransport, +) + + +class CustomerClientLinkServiceClientMeta(type): + """Metaclass for the CustomerClientLinkService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerClientLinkServiceTransport]] + _transport_registry["grpc"] = CustomerClientLinkServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomerClientLinkServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerClientLinkServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerClientLinkServiceClient( + metaclass=CustomerClientLinkServiceClientMeta +): + """Service to manage customer client links.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerClientLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerClientLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerClientLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerClientLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_client_link_path( + customer_id: str, + client_customer_id: str, + manager_link_id: str, + ) -> str: + """Returns a fully-qualified customer_client_link string.""" + return "customers/{customer_id}/customerClientLinks/{client_customer_id}~{manager_link_id}".format( + customer_id=customer_id, + client_customer_id=client_customer_id, + manager_link_id=manager_link_id, + ) + + @staticmethod + def parse_customer_client_link_path(path: str) -> Dict[str, str]: + """Parses a customer_client_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerClientLinks/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerClientLinkServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerClientLinkServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CustomerClientLinkServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CustomerClientLinkServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = CustomerClientLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomerClientLinkServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerClientLinkServiceTransport, + Callable[..., CustomerClientLinkServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer client link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerClientLinkServiceTransport,Callable[..., CustomerClientLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerClientLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomerClientLinkServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomerClientLinkServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomerClientLinkServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerClientLinkServiceTransport + ) + if transport_provided: + # transport is a CustomerClientLinkServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CustomerClientLinkServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerClientLinkServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerClientLinkServiceTransport], + Callable[..., CustomerClientLinkServiceTransport], + ] = ( + CustomerClientLinkServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomerClientLinkServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerClientLinkServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerClientLinkService", + "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.ads.googleads.v23.services.CustomerClientLinkService", + "credentialsType": None, + } + ), + ) + + def mutate_customer_client_link( + self, + request: Optional[ + Union[ + customer_client_link_service.MutateCustomerClientLinkRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + customer_client_link_service.CustomerClientLinkOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_client_link_service.MutateCustomerClientLinkResponse: + r"""Creates or updates a customer client link. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerClientLinkRequest, dict]): + The request object. Request message for + [CustomerClientLinkService.MutateCustomerClientLink][google.ads.googleads.v23.services.CustomerClientLinkService.MutateCustomerClientLink]. + customer_id (str): + Required. The ID of the customer + whose customer link are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v23.services.types.CustomerClientLinkOperation): + Required. The operation to perform on + the individual CustomerClientLink. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerClientLinkResponse: + Response message for a + CustomerClientLink mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_client_link_service.MutateCustomerClientLinkRequest, + ): + request = ( + customer_client_link_service.MutateCustomerClientLinkRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_client_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerClientLinkServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerClientLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_client_link_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_client_link_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_client_link_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_client_link_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_client_link_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_client_link_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_client_link_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_client_link_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_client_link_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_client_link_service/transports/base.py new file mode 100644 index 000000000..081077ff6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_client_link_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import customer_client_link_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerClientLinkServiceTransport(abc.ABC): + """Abstract transport class for CustomerClientLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_client_link: gapic_v1.method.wrap_method( + self.mutate_customer_client_link, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_client_link( + self, + ) -> Callable[ + [customer_client_link_service.MutateCustomerClientLinkRequest], + Union[ + customer_client_link_service.MutateCustomerClientLinkResponse, + Awaitable[ + customer_client_link_service.MutateCustomerClientLinkResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerClientLinkServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_client_link_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_client_link_service/transports/grpc.py new file mode 100644 index 000000000..dbbb99043 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_client_link_service/transports/grpc.py @@ -0,0 +1,393 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import customer_client_link_service +from .base import CustomerClientLinkServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerClientLinkService", + "rpcName": str(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.ads.googleads.v23.services.CustomerClientLinkService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerClientLinkServiceGrpcTransport( + CustomerClientLinkServiceTransport +): + """gRPC backend transport for CustomerClientLinkService. + + Service to manage customer client links. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer_client_link( + self, + ) -> Callable[ + [customer_client_link_service.MutateCustomerClientLinkRequest], + customer_client_link_service.MutateCustomerClientLinkResponse, + ]: + r"""Return a callable for the mutate customer client link method over gRPC. + + Creates or updates a customer client link. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerClientLinkRequest], + ~.MutateCustomerClientLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_client_link" not in self._stubs: + self._stubs["mutate_customer_client_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerClientLinkService/MutateCustomerClientLink", + request_serializer=customer_client_link_service.MutateCustomerClientLinkRequest.serialize, + response_deserializer=customer_client_link_service.MutateCustomerClientLinkResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_client_link"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerClientLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_client_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_client_link_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..a374b0292 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_client_link_service/transports/grpc_asyncio.py @@ -0,0 +1,416 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import customer_client_link_service +from .base import CustomerClientLinkServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerClientLinkService", + "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.ads.googleads.v23.services.CustomerClientLinkService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerClientLinkServiceGrpcAsyncIOTransport( + CustomerClientLinkServiceTransport +): + """gRPC AsyncIO backend transport for CustomerClientLinkService. + + Service to manage customer client links. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer_client_link( + self, + ) -> Callable[ + [customer_client_link_service.MutateCustomerClientLinkRequest], + Awaitable[ + customer_client_link_service.MutateCustomerClientLinkResponse + ], + ]: + r"""Return a callable for the mutate customer client link method over gRPC. + + Creates or updates a customer client link. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerClientLinkRequest], + Awaitable[~.MutateCustomerClientLinkResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_client_link" not in self._stubs: + self._stubs["mutate_customer_client_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerClientLinkService/MutateCustomerClientLink", + request_serializer=customer_client_link_service.MutateCustomerClientLinkRequest.serialize, + response_deserializer=customer_client_link_service.MutateCustomerClientLinkResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_client_link"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer_client_link: self._wrap_method( + self.mutate_customer_client_link, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerClientLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/__init__.py b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_conversion_goal_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_conversion_goal_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_conversion_goal_service/async_client.py b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/async_client.py new file mode 100644 index 000000000..0b5340fe5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/async_client.py @@ -0,0 +1,436 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_conversion_goal_service, +) +from .transports.base import ( + CustomerConversionGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomerConversionGoalServiceClient + +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 CustomerConversionGoalServiceAsyncClient: + """Service to manage customer conversion goal.""" + + _client: CustomerConversionGoalServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomerConversionGoalServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CustomerConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomerConversionGoalServiceClient._DEFAULT_UNIVERSE + + customer_conversion_goal_path = staticmethod( + CustomerConversionGoalServiceClient.customer_conversion_goal_path + ) + parse_customer_conversion_goal_path = staticmethod( + CustomerConversionGoalServiceClient.parse_customer_conversion_goal_path + ) + common_billing_account_path = staticmethod( + CustomerConversionGoalServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerConversionGoalServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerConversionGoalServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerConversionGoalServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerConversionGoalServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerConversionGoalServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerConversionGoalServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerConversionGoalServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerConversionGoalServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerConversionGoalServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerConversionGoalServiceAsyncClient: The constructed client. + """ + return CustomerConversionGoalServiceClient.from_service_account_info.__func__(CustomerConversionGoalServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerConversionGoalServiceAsyncClient: The constructed client. + """ + return CustomerConversionGoalServiceClient.from_service_account_file.__func__(CustomerConversionGoalServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerConversionGoalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerConversionGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerConversionGoalServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + CustomerConversionGoalServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerConversionGoalServiceTransport, + Callable[..., CustomerConversionGoalServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer conversion goal service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerConversionGoalServiceTransport,Callable[..., CustomerConversionGoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerConversionGoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerConversionGoalServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerConversionGoalServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerConversionGoalService", + "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.ads.googleads.v23.services.CustomerConversionGoalService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer_conversion_goals( + self, + request: Optional[ + Union[ + customer_conversion_goal_service.MutateCustomerConversionGoalsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customer_conversion_goal_service.CustomerConversionGoalOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_conversion_goal_service.MutateCustomerConversionGoalsResponse: + r"""Creates, updates or removes customer conversion + goals. Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerConversionGoalsRequest, dict]]): + The request object. Request message for + [CustomerConversionGoalService.MutateCustomerConversionGoals][google.ads.googleads.v23.services.CustomerConversionGoalService.MutateCustomerConversionGoals]. + customer_id (:class:`str`): + Required. The ID of the customer + whose customer conversion goals are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CustomerConversionGoalOperation]`): + Required. The list of operations to + perform on individual customer + conversion goal. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerConversionGoalsResponse: + Response message for a customer + conversion goal mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_conversion_goal_service.MutateCustomerConversionGoalsRequest, + ): + request = customer_conversion_goal_service.MutateCustomerConversionGoalsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer_conversion_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomerConversionGoalServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerConversionGoalServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_conversion_goal_service/client.py b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/client.py new file mode 100644 index 000000000..06f3db5be --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/client.py @@ -0,0 +1,921 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + customer_conversion_goal_service, +) +from .transports.base import ( + CustomerConversionGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerConversionGoalServiceGrpcTransport +from .transports.grpc_asyncio import ( + CustomerConversionGoalServiceGrpcAsyncIOTransport, +) + + +class CustomerConversionGoalServiceClientMeta(type): + """Metaclass for the CustomerConversionGoalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerConversionGoalServiceTransport]] + _transport_registry["grpc"] = CustomerConversionGoalServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomerConversionGoalServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerConversionGoalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerConversionGoalServiceClient( + metaclass=CustomerConversionGoalServiceClientMeta +): + """Service to manage customer conversion goal.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerConversionGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerConversionGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerConversionGoalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_conversion_goal_path( + customer_id: str, + category: str, + source: str, + ) -> str: + """Returns a fully-qualified customer_conversion_goal string.""" + return "customers/{customer_id}/customerConversionGoals/{category}~{source}".format( + customer_id=customer_id, + category=category, + source=source, + ) + + @staticmethod + def parse_customer_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a customer_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerConversionGoals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerConversionGoalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerConversionGoalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CustomerConversionGoalServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + CustomerConversionGoalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = CustomerConversionGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomerConversionGoalServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerConversionGoalServiceTransport, + Callable[..., CustomerConversionGoalServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer conversion goal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerConversionGoalServiceTransport,Callable[..., CustomerConversionGoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerConversionGoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomerConversionGoalServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomerConversionGoalServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomerConversionGoalServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerConversionGoalServiceTransport + ) + if transport_provided: + # transport is a CustomerConversionGoalServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CustomerConversionGoalServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerConversionGoalServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerConversionGoalServiceTransport], + Callable[..., CustomerConversionGoalServiceTransport], + ] = ( + CustomerConversionGoalServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomerConversionGoalServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerConversionGoalServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerConversionGoalService", + "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.ads.googleads.v23.services.CustomerConversionGoalService", + "credentialsType": None, + } + ), + ) + + def mutate_customer_conversion_goals( + self, + request: Optional[ + Union[ + customer_conversion_goal_service.MutateCustomerConversionGoalsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customer_conversion_goal_service.CustomerConversionGoalOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_conversion_goal_service.MutateCustomerConversionGoalsResponse: + r"""Creates, updates or removes customer conversion + goals. Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerConversionGoalsRequest, dict]): + The request object. Request message for + [CustomerConversionGoalService.MutateCustomerConversionGoals][google.ads.googleads.v23.services.CustomerConversionGoalService.MutateCustomerConversionGoals]. + customer_id (str): + Required. The ID of the customer + whose customer conversion goals are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerConversionGoalOperation]): + Required. The list of operations to + perform on individual customer + conversion goal. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerConversionGoalsResponse: + Response message for a customer + conversion goal mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_conversion_goal_service.MutateCustomerConversionGoalsRequest, + ): + request = customer_conversion_goal_service.MutateCustomerConversionGoalsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_conversion_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerConversionGoalServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerConversionGoalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_conversion_goal_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/base.py new file mode 100644 index 000000000..a4db49db2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + customer_conversion_goal_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerConversionGoalServiceTransport(abc.ABC): + """Abstract transport class for CustomerConversionGoalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_conversion_goals: gapic_v1.method.wrap_method( + self.mutate_customer_conversion_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_conversion_goals( + self, + ) -> Callable[ + [customer_conversion_goal_service.MutateCustomerConversionGoalsRequest], + Union[ + customer_conversion_goal_service.MutateCustomerConversionGoalsResponse, + Awaitable[ + customer_conversion_goal_service.MutateCustomerConversionGoalsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerConversionGoalServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/grpc.py new file mode 100644 index 000000000..c94cdf626 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/grpc.py @@ -0,0 +1,389 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + customer_conversion_goal_service, +) +from .base import CustomerConversionGoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerConversionGoalService", + "rpcName": str(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.ads.googleads.v23.services.CustomerConversionGoalService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerConversionGoalServiceGrpcTransport( + CustomerConversionGoalServiceTransport +): + """gRPC backend transport for CustomerConversionGoalService. + + Service to manage customer conversion goal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer_conversion_goals( + self, + ) -> Callable[ + [customer_conversion_goal_service.MutateCustomerConversionGoalsRequest], + customer_conversion_goal_service.MutateCustomerConversionGoalsResponse, + ]: + r"""Return a callable for the mutate customer conversion + goals method over gRPC. + + Creates, updates or removes customer conversion + goals. Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomerConversionGoalsRequest], + ~.MutateCustomerConversionGoalsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_conversion_goals" not in self._stubs: + self._stubs["mutate_customer_conversion_goals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerConversionGoalService/MutateCustomerConversionGoals", + request_serializer=customer_conversion_goal_service.MutateCustomerConversionGoalsRequest.serialize, + response_deserializer=customer_conversion_goal_service.MutateCustomerConversionGoalsResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_conversion_goals"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerConversionGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..64d450cb7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_conversion_goal_service/transports/grpc_asyncio.py @@ -0,0 +1,412 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_conversion_goal_service, +) +from .base import CustomerConversionGoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerConversionGoalService", + "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.ads.googleads.v23.services.CustomerConversionGoalService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerConversionGoalServiceGrpcAsyncIOTransport( + CustomerConversionGoalServiceTransport +): + """gRPC AsyncIO backend transport for CustomerConversionGoalService. + + Service to manage customer conversion goal. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer_conversion_goals( + self, + ) -> Callable[ + [customer_conversion_goal_service.MutateCustomerConversionGoalsRequest], + Awaitable[ + customer_conversion_goal_service.MutateCustomerConversionGoalsResponse + ], + ]: + r"""Return a callable for the mutate customer conversion + goals method over gRPC. + + Creates, updates or removes customer conversion + goals. Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomerConversionGoalsRequest], + Awaitable[~.MutateCustomerConversionGoalsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_conversion_goals" not in self._stubs: + self._stubs["mutate_customer_conversion_goals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerConversionGoalService/MutateCustomerConversionGoals", + request_serializer=customer_conversion_goal_service.MutateCustomerConversionGoalsRequest.serialize, + response_deserializer=customer_conversion_goal_service.MutateCustomerConversionGoalsResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_conversion_goals"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer_conversion_goals: self._wrap_method( + self.mutate_customer_conversion_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerConversionGoalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_customizer_service/__init__.py b/google/ads/googleads/v23/services/services/customer_customizer_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_customizer_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_customizer_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_customizer_service/async_client.py b/google/ads/googleads/v23/services/services/customer_customizer_service/async_client.py new file mode 100644 index 000000000..3a6734d87 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_customizer_service/async_client.py @@ -0,0 +1,441 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import customer_customizer_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomerCustomizerServiceClient + +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 CustomerCustomizerServiceAsyncClient: + """Service to manage customer customizer""" + + _client: CustomerCustomizerServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomerCustomizerServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CustomerCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomerCustomizerServiceClient._DEFAULT_UNIVERSE + + customer_customizer_path = staticmethod( + CustomerCustomizerServiceClient.customer_customizer_path + ) + parse_customer_customizer_path = staticmethod( + CustomerCustomizerServiceClient.parse_customer_customizer_path + ) + customizer_attribute_path = staticmethod( + CustomerCustomizerServiceClient.customizer_attribute_path + ) + parse_customizer_attribute_path = staticmethod( + CustomerCustomizerServiceClient.parse_customizer_attribute_path + ) + common_billing_account_path = staticmethod( + CustomerCustomizerServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerCustomizerServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerCustomizerServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerCustomizerServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerCustomizerServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerCustomizerServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerCustomizerServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerCustomizerServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerCustomizerServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerCustomizerServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerCustomizerServiceAsyncClient: The constructed client. + """ + return CustomerCustomizerServiceClient.from_service_account_info.__func__(CustomerCustomizerServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerCustomizerServiceAsyncClient: The constructed client. + """ + return CustomerCustomizerServiceClient.from_service_account_file.__func__(CustomerCustomizerServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerCustomizerServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerCustomizerServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomerCustomizerServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerCustomizerServiceTransport, + Callable[..., CustomerCustomizerServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer customizer service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerCustomizerServiceTransport,Callable[..., CustomerCustomizerServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerCustomizerServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerCustomizerServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerCustomizerServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerCustomizerService", + "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.ads.googleads.v23.services.CustomerCustomizerService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer_customizers( + self, + request: Optional[ + Union[ + customer_customizer_service.MutateCustomerCustomizersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customer_customizer_service.CustomerCustomizerOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_customizer_service.MutateCustomerCustomizersResponse: + r"""Creates, updates or removes customer customizers. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerCustomizersRequest, dict]]): + The request object. Request message for + [CustomerCustomizerService.MutateCustomerCustomizers][google.ads.googleads.v23.services.CustomerCustomizerService.MutateCustomerCustomizers]. + customer_id (:class:`str`): + Required. The ID of the customer + whose customer customizers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CustomerCustomizerOperation]`): + Required. The list of operations to + perform on individual customer + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerCustomizersResponse: + Response message for a customizer + attribute mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_customizer_service.MutateCustomerCustomizersRequest, + ): + request = ( + customer_customizer_service.MutateCustomerCustomizersRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomerCustomizerServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerCustomizerServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_customizer_service/client.py b/google/ads/googleads/v23/services/services/customer_customizer_service/client.py new file mode 100644 index 000000000..e0b6e508f --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_customizer_service/client.py @@ -0,0 +1,935 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import customer_customizer_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerCustomizerServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerCustomizerServiceGrpcTransport +from .transports.grpc_asyncio import ( + CustomerCustomizerServiceGrpcAsyncIOTransport, +) + + +class CustomerCustomizerServiceClientMeta(type): + """Metaclass for the CustomerCustomizerService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerCustomizerServiceTransport]] + _transport_registry["grpc"] = CustomerCustomizerServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomerCustomizerServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerCustomizerServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerCustomizerServiceClient( + metaclass=CustomerCustomizerServiceClientMeta +): + """Service to manage customer customizer""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerCustomizerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerCustomizerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerCustomizerServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_customizer_path( + customer_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customer_customizer string.""" + return "customers/{customer_id}/customerCustomizers/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customer_customizer_path(path: str) -> Dict[str, str]: + """Parses a customer_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerCustomizers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerCustomizerServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerCustomizerServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CustomerCustomizerServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CustomerCustomizerServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = CustomerCustomizerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomerCustomizerServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerCustomizerServiceTransport, + Callable[..., CustomerCustomizerServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer customizer service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerCustomizerServiceTransport,Callable[..., CustomerCustomizerServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerCustomizerServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomerCustomizerServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomerCustomizerServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomerCustomizerServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerCustomizerServiceTransport + ) + if transport_provided: + # transport is a CustomerCustomizerServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CustomerCustomizerServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerCustomizerServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerCustomizerServiceTransport], + Callable[..., CustomerCustomizerServiceTransport], + ] = ( + CustomerCustomizerServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomerCustomizerServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerCustomizerServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerCustomizerService", + "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.ads.googleads.v23.services.CustomerCustomizerService", + "credentialsType": None, + } + ), + ) + + def mutate_customer_customizers( + self, + request: Optional[ + Union[ + customer_customizer_service.MutateCustomerCustomizersRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customer_customizer_service.CustomerCustomizerOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_customizer_service.MutateCustomerCustomizersResponse: + r"""Creates, updates or removes customer customizers. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerCustomizersRequest, dict]): + The request object. Request message for + [CustomerCustomizerService.MutateCustomerCustomizers][google.ads.googleads.v23.services.CustomerCustomizerService.MutateCustomerCustomizers]. + customer_id (str): + Required. The ID of the customer + whose customer customizers are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerCustomizerOperation]): + Required. The list of operations to + perform on individual customer + customizers. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerCustomizersResponse: + Response message for a customizer + attribute mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_customizer_service.MutateCustomerCustomizersRequest, + ): + request = ( + customer_customizer_service.MutateCustomerCustomizersRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_customizers + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerCustomizerServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerCustomizerServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_customizer_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_customizer_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_customizer_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_customizer_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_customizer_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_customizer_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_customizer_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_customizer_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_customizer_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_customizer_service/transports/base.py new file mode 100644 index 000000000..4c4147375 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_customizer_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import customer_customizer_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerCustomizerServiceTransport(abc.ABC): + """Abstract transport class for CustomerCustomizerService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_customizers: gapic_v1.method.wrap_method( + self.mutate_customer_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_customizers( + self, + ) -> Callable[ + [customer_customizer_service.MutateCustomerCustomizersRequest], + Union[ + customer_customizer_service.MutateCustomerCustomizersResponse, + Awaitable[ + customer_customizer_service.MutateCustomerCustomizersResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerCustomizerServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_customizer_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_customizer_service/transports/grpc.py new file mode 100644 index 000000000..8ca22274b --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_customizer_service/transports/grpc.py @@ -0,0 +1,386 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import customer_customizer_service +from .base import CustomerCustomizerServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerCustomizerService", + "rpcName": str(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.ads.googleads.v23.services.CustomerCustomizerService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerCustomizerServiceGrpcTransport( + CustomerCustomizerServiceTransport +): + """gRPC backend transport for CustomerCustomizerService. + + Service to manage customer customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer_customizers( + self, + ) -> Callable[ + [customer_customizer_service.MutateCustomerCustomizersRequest], + customer_customizer_service.MutateCustomerCustomizersResponse, + ]: + r"""Return a callable for the mutate customer customizers method over gRPC. + + Creates, updates or removes customer customizers. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomerCustomizersRequest], + ~.MutateCustomerCustomizersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_customizers" not in self._stubs: + self._stubs["mutate_customer_customizers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerCustomizerService/MutateCustomerCustomizers", + request_serializer=customer_customizer_service.MutateCustomerCustomizersRequest.serialize, + response_deserializer=customer_customizer_service.MutateCustomerCustomizersResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_customizers"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerCustomizerServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_customizer_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_customizer_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..22b434f8f --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_customizer_service/transports/grpc_asyncio.py @@ -0,0 +1,409 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import customer_customizer_service +from .base import CustomerCustomizerServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerCustomizerService", + "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.ads.googleads.v23.services.CustomerCustomizerService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerCustomizerServiceGrpcAsyncIOTransport( + CustomerCustomizerServiceTransport +): + """gRPC AsyncIO backend transport for CustomerCustomizerService. + + Service to manage customer customizer + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer_customizers( + self, + ) -> Callable[ + [customer_customizer_service.MutateCustomerCustomizersRequest], + Awaitable[ + customer_customizer_service.MutateCustomerCustomizersResponse + ], + ]: + r"""Return a callable for the mutate customer customizers method over gRPC. + + Creates, updates or removes customer customizers. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomerCustomizersRequest], + Awaitable[~.MutateCustomerCustomizersResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_customizers" not in self._stubs: + self._stubs["mutate_customer_customizers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerCustomizerService/MutateCustomerCustomizers", + request_serializer=customer_customizer_service.MutateCustomerCustomizersRequest.serialize, + response_deserializer=customer_customizer_service.MutateCustomerCustomizersResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_customizers"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer_customizers: self._wrap_method( + self.mutate_customer_customizers, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerCustomizerServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_label_service/__init__.py b/google/ads/googleads/v23/services/services/customer_label_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_label_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_label_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_label_service/async_client.py b/google/ads/googleads/v23/services/services/customer_label_service/async_client.py new file mode 100644 index 000000000..1e8c02503 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_label_service/async_client.py @@ -0,0 +1,432 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import customer_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CustomerLabelServiceTransport, DEFAULT_CLIENT_INFO +from .client import CustomerLabelServiceClient + +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 CustomerLabelServiceAsyncClient: + """Service to manage labels on customers.""" + + _client: CustomerLabelServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomerLabelServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CustomerLabelServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomerLabelServiceClient._DEFAULT_UNIVERSE + + customer_path = staticmethod(CustomerLabelServiceClient.customer_path) + parse_customer_path = staticmethod( + CustomerLabelServiceClient.parse_customer_path + ) + customer_label_path = staticmethod( + CustomerLabelServiceClient.customer_label_path + ) + parse_customer_label_path = staticmethod( + CustomerLabelServiceClient.parse_customer_label_path + ) + label_path = staticmethod(CustomerLabelServiceClient.label_path) + parse_label_path = staticmethod(CustomerLabelServiceClient.parse_label_path) + common_billing_account_path = staticmethod( + CustomerLabelServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerLabelServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerLabelServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerLabelServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerLabelServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerLabelServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerLabelServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerLabelServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerLabelServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerLabelServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerLabelServiceAsyncClient: The constructed client. + """ + return CustomerLabelServiceClient.from_service_account_info.__func__(CustomerLabelServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerLabelServiceAsyncClient: The constructed client. + """ + return CustomerLabelServiceClient.from_service_account_file.__func__(CustomerLabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerLabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerLabelServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomerLabelServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerLabelServiceTransport, + Callable[..., CustomerLabelServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer label service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerLabelServiceTransport,Callable[..., CustomerLabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerLabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerLabelServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerLabelServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerLabelService", + "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.ads.googleads.v23.services.CustomerLabelService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer_labels( + self, + request: Optional[ + Union[customer_label_service.MutateCustomerLabelsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[customer_label_service.CustomerLabelOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_label_service.MutateCustomerLabelsResponse: + r"""Creates and removes customer-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerLabelsRequest, dict]]): + The request object. Request message for + [CustomerLabelService.MutateCustomerLabels][google.ads.googleads.v23.services.CustomerLabelService.MutateCustomerLabels]. + customer_id (:class:`str`): + Required. ID of the customer whose + customer-label relationships are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CustomerLabelOperation]`): + Required. The list of operations to + perform on customer-label relationships. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerLabelsResponse: + Response message for a customer + labels mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_label_service.MutateCustomerLabelsRequest + ): + request = customer_label_service.MutateCustomerLabelsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomerLabelServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerLabelServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_label_service/client.py b/google/ads/googleads/v23/services/services/customer_label_service/client.py new file mode 100644 index 000000000..67cc80071 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_label_service/client.py @@ -0,0 +1,934 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import customer_label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import CustomerLabelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CustomerLabelServiceGrpcTransport +from .transports.grpc_asyncio import CustomerLabelServiceGrpcAsyncIOTransport + + +class CustomerLabelServiceClientMeta(type): + """Metaclass for the CustomerLabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerLabelServiceTransport]] + _transport_registry["grpc"] = CustomerLabelServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomerLabelServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerLabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerLabelServiceClient(metaclass=CustomerLabelServiceClientMeta): + """Service to manage labels on customers.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerLabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerLabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerLabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_label_path( + customer_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified customer_label string.""" + return "customers/{customer_id}/customerLabels/{label_id}".format( + customer_id=customer_id, + label_id=label_id, + ) + + @staticmethod + def parse_customer_label_path(path: str) -> Dict[str, str]: + """Parses a customer_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerLabels/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path( + customer_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, + label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerLabelServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerLabelServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CustomerLabelServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CustomerLabelServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CustomerLabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomerLabelServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerLabelServiceTransport, + Callable[..., CustomerLabelServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerLabelServiceTransport,Callable[..., CustomerLabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerLabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomerLabelServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomerLabelServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = CustomerLabelServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerLabelServiceTransport + ) + if transport_provided: + # transport is a CustomerLabelServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CustomerLabelServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerLabelServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerLabelServiceTransport], + Callable[..., CustomerLabelServiceTransport], + ] = ( + CustomerLabelServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomerLabelServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerLabelServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerLabelService", + "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.ads.googleads.v23.services.CustomerLabelService", + "credentialsType": None, + } + ), + ) + + def mutate_customer_labels( + self, + request: Optional[ + Union[customer_label_service.MutateCustomerLabelsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[customer_label_service.CustomerLabelOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_label_service.MutateCustomerLabelsResponse: + r"""Creates and removes customer-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerLabelsRequest, dict]): + The request object. Request message for + [CustomerLabelService.MutateCustomerLabels][google.ads.googleads.v23.services.CustomerLabelService.MutateCustomerLabels]. + customer_id (str): + Required. ID of the customer whose + customer-label relationships are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerLabelOperation]): + Required. The list of operations to + perform on customer-label relationships. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerLabelsResponse: + Response message for a customer + labels mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_label_service.MutateCustomerLabelsRequest + ): + request = customer_label_service.MutateCustomerLabelsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerLabelServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerLabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_label_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_label_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_label_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_label_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_label_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_label_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_label_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_label_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_label_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_label_service/transports/base.py new file mode 100644 index 000000000..a32f5ed79 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_label_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import customer_label_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerLabelServiceTransport(abc.ABC): + """Abstract transport class for CustomerLabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_labels: gapic_v1.method.wrap_method( + self.mutate_customer_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_labels( + self, + ) -> Callable[ + [customer_label_service.MutateCustomerLabelsRequest], + Union[ + customer_label_service.MutateCustomerLabelsResponse, + Awaitable[customer_label_service.MutateCustomerLabelsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerLabelServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_label_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_label_service/transports/grpc.py new file mode 100644 index 000000000..ee525415f --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_label_service/transports/grpc.py @@ -0,0 +1,389 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import customer_label_service +from .base import CustomerLabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerLabelService", + "rpcName": str(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.ads.googleads.v23.services.CustomerLabelService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerLabelServiceGrpcTransport(CustomerLabelServiceTransport): + """gRPC backend transport for CustomerLabelService. + + Service to manage labels on customers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer_labels( + self, + ) -> Callable[ + [customer_label_service.MutateCustomerLabelsRequest], + customer_label_service.MutateCustomerLabelsResponse, + ]: + r"""Return a callable for the mutate customer labels method over gRPC. + + Creates and removes customer-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerLabelsRequest], + ~.MutateCustomerLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_labels" not in self._stubs: + self._stubs["mutate_customer_labels"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerLabelService/MutateCustomerLabels", + request_serializer=customer_label_service.MutateCustomerLabelsRequest.serialize, + response_deserializer=customer_label_service.MutateCustomerLabelsResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_labels"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerLabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_label_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_label_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..40a747171 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_label_service/transports/grpc_asyncio.py @@ -0,0 +1,410 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import customer_label_service +from .base import CustomerLabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerLabelService", + "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.ads.googleads.v23.services.CustomerLabelService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerLabelServiceGrpcAsyncIOTransport(CustomerLabelServiceTransport): + """gRPC AsyncIO backend transport for CustomerLabelService. + + Service to manage labels on customers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer_labels( + self, + ) -> Callable[ + [customer_label_service.MutateCustomerLabelsRequest], + Awaitable[customer_label_service.MutateCustomerLabelsResponse], + ]: + r"""Return a callable for the mutate customer labels method over gRPC. + + Creates and removes customer-label relationships. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ `LabelError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerLabelsRequest], + Awaitable[~.MutateCustomerLabelsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_labels" not in self._stubs: + self._stubs["mutate_customer_labels"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerLabelService/MutateCustomerLabels", + request_serializer=customer_label_service.MutateCustomerLabelsRequest.serialize, + response_deserializer=customer_label_service.MutateCustomerLabelsResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_labels"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer_labels: self._wrap_method( + self.mutate_customer_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerLabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/__init__.py b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/async_client.py b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/async_client.py new file mode 100644 index 000000000..a9ee1b481 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/async_client.py @@ -0,0 +1,442 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_lifecycle_goal_service, +) +from .transports.base import ( + CustomerLifecycleGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomerLifecycleGoalServiceClient + +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 CustomerLifecycleGoalServiceAsyncClient: + """Service to configure customer lifecycle goals.""" + + _client: CustomerLifecycleGoalServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomerLifecycleGoalServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CustomerLifecycleGoalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerLifecycleGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomerLifecycleGoalServiceClient._DEFAULT_UNIVERSE + + customer_path = staticmethod( + CustomerLifecycleGoalServiceClient.customer_path + ) + parse_customer_path = staticmethod( + CustomerLifecycleGoalServiceClient.parse_customer_path + ) + customer_lifecycle_goal_path = staticmethod( + CustomerLifecycleGoalServiceClient.customer_lifecycle_goal_path + ) + parse_customer_lifecycle_goal_path = staticmethod( + CustomerLifecycleGoalServiceClient.parse_customer_lifecycle_goal_path + ) + common_billing_account_path = staticmethod( + CustomerLifecycleGoalServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerLifecycleGoalServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerLifecycleGoalServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerLifecycleGoalServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerLifecycleGoalServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerLifecycleGoalServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerLifecycleGoalServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerLifecycleGoalServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerLifecycleGoalServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerLifecycleGoalServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerLifecycleGoalServiceAsyncClient: The constructed client. + """ + return CustomerLifecycleGoalServiceClient.from_service_account_info.__func__(CustomerLifecycleGoalServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerLifecycleGoalServiceAsyncClient: The constructed client. + """ + return CustomerLifecycleGoalServiceClient.from_service_account_file.__func__(CustomerLifecycleGoalServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerLifecycleGoalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerLifecycleGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerLifecycleGoalServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomerLifecycleGoalServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerLifecycleGoalServiceTransport, + Callable[..., CustomerLifecycleGoalServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer lifecycle goal service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerLifecycleGoalServiceTransport,Callable[..., CustomerLifecycleGoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerLifecycleGoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerLifecycleGoalServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerLifecycleGoalServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerLifecycleGoalService", + "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.ads.googleads.v23.services.CustomerLifecycleGoalService", + "credentialsType": None, + } + ), + ) + + async def configure_customer_lifecycle_goals( + self, + request: Optional[ + Union[ + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + customer_lifecycle_goal_service.CustomerLifecycleGoalOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse + ): + r"""Process the given customer lifecycle configurations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `CustomerLifecycleGoalConfigError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ConfigureCustomerLifecycleGoalsRequest, dict]]): + The request object. Request message for + [CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals][google.ads.googleads.v23.services.CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals]. + customer_id (:class:`str`): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (:class:`google.ads.googleads.v23.services.types.CustomerLifecycleGoalOperation`): + Required. The operation to perform + customer lifecycle goal update. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ConfigureCustomerLifecycleGoalsResponse: + Response message for + [CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals][google.ads.googleads.v23.services.CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest, + ): + request = customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.configure_customer_lifecycle_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomerLifecycleGoalServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerLifecycleGoalServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/client.py b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/client.py new file mode 100644 index 000000000..f54609e09 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/client.py @@ -0,0 +1,923 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + customer_lifecycle_goal_service, +) +from .transports.base import ( + CustomerLifecycleGoalServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerLifecycleGoalServiceGrpcTransport +from .transports.grpc_asyncio import ( + CustomerLifecycleGoalServiceGrpcAsyncIOTransport, +) + + +class CustomerLifecycleGoalServiceClientMeta(type): + """Metaclass for the CustomerLifecycleGoalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerLifecycleGoalServiceTransport]] + _transport_registry["grpc"] = CustomerLifecycleGoalServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomerLifecycleGoalServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerLifecycleGoalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerLifecycleGoalServiceClient( + metaclass=CustomerLifecycleGoalServiceClientMeta +): + """Service to configure customer lifecycle goals.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerLifecycleGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerLifecycleGoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerLifecycleGoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerLifecycleGoalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_lifecycle_goal_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer_lifecycle_goal string.""" + return "customers/{customer_id}/customerLifecycleGoals".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_lifecycle_goal_path(path: str) -> Dict[str, str]: + """Parses a customer_lifecycle_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerLifecycleGoals$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerLifecycleGoalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerLifecycleGoalServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CustomerLifecycleGoalServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + CustomerLifecycleGoalServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = CustomerLifecycleGoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomerLifecycleGoalServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerLifecycleGoalServiceTransport, + Callable[..., CustomerLifecycleGoalServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer lifecycle goal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerLifecycleGoalServiceTransport,Callable[..., CustomerLifecycleGoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerLifecycleGoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomerLifecycleGoalServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomerLifecycleGoalServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomerLifecycleGoalServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerLifecycleGoalServiceTransport + ) + if transport_provided: + # transport is a CustomerLifecycleGoalServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CustomerLifecycleGoalServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerLifecycleGoalServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerLifecycleGoalServiceTransport], + Callable[..., CustomerLifecycleGoalServiceTransport], + ] = ( + CustomerLifecycleGoalServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomerLifecycleGoalServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerLifecycleGoalServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerLifecycleGoalService", + "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.ads.googleads.v23.services.CustomerLifecycleGoalService", + "credentialsType": None, + } + ), + ) + + def configure_customer_lifecycle_goals( + self, + request: Optional[ + Union[ + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + customer_lifecycle_goal_service.CustomerLifecycleGoalOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse + ): + r"""Process the given customer lifecycle configurations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `CustomerLifecycleGoalConfigError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ConfigureCustomerLifecycleGoalsRequest, dict]): + The request object. Request message for + [CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals][google.ads.googleads.v23.services.CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals]. + customer_id (str): + Required. The ID of the customer + performing the upload. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v23.services.types.CustomerLifecycleGoalOperation): + Required. The operation to perform + customer lifecycle goal update. + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ConfigureCustomerLifecycleGoalsResponse: + Response message for + [CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals][google.ads.googleads.v23.services.CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest, + ): + request = customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.configure_customer_lifecycle_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerLifecycleGoalServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerLifecycleGoalServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_lifecycle_goal_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/base.py new file mode 100644 index 000000000..bcf10db2c --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + customer_lifecycle_goal_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerLifecycleGoalServiceTransport(abc.ABC): + """Abstract transport class for CustomerLifecycleGoalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.configure_customer_lifecycle_goals: gapic_v1.method.wrap_method( + self.configure_customer_lifecycle_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def configure_customer_lifecycle_goals( + self, + ) -> Callable[ + [ + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest + ], + Union[ + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse, + Awaitable[ + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerLifecycleGoalServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/grpc.py new file mode 100644 index 000000000..d95b98eca --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/grpc.py @@ -0,0 +1,395 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + customer_lifecycle_goal_service, +) +from .base import CustomerLifecycleGoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerLifecycleGoalService", + "rpcName": str(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.ads.googleads.v23.services.CustomerLifecycleGoalService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerLifecycleGoalServiceGrpcTransport( + CustomerLifecycleGoalServiceTransport +): + """gRPC backend transport for CustomerLifecycleGoalService. + + Service to configure customer lifecycle goals. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def configure_customer_lifecycle_goals( + self, + ) -> Callable[ + [ + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest + ], + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse, + ]: + r"""Return a callable for the configure customer lifecycle + goals method over gRPC. + + Process the given customer lifecycle configurations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `CustomerLifecycleGoalConfigError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ConfigureCustomerLifecycleGoalsRequest], + ~.ConfigureCustomerLifecycleGoalsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "configure_customer_lifecycle_goals" not in self._stubs: + self._stubs["configure_customer_lifecycle_goals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerLifecycleGoalService/ConfigureCustomerLifecycleGoals", + request_serializer=customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest.serialize, + response_deserializer=customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse.deserialize, + ) + ) + return self._stubs["configure_customer_lifecycle_goals"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerLifecycleGoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..adc51d655 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_lifecycle_goal_service/transports/grpc_asyncio.py @@ -0,0 +1,418 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_lifecycle_goal_service, +) +from .base import CustomerLifecycleGoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerLifecycleGoalService", + "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.ads.googleads.v23.services.CustomerLifecycleGoalService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerLifecycleGoalServiceGrpcAsyncIOTransport( + CustomerLifecycleGoalServiceTransport +): + """gRPC AsyncIO backend transport for CustomerLifecycleGoalService. + + Service to configure customer lifecycle goals. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def configure_customer_lifecycle_goals( + self, + ) -> Callable[ + [ + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest + ], + Awaitable[ + customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse + ], + ]: + r"""Return a callable for the configure customer lifecycle + goals method over gRPC. + + Process the given customer lifecycle configurations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `CustomerLifecycleGoalConfigError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ConfigureCustomerLifecycleGoalsRequest], + Awaitable[~.ConfigureCustomerLifecycleGoalsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "configure_customer_lifecycle_goals" not in self._stubs: + self._stubs["configure_customer_lifecycle_goals"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerLifecycleGoalService/ConfigureCustomerLifecycleGoals", + request_serializer=customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsRequest.serialize, + response_deserializer=customer_lifecycle_goal_service.ConfigureCustomerLifecycleGoalsResponse.deserialize, + ) + ) + return self._stubs["configure_customer_lifecycle_goals"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.configure_customer_lifecycle_goals: self._wrap_method( + self.configure_customer_lifecycle_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerLifecycleGoalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_manager_link_service/__init__.py b/google/ads/googleads/v23/services/services/customer_manager_link_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_manager_link_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_manager_link_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_manager_link_service/async_client.py b/google/ads/googleads/v23/services/services/customer_manager_link_service/async_client.py new file mode 100644 index 000000000..aabfa956c --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_manager_link_service/async_client.py @@ -0,0 +1,576 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_manager_link_service, +) +from .transports.base import ( + CustomerManagerLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomerManagerLinkServiceClient + +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 CustomerManagerLinkServiceAsyncClient: + """Service to manage customer-manager links.""" + + _client: CustomerManagerLinkServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomerManagerLinkServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CustomerManagerLinkServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerManagerLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomerManagerLinkServiceClient._DEFAULT_UNIVERSE + + customer_path = staticmethod(CustomerManagerLinkServiceClient.customer_path) + parse_customer_path = staticmethod( + CustomerManagerLinkServiceClient.parse_customer_path + ) + customer_manager_link_path = staticmethod( + CustomerManagerLinkServiceClient.customer_manager_link_path + ) + parse_customer_manager_link_path = staticmethod( + CustomerManagerLinkServiceClient.parse_customer_manager_link_path + ) + common_billing_account_path = staticmethod( + CustomerManagerLinkServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerManagerLinkServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerManagerLinkServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerManagerLinkServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerManagerLinkServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerManagerLinkServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerManagerLinkServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerManagerLinkServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerManagerLinkServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerManagerLinkServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerManagerLinkServiceAsyncClient: The constructed client. + """ + return CustomerManagerLinkServiceClient.from_service_account_info.__func__(CustomerManagerLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerManagerLinkServiceAsyncClient: The constructed client. + """ + return CustomerManagerLinkServiceClient.from_service_account_file.__func__(CustomerManagerLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerManagerLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerManagerLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerManagerLinkServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomerManagerLinkServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerManagerLinkServiceTransport, + Callable[..., CustomerManagerLinkServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer manager link service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerManagerLinkServiceTransport,Callable[..., CustomerManagerLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerManagerLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerManagerLinkServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerManagerLinkServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerManagerLinkService", + "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.ads.googleads.v23.services.CustomerManagerLinkService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer_manager_link( + self, + request: Optional[ + Union[ + customer_manager_link_service.MutateCustomerManagerLinkRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customer_manager_link_service.CustomerManagerLinkOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_manager_link_service.MutateCustomerManagerLinkResponse: + r"""Updates customer manager links. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerManagerLinkRequest, dict]]): + The request object. Request message for + [CustomerManagerLinkService.MutateCustomerManagerLink][google.ads.googleads.v23.services.CustomerManagerLinkService.MutateCustomerManagerLink]. + customer_id (:class:`str`): + Required. The ID of the customer + whose customer manager links are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CustomerManagerLinkOperation]`): + Required. The list of operations to + perform on individual customer manager + links. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerManagerLinkResponse: + Response message for a + CustomerManagerLink mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_manager_link_service.MutateCustomerManagerLinkRequest, + ): + request = ( + customer_manager_link_service.MutateCustomerManagerLinkRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer_manager_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def move_manager_link( + self, + request: Optional[ + Union[customer_manager_link_service.MoveManagerLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + previous_customer_manager_link: Optional[str] = None, + new_manager: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_manager_link_service.MoveManagerLinkResponse: + r"""Moves a client customer to a new manager customer. This + simplifies the complex request that requires two operations to + move a client customer to a new manager, for example: + + 1. Update operation with Status INACTIVE (previous manager) and, + 2. Update operation with Status ACTIVE (new manager). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MoveManagerLinkRequest, dict]]): + The request object. Request message for + [CustomerManagerLinkService.MoveManagerLink][google.ads.googleads.v23.services.CustomerManagerLinkService.MoveManagerLink]. + customer_id (:class:`str`): + Required. The ID of the client + customer that is being moved. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + previous_customer_manager_link (:class:`str`): + Required. The resource name of the previous + CustomerManagerLink. The resource name has the form: + ``customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}`` + + This corresponds to the ``previous_customer_manager_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + new_manager (:class:`str`): + Required. The resource name of the new manager customer + that the client wants to move to. Customer resource + names have the format: "customers/{customer_id}" + + This corresponds to the ``new_manager`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MoveManagerLinkResponse: + Response message for a + CustomerManagerLink moveManagerLink. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + previous_customer_manager_link, + new_manager, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_manager_link_service.MoveManagerLinkRequest + ): + request = customer_manager_link_service.MoveManagerLinkRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if previous_customer_manager_link is not None: + request.previous_customer_manager_link = ( + previous_customer_manager_link + ) + if new_manager is not None: + request.new_manager = new_manager + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.move_manager_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomerManagerLinkServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerManagerLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_manager_link_service/client.py b/google/ads/googleads/v23/services/services/customer_manager_link_service/client.py new file mode 100644 index 000000000..cacc02248 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_manager_link_service/client.py @@ -0,0 +1,1071 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + customer_manager_link_service, +) +from .transports.base import ( + CustomerManagerLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerManagerLinkServiceGrpcTransport +from .transports.grpc_asyncio import ( + CustomerManagerLinkServiceGrpcAsyncIOTransport, +) + + +class CustomerManagerLinkServiceClientMeta(type): + """Metaclass for the CustomerManagerLinkService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerManagerLinkServiceTransport]] + _transport_registry["grpc"] = CustomerManagerLinkServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomerManagerLinkServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerManagerLinkServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerManagerLinkServiceClient( + metaclass=CustomerManagerLinkServiceClientMeta +): + """Service to manage customer-manager links.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerManagerLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerManagerLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerManagerLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerManagerLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_manager_link_path( + customer_id: str, + manager_customer_id: str, + manager_link_id: str, + ) -> str: + """Returns a fully-qualified customer_manager_link string.""" + return "customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}".format( + customer_id=customer_id, + manager_customer_id=manager_customer_id, + manager_link_id=manager_link_id, + ) + + @staticmethod + def parse_customer_manager_link_path(path: str) -> Dict[str, str]: + """Parses a customer_manager_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerManagerLinks/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerManagerLinkServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerManagerLinkServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CustomerManagerLinkServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + CustomerManagerLinkServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = CustomerManagerLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomerManagerLinkServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerManagerLinkServiceTransport, + Callable[..., CustomerManagerLinkServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer manager link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerManagerLinkServiceTransport,Callable[..., CustomerManagerLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerManagerLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomerManagerLinkServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomerManagerLinkServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomerManagerLinkServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerManagerLinkServiceTransport + ) + if transport_provided: + # transport is a CustomerManagerLinkServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CustomerManagerLinkServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerManagerLinkServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerManagerLinkServiceTransport], + Callable[..., CustomerManagerLinkServiceTransport], + ] = ( + CustomerManagerLinkServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomerManagerLinkServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerManagerLinkServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerManagerLinkService", + "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.ads.googleads.v23.services.CustomerManagerLinkService", + "credentialsType": None, + } + ), + ) + + def mutate_customer_manager_link( + self, + request: Optional[ + Union[ + customer_manager_link_service.MutateCustomerManagerLinkRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customer_manager_link_service.CustomerManagerLinkOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_manager_link_service.MutateCustomerManagerLinkResponse: + r"""Updates customer manager links. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerManagerLinkRequest, dict]): + The request object. Request message for + [CustomerManagerLinkService.MutateCustomerManagerLink][google.ads.googleads.v23.services.CustomerManagerLinkService.MutateCustomerManagerLink]. + customer_id (str): + Required. The ID of the customer + whose customer manager links are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerManagerLinkOperation]): + Required. The list of operations to + perform on individual customer manager + links. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerManagerLinkResponse: + Response message for a + CustomerManagerLink mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_manager_link_service.MutateCustomerManagerLinkRequest, + ): + request = ( + customer_manager_link_service.MutateCustomerManagerLinkRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_manager_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def move_manager_link( + self, + request: Optional[ + Union[customer_manager_link_service.MoveManagerLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + previous_customer_manager_link: Optional[str] = None, + new_manager: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_manager_link_service.MoveManagerLinkResponse: + r"""Moves a client customer to a new manager customer. This + simplifies the complex request that requires two operations to + move a client customer to a new manager, for example: + + 1. Update operation with Status INACTIVE (previous manager) and, + 2. Update operation with Status ACTIVE (new manager). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MoveManagerLinkRequest, dict]): + The request object. Request message for + [CustomerManagerLinkService.MoveManagerLink][google.ads.googleads.v23.services.CustomerManagerLinkService.MoveManagerLink]. + customer_id (str): + Required. The ID of the client + customer that is being moved. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + previous_customer_manager_link (str): + Required. The resource name of the previous + CustomerManagerLink. The resource name has the form: + ``customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}`` + + This corresponds to the ``previous_customer_manager_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + new_manager (str): + Required. The resource name of the new manager customer + that the client wants to move to. Customer resource + names have the format: "customers/{customer_id}" + + This corresponds to the ``new_manager`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MoveManagerLinkResponse: + Response message for a + CustomerManagerLink moveManagerLink. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + previous_customer_manager_link, + new_manager, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_manager_link_service.MoveManagerLinkRequest + ): + request = customer_manager_link_service.MoveManagerLinkRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if previous_customer_manager_link is not None: + request.previous_customer_manager_link = ( + previous_customer_manager_link + ) + if new_manager is not None: + request.new_manager = new_manager + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.move_manager_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerManagerLinkServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerManagerLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_manager_link_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_manager_link_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_manager_link_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_manager_link_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_manager_link_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_manager_link_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_manager_link_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_manager_link_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_manager_link_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_manager_link_service/transports/base.py new file mode 100644 index 000000000..274f5416a --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_manager_link_service/transports/base.py @@ -0,0 +1,194 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + customer_manager_link_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerManagerLinkServiceTransport(abc.ABC): + """Abstract transport class for CustomerManagerLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_manager_link: gapic_v1.method.wrap_method( + self.mutate_customer_manager_link, + default_timeout=None, + client_info=client_info, + ), + self.move_manager_link: gapic_v1.method.wrap_method( + self.move_manager_link, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_manager_link( + self, + ) -> Callable[ + [customer_manager_link_service.MutateCustomerManagerLinkRequest], + Union[ + customer_manager_link_service.MutateCustomerManagerLinkResponse, + Awaitable[ + customer_manager_link_service.MutateCustomerManagerLinkResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def move_manager_link( + self, + ) -> Callable[ + [customer_manager_link_service.MoveManagerLinkRequest], + Union[ + customer_manager_link_service.MoveManagerLinkResponse, + Awaitable[customer_manager_link_service.MoveManagerLinkResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerManagerLinkServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_manager_link_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_manager_link_service/transports/grpc.py new file mode 100644 index 000000000..d87a701a7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_manager_link_service/transports/grpc.py @@ -0,0 +1,432 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + customer_manager_link_service, +) +from .base import CustomerManagerLinkServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerManagerLinkService", + "rpcName": str(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.ads.googleads.v23.services.CustomerManagerLinkService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerManagerLinkServiceGrpcTransport( + CustomerManagerLinkServiceTransport +): + """gRPC backend transport for CustomerManagerLinkService. + + Service to manage customer-manager links. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer_manager_link( + self, + ) -> Callable[ + [customer_manager_link_service.MutateCustomerManagerLinkRequest], + customer_manager_link_service.MutateCustomerManagerLinkResponse, + ]: + r"""Return a callable for the mutate customer manager link method over gRPC. + + Updates customer manager links. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerManagerLinkRequest], + ~.MutateCustomerManagerLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_manager_link" not in self._stubs: + self._stubs["mutate_customer_manager_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerManagerLinkService/MutateCustomerManagerLink", + request_serializer=customer_manager_link_service.MutateCustomerManagerLinkRequest.serialize, + response_deserializer=customer_manager_link_service.MutateCustomerManagerLinkResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_manager_link"] + + @property + def move_manager_link( + self, + ) -> Callable[ + [customer_manager_link_service.MoveManagerLinkRequest], + customer_manager_link_service.MoveManagerLinkResponse, + ]: + r"""Return a callable for the move manager link method over gRPC. + + Moves a client customer to a new manager customer. This + simplifies the complex request that requires two operations to + move a client customer to a new manager, for example: + + 1. Update operation with Status INACTIVE (previous manager) and, + 2. Update operation with Status ACTIVE (new manager). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MoveManagerLinkRequest], + ~.MoveManagerLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "move_manager_link" not in self._stubs: + self._stubs["move_manager_link"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerManagerLinkService/MoveManagerLink", + request_serializer=customer_manager_link_service.MoveManagerLinkRequest.serialize, + response_deserializer=customer_manager_link_service.MoveManagerLinkResponse.deserialize, + ) + return self._stubs["move_manager_link"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerManagerLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_manager_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_manager_link_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..ce2484ecd --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_manager_link_service/transports/grpc_asyncio.py @@ -0,0 +1,460 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_manager_link_service, +) +from .base import CustomerManagerLinkServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerManagerLinkService", + "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.ads.googleads.v23.services.CustomerManagerLinkService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerManagerLinkServiceGrpcAsyncIOTransport( + CustomerManagerLinkServiceTransport +): + """gRPC AsyncIO backend transport for CustomerManagerLinkService. + + Service to manage customer-manager links. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer_manager_link( + self, + ) -> Callable[ + [customer_manager_link_service.MutateCustomerManagerLinkRequest], + Awaitable[ + customer_manager_link_service.MutateCustomerManagerLinkResponse + ], + ]: + r"""Return a callable for the mutate customer manager link method over gRPC. + + Updates customer manager links. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerManagerLinkRequest], + Awaitable[~.MutateCustomerManagerLinkResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_manager_link" not in self._stubs: + self._stubs["mutate_customer_manager_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerManagerLinkService/MutateCustomerManagerLink", + request_serializer=customer_manager_link_service.MutateCustomerManagerLinkRequest.serialize, + response_deserializer=customer_manager_link_service.MutateCustomerManagerLinkResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_manager_link"] + + @property + def move_manager_link( + self, + ) -> Callable[ + [customer_manager_link_service.MoveManagerLinkRequest], + Awaitable[customer_manager_link_service.MoveManagerLinkResponse], + ]: + r"""Return a callable for the move manager link method over gRPC. + + Moves a client customer to a new manager customer. This + simplifies the complex request that requires two operations to + move a client customer to a new manager, for example: + + 1. Update operation with Status INACTIVE (previous manager) and, + 2. Update operation with Status ACTIVE (new manager). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MoveManagerLinkRequest], + Awaitable[~.MoveManagerLinkResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "move_manager_link" not in self._stubs: + self._stubs["move_manager_link"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerManagerLinkService/MoveManagerLink", + request_serializer=customer_manager_link_service.MoveManagerLinkRequest.serialize, + response_deserializer=customer_manager_link_service.MoveManagerLinkResponse.deserialize, + ) + return self._stubs["move_manager_link"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer_manager_link: self._wrap_method( + self.mutate_customer_manager_link, + default_timeout=None, + client_info=client_info, + ), + self.move_manager_link: self._wrap_method( + self.move_manager_link, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerManagerLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/__init__.py b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_negative_criterion_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_negative_criterion_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_negative_criterion_service/async_client.py b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/async_client.py new file mode 100644 index 000000000..9146edbe3 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/async_client.py @@ -0,0 +1,448 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_negative_criterion_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerNegativeCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomerNegativeCriterionServiceClient + +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 CustomerNegativeCriterionServiceAsyncClient: + """Service to manage customer negative criteria.""" + + _client: CustomerNegativeCriterionServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomerNegativeCriterionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CustomerNegativeCriterionServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerNegativeCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomerNegativeCriterionServiceClient._DEFAULT_UNIVERSE + + customer_negative_criterion_path = staticmethod( + CustomerNegativeCriterionServiceClient.customer_negative_criterion_path + ) + parse_customer_negative_criterion_path = staticmethod( + CustomerNegativeCriterionServiceClient.parse_customer_negative_criterion_path + ) + mobile_app_category_constant_path = staticmethod( + CustomerNegativeCriterionServiceClient.mobile_app_category_constant_path + ) + parse_mobile_app_category_constant_path = staticmethod( + CustomerNegativeCriterionServiceClient.parse_mobile_app_category_constant_path + ) + common_billing_account_path = staticmethod( + CustomerNegativeCriterionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerNegativeCriterionServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerNegativeCriterionServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerNegativeCriterionServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerNegativeCriterionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerNegativeCriterionServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerNegativeCriterionServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerNegativeCriterionServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerNegativeCriterionServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerNegativeCriterionServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerNegativeCriterionServiceAsyncClient: The constructed client. + """ + return CustomerNegativeCriterionServiceClient.from_service_account_info.__func__(CustomerNegativeCriterionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerNegativeCriterionServiceAsyncClient: The constructed client. + """ + return CustomerNegativeCriterionServiceClient.from_service_account_file.__func__(CustomerNegativeCriterionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerNegativeCriterionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerNegativeCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerNegativeCriterionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + CustomerNegativeCriterionServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerNegativeCriterionServiceTransport, + Callable[..., CustomerNegativeCriterionServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer negative criterion service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerNegativeCriterionServiceTransport,Callable[..., CustomerNegativeCriterionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerNegativeCriterionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerNegativeCriterionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerNegativeCriterionServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerNegativeCriterionService", + "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.ads.googleads.v23.services.CustomerNegativeCriterionService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer_negative_criteria( + self, + request: Optional[ + Union[ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customer_negative_criterion_service.CustomerNegativeCriterionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse + ): + r"""Creates or removes criteria. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerNegativeCriteriaRequest, dict]]): + The request object. Request message for + [CustomerNegativeCriterionService.MutateCustomerNegativeCriteria][google.ads.googleads.v23.services.CustomerNegativeCriterionService.MutateCustomerNegativeCriteria]. + customer_id (:class:`str`): + Required. The ID of the customer + whose criteria are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CustomerNegativeCriterionOperation]`): + Required. The list of operations to + perform on individual criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerNegativeCriteriaResponse: + Response message for customer + negative criterion mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest, + ): + request = customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer_negative_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomerNegativeCriterionServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerNegativeCriterionServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_negative_criterion_service/client.py b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/client.py new file mode 100644 index 000000000..997994d5c --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/client.py @@ -0,0 +1,945 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + customer_negative_criterion_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerNegativeCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerNegativeCriterionServiceGrpcTransport +from .transports.grpc_asyncio import ( + CustomerNegativeCriterionServiceGrpcAsyncIOTransport, +) + + +class CustomerNegativeCriterionServiceClientMeta(type): + """Metaclass for the CustomerNegativeCriterionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerNegativeCriterionServiceTransport]] + _transport_registry["grpc"] = CustomerNegativeCriterionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomerNegativeCriterionServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerNegativeCriterionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerNegativeCriterionServiceClient( + metaclass=CustomerNegativeCriterionServiceClientMeta +): + """Service to manage customer negative criteria.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerNegativeCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerNegativeCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerNegativeCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerNegativeCriterionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_negative_criterion_path( + customer_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified customer_negative_criterion string.""" + return "customers/{customer_id}/customerNegativeCriteria/{criterion_id}".format( + customer_id=customer_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_customer_negative_criterion_path(path: str) -> Dict[str, str]: + """Parses a customer_negative_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerNegativeCriteria/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_app_category_constant_path( + mobile_app_category_id: str, + ) -> str: + """Returns a fully-qualified mobile_app_category_constant string.""" + return "mobileAppCategoryConstants/{mobile_app_category_id}".format( + mobile_app_category_id=mobile_app_category_id, + ) + + @staticmethod + def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: + """Parses a mobile_app_category_constant path into its component segments.""" + m = re.match( + r"^mobileAppCategoryConstants/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerNegativeCriterionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerNegativeCriterionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CustomerNegativeCriterionServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + CustomerNegativeCriterionServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = CustomerNegativeCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + CustomerNegativeCriterionServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerNegativeCriterionServiceTransport, + Callable[..., CustomerNegativeCriterionServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer negative criterion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerNegativeCriterionServiceTransport,Callable[..., CustomerNegativeCriterionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerNegativeCriterionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomerNegativeCriterionServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomerNegativeCriterionServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomerNegativeCriterionServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerNegativeCriterionServiceTransport + ) + if transport_provided: + # transport is a CustomerNegativeCriterionServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CustomerNegativeCriterionServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerNegativeCriterionServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerNegativeCriterionServiceTransport], + Callable[..., CustomerNegativeCriterionServiceTransport], + ] = ( + CustomerNegativeCriterionServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomerNegativeCriterionServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerNegativeCriterionServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerNegativeCriterionService", + "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.ads.googleads.v23.services.CustomerNegativeCriterionService", + "credentialsType": None, + } + ), + ) + + def mutate_customer_negative_criteria( + self, + request: Optional[ + Union[ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customer_negative_criterion_service.CustomerNegativeCriterionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse + ): + r"""Creates or removes criteria. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerNegativeCriteriaRequest, dict]): + The request object. Request message for + [CustomerNegativeCriterionService.MutateCustomerNegativeCriteria][google.ads.googleads.v23.services.CustomerNegativeCriterionService.MutateCustomerNegativeCriteria]. + customer_id (str): + Required. The ID of the customer + whose criteria are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerNegativeCriterionOperation]): + Required. The list of operations to + perform on individual criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerNegativeCriteriaResponse: + Response message for customer + negative criterion mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest, + ): + request = customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_negative_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerNegativeCriterionServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerNegativeCriterionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_negative_criterion_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/base.py new file mode 100644 index 000000000..58a08db04 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + customer_negative_criterion_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerNegativeCriterionServiceTransport(abc.ABC): + """Abstract transport class for CustomerNegativeCriterionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_negative_criteria: gapic_v1.method.wrap_method( + self.mutate_customer_negative_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_negative_criteria( + self, + ) -> Callable[ + [ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest + ], + Union[ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse, + Awaitable[ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerNegativeCriterionServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/grpc.py new file mode 100644 index 000000000..618a19304 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/grpc.py @@ -0,0 +1,396 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + customer_negative_criterion_service, +) +from .base import CustomerNegativeCriterionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerNegativeCriterionService", + "rpcName": str(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.ads.googleads.v23.services.CustomerNegativeCriterionService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerNegativeCriterionServiceGrpcTransport( + CustomerNegativeCriterionServiceTransport +): + """gRPC backend transport for CustomerNegativeCriterionService. + + Service to manage customer negative criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer_negative_criteria( + self, + ) -> Callable[ + [ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest + ], + customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse, + ]: + r"""Return a callable for the mutate customer negative + criteria method over gRPC. + + Creates or removes criteria. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerNegativeCriteriaRequest], + ~.MutateCustomerNegativeCriteriaResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_negative_criteria" not in self._stubs: + self._stubs["mutate_customer_negative_criteria"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerNegativeCriterionService/MutateCustomerNegativeCriteria", + request_serializer=customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest.serialize, + response_deserializer=customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_negative_criteria"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerNegativeCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..abe3d0e38 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_negative_criterion_service/transports/grpc_asyncio.py @@ -0,0 +1,419 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_negative_criterion_service, +) +from .base import CustomerNegativeCriterionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerNegativeCriterionService", + "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.ads.googleads.v23.services.CustomerNegativeCriterionService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerNegativeCriterionServiceGrpcAsyncIOTransport( + CustomerNegativeCriterionServiceTransport +): + """gRPC AsyncIO backend transport for CustomerNegativeCriterionService. + + Service to manage customer negative criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer_negative_criteria( + self, + ) -> Callable[ + [ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest + ], + Awaitable[ + customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse + ], + ]: + r"""Return a callable for the mutate customer negative + criteria method over gRPC. + + Creates or removes criteria. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerNegativeCriteriaRequest], + Awaitable[~.MutateCustomerNegativeCriteriaResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_negative_criteria" not in self._stubs: + self._stubs["mutate_customer_negative_criteria"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerNegativeCriterionService/MutateCustomerNegativeCriteria", + request_serializer=customer_negative_criterion_service.MutateCustomerNegativeCriteriaRequest.serialize, + response_deserializer=customer_negative_criterion_service.MutateCustomerNegativeCriteriaResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_negative_criteria"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer_negative_criteria: self._wrap_method( + self.mutate_customer_negative_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerNegativeCriterionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_service/__init__.py b/google/ads/googleads/v23/services/services/customer_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_service/async_client.py b/google/ads/googleads/v23/services/services/customer_service/async_client.py new file mode 100644 index 000000000..2e9808ed3 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_service/async_client.py @@ -0,0 +1,590 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.resources.types import customer +from google.ads.googleads.v23.services.types import customer_service +from .transports.base import CustomerServiceTransport, DEFAULT_CLIENT_INFO +from .client import CustomerServiceClient + +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 CustomerServiceAsyncClient: + """Service to manage customers.""" + + _client: CustomerServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomerServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CustomerServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomerServiceClient._DEFAULT_UNIVERSE + + conversion_action_path = staticmethod( + CustomerServiceClient.conversion_action_path + ) + parse_conversion_action_path = staticmethod( + CustomerServiceClient.parse_conversion_action_path + ) + customer_path = staticmethod(CustomerServiceClient.customer_path) + parse_customer_path = staticmethod( + CustomerServiceClient.parse_customer_path + ) + common_billing_account_path = staticmethod( + CustomerServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(CustomerServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + CustomerServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerServiceAsyncClient: The constructed client. + """ + return CustomerServiceClient.from_service_account_info.__func__(CustomerServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerServiceAsyncClient: The constructed client. + """ + return CustomerServiceClient.from_service_account_file.__func__(CustomerServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomerServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerServiceTransport, + Callable[..., CustomerServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerServiceTransport,Callable[..., CustomerServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerService", + "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.ads.googleads.v23.services.CustomerService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer( + self, + request: Optional[ + Union[customer_service.MutateCustomerRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[customer_service.CustomerOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_service.MutateCustomerResponse: + r"""Updates a customer. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UrlFieldError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerRequest, dict]]): + The request object. Request message for + [CustomerService.MutateCustomer][google.ads.googleads.v23.services.CustomerService.MutateCustomer]. + customer_id (:class:`str`): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (:class:`google.ads.googleads.v23.services.types.CustomerOperation`): + Required. The operation to perform on + the customer + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerResponse: + Response message for customer mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, customer_service.MutateCustomerRequest): + request = customer_service.MutateCustomerRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_accessible_customers( + self, + request: Optional[ + Union[customer_service.ListAccessibleCustomersRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_service.ListAccessibleCustomersResponse: + r"""Returns resource names of customers directly accessible by the + user authenticating the call. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListAccessibleCustomersRequest, dict]]): + The request object. Request message for + [CustomerService.ListAccessibleCustomers][google.ads.googleads.v23.services.CustomerService.ListAccessibleCustomers]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListAccessibleCustomersResponse: + Response message for + [CustomerService.ListAccessibleCustomers][google.ads.googleads.v23.services.CustomerService.ListAccessibleCustomers]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_service.ListAccessibleCustomersRequest + ): + request = customer_service.ListAccessibleCustomersRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_accessible_customers + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def create_customer_client( + self, + request: Optional[ + Union[customer_service.CreateCustomerClientRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + customer_client: Optional[customer.Customer] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_service.CreateCustomerClientResponse: + r"""Creates a new client under manager. The new client customer is + returned. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CurrencyCodeError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ `TimeZoneError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.CreateCustomerClientRequest, dict]]): + The request object. Request message for + [CustomerService.CreateCustomerClient][google.ads.googleads.v23.services.CustomerService.CreateCustomerClient]. + customer_id (:class:`str`): + Required. The ID of the Manager under + whom client customer is being created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + customer_client (:class:`google.ads.googleads.v23.resources.types.Customer`): + Required. The new client customer to + create. The resource name on this + customer will be ignored. + + This corresponds to the ``customer_client`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateCustomerClientResponse: + Response message for + CreateCustomerClient mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, customer_client] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_service.CreateCustomerClientRequest + ): + request = customer_service.CreateCustomerClientRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if customer_client is not None: + request.customer_client = customer_client + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_customer_client + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomerServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_service/client.py b/google/ads/googleads/v23/services/services/customer_service/client.py new file mode 100644 index 000000000..dac4d6573 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_service/client.py @@ -0,0 +1,1054 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.resources.types import customer +from google.ads.googleads.v23.services.types import customer_service +from .transports.base import CustomerServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CustomerServiceGrpcTransport +from .transports.grpc_asyncio import CustomerServiceGrpcAsyncIOTransport + + +class CustomerServiceClientMeta(type): + """Metaclass for the CustomerService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerServiceTransport]] + _transport_registry["grpc"] = CustomerServiceGrpcTransport + _transport_registry["grpc_asyncio"] = CustomerServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerServiceClient(metaclass=CustomerServiceClientMeta): + """Service to manage customers.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def conversion_action_path( + customer_id: str, + conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, + conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = CustomerServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = CustomerServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = CustomerServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CustomerServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + CustomerServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomerServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerServiceTransport, + Callable[..., CustomerServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerServiceTransport,Callable[..., CustomerServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomerServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomerServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = CustomerServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, CustomerServiceTransport) + if transport_provided: + # transport is a CustomerServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(CustomerServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerServiceTransport], + Callable[..., CustomerServiceTransport], + ] = ( + CustomerServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., CustomerServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerService", + "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.ads.googleads.v23.services.CustomerService", + "credentialsType": None, + } + ), + ) + + def mutate_customer( + self, + request: Optional[ + Union[customer_service.MutateCustomerRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[customer_service.CustomerOperation] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_service.MutateCustomerResponse: + r"""Updates a customer. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerRequest, dict]): + The request object. Request message for + [CustomerService.MutateCustomer][google.ads.googleads.v23.services.CustomerService.MutateCustomer]. + customer_id (str): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v23.services.types.CustomerOperation): + Required. The operation to perform on + the customer + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerResponse: + Response message for customer mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, customer_service.MutateCustomerRequest): + request = customer_service.MutateCustomerRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_customer] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_accessible_customers( + self, + request: Optional[ + Union[customer_service.ListAccessibleCustomersRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_service.ListAccessibleCustomersResponse: + r"""Returns resource names of customers directly accessible by the + user authenticating the call. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListAccessibleCustomersRequest, dict]): + The request object. Request message for + [CustomerService.ListAccessibleCustomers][google.ads.googleads.v23.services.CustomerService.ListAccessibleCustomers]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListAccessibleCustomersResponse: + Response message for + [CustomerService.ListAccessibleCustomers][google.ads.googleads.v23.services.CustomerService.ListAccessibleCustomers]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_service.ListAccessibleCustomersRequest + ): + request = customer_service.ListAccessibleCustomersRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_accessible_customers + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def create_customer_client( + self, + request: Optional[ + Union[customer_service.CreateCustomerClientRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + customer_client: Optional[customer.Customer] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_service.CreateCustomerClientResponse: + r"""Creates a new client under manager. The new client customer is + returned. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CurrencyCodeError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ `TimeZoneError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.CreateCustomerClientRequest, dict]): + The request object. Request message for + [CustomerService.CreateCustomerClient][google.ads.googleads.v23.services.CustomerService.CreateCustomerClient]. + customer_id (str): + Required. The ID of the Manager under + whom client customer is being created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + customer_client (google.ads.googleads.v23.resources.types.Customer): + Required. The new client customer to + create. The resource name on this + customer will be ignored. + + This corresponds to the ``customer_client`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateCustomerClientResponse: + Response message for + CreateCustomerClient mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, customer_client] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, customer_service.CreateCustomerClientRequest + ): + request = customer_service.CreateCustomerClientRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if customer_client is not None: + request.customer_client = customer_client + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_customer_client + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_service/transports/base.py new file mode 100644 index 000000000..bc4cafcb2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_service/transports/base.py @@ -0,0 +1,207 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import customer_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerServiceTransport(abc.ABC): + """Abstract transport class for CustomerService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer: gapic_v1.method.wrap_method( + self.mutate_customer, + default_timeout=None, + client_info=client_info, + ), + self.list_accessible_customers: gapic_v1.method.wrap_method( + self.list_accessible_customers, + default_timeout=None, + client_info=client_info, + ), + self.create_customer_client: gapic_v1.method.wrap_method( + self.create_customer_client, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer( + self, + ) -> Callable[ + [customer_service.MutateCustomerRequest], + Union[ + customer_service.MutateCustomerResponse, + Awaitable[customer_service.MutateCustomerResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_accessible_customers( + self, + ) -> Callable[ + [customer_service.ListAccessibleCustomersRequest], + Union[ + customer_service.ListAccessibleCustomersResponse, + Awaitable[customer_service.ListAccessibleCustomersResponse], + ], + ]: + raise NotImplementedError() + + @property + def create_customer_client( + self, + ) -> Callable[ + [customer_service.CreateCustomerClientRequest], + Union[ + customer_service.CreateCustomerClientResponse, + Awaitable[customer_service.CreateCustomerClientResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_service/transports/grpc.py new file mode 100644 index 000000000..89e3f8066 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_service/transports/grpc.py @@ -0,0 +1,460 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import customer_service +from .base import CustomerServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerService", + "rpcName": str(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.ads.googleads.v23.services.CustomerService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerServiceGrpcTransport(CustomerServiceTransport): + """gRPC backend transport for CustomerService. + + Service to manage customers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer( + self, + ) -> Callable[ + [customer_service.MutateCustomerRequest], + customer_service.MutateCustomerResponse, + ]: + r"""Return a callable for the mutate customer method over gRPC. + + Updates a customer. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateCustomerRequest], + ~.MutateCustomerResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer" not in self._stubs: + self._stubs["mutate_customer"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerService/MutateCustomer", + request_serializer=customer_service.MutateCustomerRequest.serialize, + response_deserializer=customer_service.MutateCustomerResponse.deserialize, + ) + return self._stubs["mutate_customer"] + + @property + def list_accessible_customers( + self, + ) -> Callable[ + [customer_service.ListAccessibleCustomersRequest], + customer_service.ListAccessibleCustomersResponse, + ]: + r"""Return a callable for the list accessible customers method over gRPC. + + Returns resource names of customers directly accessible by the + user authenticating the call. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListAccessibleCustomersRequest], + ~.ListAccessibleCustomersResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_accessible_customers" not in self._stubs: + self._stubs["list_accessible_customers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerService/ListAccessibleCustomers", + request_serializer=customer_service.ListAccessibleCustomersRequest.serialize, + response_deserializer=customer_service.ListAccessibleCustomersResponse.deserialize, + ) + ) + return self._stubs["list_accessible_customers"] + + @property + def create_customer_client( + self, + ) -> Callable[ + [customer_service.CreateCustomerClientRequest], + customer_service.CreateCustomerClientResponse, + ]: + r"""Return a callable for the create customer client method over gRPC. + + Creates a new client under manager. The new client customer is + returned. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CurrencyCodeError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ `TimeZoneError <>`__ + + Returns: + Callable[[~.CreateCustomerClientRequest], + ~.CreateCustomerClientResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_customer_client" not in self._stubs: + self._stubs["create_customer_client"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerService/CreateCustomerClient", + request_serializer=customer_service.CreateCustomerClientRequest.serialize, + response_deserializer=customer_service.CreateCustomerClientResponse.deserialize, + ) + ) + return self._stubs["create_customer_client"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..7e041a288 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_service/transports/grpc_asyncio.py @@ -0,0 +1,491 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import customer_service +from .base import CustomerServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerService", + "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.ads.googleads.v23.services.CustomerService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerServiceGrpcAsyncIOTransport(CustomerServiceTransport): + """gRPC AsyncIO backend transport for CustomerService. + + Service to manage customers. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer( + self, + ) -> Callable[ + [customer_service.MutateCustomerRequest], + Awaitable[customer_service.MutateCustomerResponse], + ]: + r"""Return a callable for the mutate customer method over gRPC. + + Updates a customer. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateCustomerRequest], + Awaitable[~.MutateCustomerResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer" not in self._stubs: + self._stubs["mutate_customer"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerService/MutateCustomer", + request_serializer=customer_service.MutateCustomerRequest.serialize, + response_deserializer=customer_service.MutateCustomerResponse.deserialize, + ) + return self._stubs["mutate_customer"] + + @property + def list_accessible_customers( + self, + ) -> Callable[ + [customer_service.ListAccessibleCustomersRequest], + Awaitable[customer_service.ListAccessibleCustomersResponse], + ]: + r"""Return a callable for the list accessible customers method over gRPC. + + Returns resource names of customers directly accessible by the + user authenticating the call. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListAccessibleCustomersRequest], + Awaitable[~.ListAccessibleCustomersResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_accessible_customers" not in self._stubs: + self._stubs["list_accessible_customers"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerService/ListAccessibleCustomers", + request_serializer=customer_service.ListAccessibleCustomersRequest.serialize, + response_deserializer=customer_service.ListAccessibleCustomersResponse.deserialize, + ) + ) + return self._stubs["list_accessible_customers"] + + @property + def create_customer_client( + self, + ) -> Callable[ + [customer_service.CreateCustomerClientRequest], + Awaitable[customer_service.CreateCustomerClientResponse], + ]: + r"""Return a callable for the create customer client method over gRPC. + + Creates a new client under manager. The new client customer is + returned. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `CurrencyCodeError <>`__ `HeaderError <>`__ `InternalError <>`__ + `ManagerLinkError <>`__ `QuotaError <>`__ `RequestError <>`__ + `StringLengthError <>`__ `TimeZoneError <>`__ + + Returns: + Callable[[~.CreateCustomerClientRequest], + Awaitable[~.CreateCustomerClientResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_customer_client" not in self._stubs: + self._stubs["create_customer_client"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerService/CreateCustomerClient", + request_serializer=customer_service.CreateCustomerClientRequest.serialize, + response_deserializer=customer_service.CreateCustomerClientResponse.deserialize, + ) + ) + return self._stubs["create_customer_client"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer: self._wrap_method( + self.mutate_customer, + default_timeout=None, + client_info=client_info, + ), + self.list_accessible_customers: self._wrap_method( + self.list_accessible_customers, + default_timeout=None, + client_info=client_info, + ), + self.create_customer_client: self._wrap_method( + self.create_customer_client, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/__init__.py b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/async_client.py b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/async_client.py new file mode 100644 index 000000000..9a27002b6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/async_client.py @@ -0,0 +1,412 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_sk_ad_network_conversion_value_schema_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerSkAdNetworkConversionValueSchemaServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomerSkAdNetworkConversionValueSchemaServiceClient + +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 CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient: + """Service to manage CustomerSkAdNetworkConversionValueSchema.""" + + _client: CustomerSkAdNetworkConversionValueSchemaServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient.DEFAULT_ENDPOINT + ) + DEFAULT_MTLS_ENDPOINT = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient._DEFAULT_UNIVERSE + ) + + customer_sk_ad_network_conversion_value_schema_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.customer_sk_ad_network_conversion_value_schema_path + ) + parse_customer_sk_ad_network_conversion_value_schema_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_customer_sk_ad_network_conversion_value_schema_path + ) + common_billing_account_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerSkAdNetworkConversionValueSchemaServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient: The constructed client. + """ + return CustomerSkAdNetworkConversionValueSchemaServiceClient.from_service_account_info.__func__(CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient: The constructed client. + """ + return CustomerSkAdNetworkConversionValueSchemaServiceClient.from_service_account_file.__func__(CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerSkAdNetworkConversionValueSchemaServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport( + self, + ) -> CustomerSkAdNetworkConversionValueSchemaServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerSkAdNetworkConversionValueSchemaServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerSkAdNetworkConversionValueSchemaServiceTransport, + Callable[ + ..., + CustomerSkAdNetworkConversionValueSchemaServiceTransport, + ], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer sk ad network conversion value schema service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerSkAdNetworkConversionValueSchemaServiceTransport,Callable[..., CustomerSkAdNetworkConversionValueSchemaServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerSkAdNetworkConversionValueSchemaServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerSkAdNetworkConversionValueSchemaServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService", + "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.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer_sk_ad_network_conversion_value_schema( + self, + request: Optional[ + Union[ + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse + ): + r"""Creates or updates the CustomerSkAdNetworkConversionValueSchema. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `InternalError <>`__ + `MutateError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerSkAdNetworkConversionValueSchemaRequest, dict]]): + The request object. Request message for + [CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema][google.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerSkAdNetworkConversionValueSchemaResponse: + Response message for + MutateCustomerSkAdNetworkConversionValueSchema. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest, + ): + request = customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer_sk_ad_network_conversion_value_schema + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__( + self, + ) -> "CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerSkAdNetworkConversionValueSchemaServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/client.py b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/client.py new file mode 100644 index 000000000..f41d9248e --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/client.py @@ -0,0 +1,895 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + customer_sk_ad_network_conversion_value_schema_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomerSkAdNetworkConversionValueSchemaServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ( + CustomerSkAdNetworkConversionValueSchemaServiceGrpcTransport, +) +from .transports.grpc_asyncio import ( + CustomerSkAdNetworkConversionValueSchemaServiceGrpcAsyncIOTransport, +) + + +class CustomerSkAdNetworkConversionValueSchemaServiceClientMeta(type): + """Metaclass for the CustomerSkAdNetworkConversionValueSchemaService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerSkAdNetworkConversionValueSchemaServiceTransport]] + _transport_registry["grpc"] = ( + CustomerSkAdNetworkConversionValueSchemaServiceGrpcTransport + ) + _transport_registry["grpc_asyncio"] = ( + CustomerSkAdNetworkConversionValueSchemaServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerSkAdNetworkConversionValueSchemaServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerSkAdNetworkConversionValueSchemaServiceClient( + metaclass=CustomerSkAdNetworkConversionValueSchemaServiceClientMeta +): + """Service to manage CustomerSkAdNetworkConversionValueSchema.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerSkAdNetworkConversionValueSchemaServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerSkAdNetworkConversionValueSchemaServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport( + self, + ) -> CustomerSkAdNetworkConversionValueSchemaServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerSkAdNetworkConversionValueSchemaServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_sk_ad_network_conversion_value_schema_path( + customer_id: str, + account_link_id: str, + ) -> str: + """Returns a fully-qualified customer_sk_ad_network_conversion_value_schema string.""" + return "customers/{customer_id}/customerSkAdNetworkConversionValueSchemas/{account_link_id}".format( + customer_id=customer_id, + account_link_id=account_link_id, + ) + + @staticmethod + def parse_customer_sk_ad_network_conversion_value_schema_path( + path: str, + ) -> Dict[str, str]: + """Parses a customer_sk_ad_network_conversion_value_schema path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerSkAdNetworkConversionValueSchemas/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = CustomerSkAdNetworkConversionValueSchemaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerSkAdNetworkConversionValueSchemaServiceTransport, + Callable[ + ..., + CustomerSkAdNetworkConversionValueSchemaServiceTransport, + ], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer sk ad network conversion value schema service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerSkAdNetworkConversionValueSchemaServiceTransport,Callable[..., CustomerSkAdNetworkConversionValueSchemaServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerSkAdNetworkConversionValueSchemaServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient._read_environment_variables() + ) + self._client_cert_source = CustomerSkAdNetworkConversionValueSchemaServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = CustomerSkAdNetworkConversionValueSchemaServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerSkAdNetworkConversionValueSchemaServiceTransport + ) + if transport_provided: + # transport is a CustomerSkAdNetworkConversionValueSchemaServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CustomerSkAdNetworkConversionValueSchemaServiceTransport, + transport, + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerSkAdNetworkConversionValueSchemaServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerSkAdNetworkConversionValueSchemaServiceTransport], + Callable[ + ..., + CustomerSkAdNetworkConversionValueSchemaServiceTransport, + ], + ] = ( + CustomerSkAdNetworkConversionValueSchemaServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[ + ..., + CustomerSkAdNetworkConversionValueSchemaServiceTransport, + ], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService", + "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.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService", + "credentialsType": None, + } + ), + ) + + def mutate_customer_sk_ad_network_conversion_value_schema( + self, + request: Optional[ + Union[ + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse + ): + r"""Creates or updates the CustomerSkAdNetworkConversionValueSchema. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `InternalError <>`__ + `MutateError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerSkAdNetworkConversionValueSchemaRequest, dict]): + The request object. Request message for + [CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema][google.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerSkAdNetworkConversionValueSchemaResponse: + Response message for + MutateCustomerSkAdNetworkConversionValueSchema. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest, + ): + request = customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_sk_ad_network_conversion_value_schema + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__( + self, + ) -> "CustomerSkAdNetworkConversionValueSchemaServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerSkAdNetworkConversionValueSchemaServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/base.py new file mode 100644 index 000000000..0e201e6a8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + customer_sk_ad_network_conversion_value_schema_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerSkAdNetworkConversionValueSchemaServiceTransport(abc.ABC): + """Abstract transport class for CustomerSkAdNetworkConversionValueSchemaService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_sk_ad_network_conversion_value_schema: gapic_v1.method.wrap_method( + self.mutate_customer_sk_ad_network_conversion_value_schema, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_sk_ad_network_conversion_value_schema( + self, + ) -> Callable[ + [ + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest + ], + Union[ + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse, + Awaitable[ + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerSkAdNetworkConversionValueSchemaServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc.py new file mode 100644 index 000000000..fb67325f9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc.py @@ -0,0 +1,402 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + customer_sk_ad_network_conversion_value_schema_service, +) +from .base import ( + CustomerSkAdNetworkConversionValueSchemaServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService", + "rpcName": str(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.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerSkAdNetworkConversionValueSchemaServiceGrpcTransport( + CustomerSkAdNetworkConversionValueSchemaServiceTransport +): + """gRPC backend transport for CustomerSkAdNetworkConversionValueSchemaService. + + Service to manage CustomerSkAdNetworkConversionValueSchema. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer_sk_ad_network_conversion_value_schema( + self, + ) -> Callable[ + [ + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest + ], + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse, + ]: + r"""Return a callable for the mutate customer sk ad network + conversion value schema method over gRPC. + + Creates or updates the CustomerSkAdNetworkConversionValueSchema. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `InternalError <>`__ + `MutateError <>`__ + + Returns: + Callable[[~.MutateCustomerSkAdNetworkConversionValueSchemaRequest], + ~.MutateCustomerSkAdNetworkConversionValueSchemaResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if ( + "mutate_customer_sk_ad_network_conversion_value_schema" + not in self._stubs + ): + self._stubs[ + "mutate_customer_sk_ad_network_conversion_value_schema" + ] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService/MutateCustomerSkAdNetworkConversionValueSchema", + request_serializer=customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest.serialize, + response_deserializer=customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse.deserialize, + ) + return self._stubs[ + "mutate_customer_sk_ad_network_conversion_value_schema" + ] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerSkAdNetworkConversionValueSchemaServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..d426acf26 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_sk_ad_network_conversion_value_schema_service/transports/grpc_asyncio.py @@ -0,0 +1,427 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_sk_ad_network_conversion_value_schema_service, +) +from .base import ( + CustomerSkAdNetworkConversionValueSchemaServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService", + "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.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerSkAdNetworkConversionValueSchemaServiceGrpcAsyncIOTransport( + CustomerSkAdNetworkConversionValueSchemaServiceTransport +): + """gRPC AsyncIO backend transport for CustomerSkAdNetworkConversionValueSchemaService. + + Service to manage CustomerSkAdNetworkConversionValueSchema. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer_sk_ad_network_conversion_value_schema( + self, + ) -> Callable[ + [ + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest + ], + Awaitable[ + customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse + ], + ]: + r"""Return a callable for the mutate customer sk ad network + conversion value schema method over gRPC. + + Creates or updates the CustomerSkAdNetworkConversionValueSchema. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `InternalError <>`__ + `MutateError <>`__ + + Returns: + Callable[[~.MutateCustomerSkAdNetworkConversionValueSchemaRequest], + Awaitable[~.MutateCustomerSkAdNetworkConversionValueSchemaResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if ( + "mutate_customer_sk_ad_network_conversion_value_schema" + not in self._stubs + ): + self._stubs[ + "mutate_customer_sk_ad_network_conversion_value_schema" + ] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService/MutateCustomerSkAdNetworkConversionValueSchema", + request_serializer=customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaRequest.serialize, + response_deserializer=customer_sk_ad_network_conversion_value_schema_service.MutateCustomerSkAdNetworkConversionValueSchemaResponse.deserialize, + ) + return self._stubs[ + "mutate_customer_sk_ad_network_conversion_value_schema" + ] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer_sk_ad_network_conversion_value_schema: self._wrap_method( + self.mutate_customer_sk_ad_network_conversion_value_schema, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ( + "CustomerSkAdNetworkConversionValueSchemaServiceGrpcAsyncIOTransport", +) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/__init__.py b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_user_access_invitation_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_user_access_invitation_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/async_client.py b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/async_client.py new file mode 100644 index 000000000..26c32266b --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/async_client.py @@ -0,0 +1,447 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_user_access_invitation_service, +) +from .transports.base import ( + CustomerUserAccessInvitationServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomerUserAccessInvitationServiceClient + +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 CustomerUserAccessInvitationServiceAsyncClient: + """This service manages the access invitation extended to users + for a given customer. + """ + + _client: CustomerUserAccessInvitationServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ( + CustomerUserAccessInvitationServiceClient.DEFAULT_ENDPOINT + ) + DEFAULT_MTLS_ENDPOINT = ( + CustomerUserAccessInvitationServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerUserAccessInvitationServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ( + CustomerUserAccessInvitationServiceClient._DEFAULT_UNIVERSE + ) + + customer_user_access_invitation_path = staticmethod( + CustomerUserAccessInvitationServiceClient.customer_user_access_invitation_path + ) + parse_customer_user_access_invitation_path = staticmethod( + CustomerUserAccessInvitationServiceClient.parse_customer_user_access_invitation_path + ) + common_billing_account_path = staticmethod( + CustomerUserAccessInvitationServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerUserAccessInvitationServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerUserAccessInvitationServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerUserAccessInvitationServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerUserAccessInvitationServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerUserAccessInvitationServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerUserAccessInvitationServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerUserAccessInvitationServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerUserAccessInvitationServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerUserAccessInvitationServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessInvitationServiceAsyncClient: The constructed client. + """ + return CustomerUserAccessInvitationServiceClient.from_service_account_info.__func__(CustomerUserAccessInvitationServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessInvitationServiceAsyncClient: The constructed client. + """ + return CustomerUserAccessInvitationServiceClient.from_service_account_file.__func__(CustomerUserAccessInvitationServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerUserAccessInvitationServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerUserAccessInvitationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerUserAccessInvitationServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + CustomerUserAccessInvitationServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerUserAccessInvitationServiceTransport, + Callable[..., CustomerUserAccessInvitationServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer user access invitation service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerUserAccessInvitationServiceTransport,Callable[..., CustomerUserAccessInvitationServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerUserAccessInvitationServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerUserAccessInvitationServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerUserAccessInvitationServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerUserAccessInvitationService", + "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.ads.googleads.v23.services.CustomerUserAccessInvitationService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer_user_access_invitation( + self, + request: Optional[ + Union[ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + customer_user_access_invitation_service.CustomerUserAccessInvitationOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse + ): + r"""Creates or removes an access invitation. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerUserAccessInvitationRequest, dict]]): + The request object. Request message for + [CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation][google.ads.googleads.v23.services.CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation] + customer_id (:class:`str`): + Required. The ID of the customer + whose access invitation is being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (:class:`google.ads.googleads.v23.services.types.CustomerUserAccessInvitationOperation`): + Required. The operation to perform on + the access invitation + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerUserAccessInvitationResponse: + Response message for access + invitation mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest, + ): + request = customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer_user_access_invitation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__( + self, + ) -> "CustomerUserAccessInvitationServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerUserAccessInvitationServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/client.py b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/client.py new file mode 100644 index 000000000..67e5e0087 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/client.py @@ -0,0 +1,920 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + customer_user_access_invitation_service, +) +from .transports.base import ( + CustomerUserAccessInvitationServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerUserAccessInvitationServiceGrpcTransport +from .transports.grpc_asyncio import ( + CustomerUserAccessInvitationServiceGrpcAsyncIOTransport, +) + + +class CustomerUserAccessInvitationServiceClientMeta(type): + """Metaclass for the CustomerUserAccessInvitationService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerUserAccessInvitationServiceTransport]] + _transport_registry["grpc"] = ( + CustomerUserAccessInvitationServiceGrpcTransport + ) + _transport_registry["grpc_asyncio"] = ( + CustomerUserAccessInvitationServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerUserAccessInvitationServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerUserAccessInvitationServiceClient( + metaclass=CustomerUserAccessInvitationServiceClientMeta +): + """This service manages the access invitation extended to users + for a given customer. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessInvitationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessInvitationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerUserAccessInvitationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerUserAccessInvitationServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_user_access_invitation_path( + customer_id: str, + invitation_id: str, + ) -> str: + """Returns a fully-qualified customer_user_access_invitation string.""" + return "customers/{customer_id}/customerUserAccessInvitations/{invitation_id}".format( + customer_id=customer_id, + invitation_id=invitation_id, + ) + + @staticmethod + def parse_customer_user_access_invitation_path(path: str) -> Dict[str, str]: + """Parses a customer_user_access_invitation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerUserAccessInvitations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerUserAccessInvitationServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerUserAccessInvitationServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CustomerUserAccessInvitationServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + CustomerUserAccessInvitationServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = CustomerUserAccessInvitationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + CustomerUserAccessInvitationServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerUserAccessInvitationServiceTransport, + Callable[..., CustomerUserAccessInvitationServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer user access invitation service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerUserAccessInvitationServiceTransport,Callable[..., CustomerUserAccessInvitationServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerUserAccessInvitationServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ( + CustomerUserAccessInvitationServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + CustomerUserAccessInvitationServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomerUserAccessInvitationServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerUserAccessInvitationServiceTransport + ) + if transport_provided: + # transport is a CustomerUserAccessInvitationServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CustomerUserAccessInvitationServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerUserAccessInvitationServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerUserAccessInvitationServiceTransport], + Callable[..., CustomerUserAccessInvitationServiceTransport], + ] = ( + CustomerUserAccessInvitationServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomerUserAccessInvitationServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerUserAccessInvitationServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerUserAccessInvitationService", + "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.ads.googleads.v23.services.CustomerUserAccessInvitationService", + "credentialsType": None, + } + ), + ) + + def mutate_customer_user_access_invitation( + self, + request: Optional[ + Union[ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + customer_user_access_invitation_service.CustomerUserAccessInvitationOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse + ): + r"""Creates or removes an access invitation. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerUserAccessInvitationRequest, dict]): + The request object. Request message for + [CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation][google.ads.googleads.v23.services.CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation] + customer_id (str): + Required. The ID of the customer + whose access invitation is being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v23.services.types.CustomerUserAccessInvitationOperation): + Required. The operation to perform on + the access invitation + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerUserAccessInvitationResponse: + Response message for access + invitation mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest, + ): + request = customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_user_access_invitation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerUserAccessInvitationServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerUserAccessInvitationServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_user_access_invitation_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/base.py new file mode 100644 index 000000000..2c88e8199 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + customer_user_access_invitation_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerUserAccessInvitationServiceTransport(abc.ABC): + """Abstract transport class for CustomerUserAccessInvitationService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_user_access_invitation: gapic_v1.method.wrap_method( + self.mutate_customer_user_access_invitation, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_user_access_invitation( + self, + ) -> Callable[ + [ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest + ], + Union[ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse, + Awaitable[ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerUserAccessInvitationServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/grpc.py new file mode 100644 index 000000000..9803fa5be --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/grpc.py @@ -0,0 +1,399 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + customer_user_access_invitation_service, +) +from .base import ( + CustomerUserAccessInvitationServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerUserAccessInvitationService", + "rpcName": str(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.ads.googleads.v23.services.CustomerUserAccessInvitationService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerUserAccessInvitationServiceGrpcTransport( + CustomerUserAccessInvitationServiceTransport +): + """gRPC backend transport for CustomerUserAccessInvitationService. + + This service manages the access invitation extended to users + for a given customer. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer_user_access_invitation( + self, + ) -> Callable[ + [ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest + ], + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse, + ]: + r"""Return a callable for the mutate customer user access + invitation method over gRPC. + + Creates or removes an access invitation. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerUserAccessInvitationRequest], + ~.MutateCustomerUserAccessInvitationResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_user_access_invitation" not in self._stubs: + self._stubs["mutate_customer_user_access_invitation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerUserAccessInvitationService/MutateCustomerUserAccessInvitation", + request_serializer=customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest.serialize, + response_deserializer=customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_user_access_invitation"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerUserAccessInvitationServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..d81ee12ae --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_user_access_invitation_service/transports/grpc_asyncio.py @@ -0,0 +1,422 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + customer_user_access_invitation_service, +) +from .base import ( + CustomerUserAccessInvitationServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerUserAccessInvitationService", + "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.ads.googleads.v23.services.CustomerUserAccessInvitationService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerUserAccessInvitationServiceGrpcAsyncIOTransport( + CustomerUserAccessInvitationServiceTransport +): + """gRPC AsyncIO backend transport for CustomerUserAccessInvitationService. + + This service manages the access invitation extended to users + for a given customer. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer_user_access_invitation( + self, + ) -> Callable[ + [ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest + ], + Awaitable[ + customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse + ], + ]: + r"""Return a callable for the mutate customer user access + invitation method over gRPC. + + Creates or removes an access invitation. + + List of thrown errors: `AccessInvitationError <>`__ + `AuthenticationError <>`__ `AuthorizationError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerUserAccessInvitationRequest], + Awaitable[~.MutateCustomerUserAccessInvitationResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_user_access_invitation" not in self._stubs: + self._stubs["mutate_customer_user_access_invitation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerUserAccessInvitationService/MutateCustomerUserAccessInvitation", + request_serializer=customer_user_access_invitation_service.MutateCustomerUserAccessInvitationRequest.serialize, + response_deserializer=customer_user_access_invitation_service.MutateCustomerUserAccessInvitationResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_user_access_invitation"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer_user_access_invitation: self._wrap_method( + self.mutate_customer_user_access_invitation, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerUserAccessInvitationServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_service/__init__.py b/google/ads/googleads/v23/services/services/customer_user_access_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_user_access_service/__init__.py rename to google/ads/googleads/v23/services/services/customer_user_access_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_user_access_service/async_client.py b/google/ads/googleads/v23/services/services/customer_user_access_service/async_client.py new file mode 100644 index 000000000..c2ed8faf1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_user_access_service/async_client.py @@ -0,0 +1,437 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import customer_user_access_service +from .transports.base import ( + CustomerUserAccessServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomerUserAccessServiceClient + +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 CustomerUserAccessServiceAsyncClient: + """This service manages the permissions of a user on a given + customer. + """ + + _client: CustomerUserAccessServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomerUserAccessServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CustomerUserAccessServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomerUserAccessServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomerUserAccessServiceClient._DEFAULT_UNIVERSE + + customer_user_access_path = staticmethod( + CustomerUserAccessServiceClient.customer_user_access_path + ) + parse_customer_user_access_path = staticmethod( + CustomerUserAccessServiceClient.parse_customer_user_access_path + ) + common_billing_account_path = staticmethod( + CustomerUserAccessServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomerUserAccessServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomerUserAccessServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomerUserAccessServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomerUserAccessServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomerUserAccessServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomerUserAccessServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomerUserAccessServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomerUserAccessServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomerUserAccessServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessServiceAsyncClient: The constructed client. + """ + return CustomerUserAccessServiceClient.from_service_account_info.__func__(CustomerUserAccessServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessServiceAsyncClient: The constructed client. + """ + return CustomerUserAccessServiceClient.from_service_account_file.__func__(CustomerUserAccessServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomerUserAccessServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomerUserAccessServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerUserAccessServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomerUserAccessServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerUserAccessServiceTransport, + Callable[..., CustomerUserAccessServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer user access service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerUserAccessServiceTransport,Callable[..., CustomerUserAccessServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerUserAccessServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomerUserAccessServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomerUserAccessServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerUserAccessService", + "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.ads.googleads.v23.services.CustomerUserAccessService", + "credentialsType": None, + } + ), + ) + + async def mutate_customer_user_access( + self, + request: Optional[ + Union[ + customer_user_access_service.MutateCustomerUserAccessRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + customer_user_access_service.CustomerUserAccessOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_user_access_service.MutateCustomerUserAccessResponse: + r"""Updates, removes permission of a user on a given customer. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomerUserAccessError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomerUserAccessRequest, dict]]): + The request object. Mutate Request for + [CustomerUserAccessService.MutateCustomerUserAccess][google.ads.googleads.v23.services.CustomerUserAccessService.MutateCustomerUserAccess]. + customer_id (:class:`str`): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (:class:`google.ads.googleads.v23.services.types.CustomerUserAccessOperation`): + Required. The operation to perform on + the customer + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerUserAccessResponse: + Response message for customer user + access mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_user_access_service.MutateCustomerUserAccessRequest, + ): + request = ( + customer_user_access_service.MutateCustomerUserAccessRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customer_user_access + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomerUserAccessServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomerUserAccessServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customer_user_access_service/client.py b/google/ads/googleads/v23/services/services/customer_user_access_service/client.py new file mode 100644 index 000000000..795c5d62b --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_user_access_service/client.py @@ -0,0 +1,907 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import customer_user_access_service +from .transports.base import ( + CustomerUserAccessServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomerUserAccessServiceGrpcTransport +from .transports.grpc_asyncio import ( + CustomerUserAccessServiceGrpcAsyncIOTransport, +) + + +class CustomerUserAccessServiceClientMeta(type): + """Metaclass for the CustomerUserAccessService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomerUserAccessServiceTransport]] + _transport_registry["grpc"] = CustomerUserAccessServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomerUserAccessServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomerUserAccessServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomerUserAccessServiceClient( + metaclass=CustomerUserAccessServiceClientMeta +): + """This service manages the permissions of a user on a given + customer. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomerUserAccessServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomerUserAccessServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomerUserAccessServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_user_access_path( + customer_id: str, + user_id: str, + ) -> str: + """Returns a fully-qualified customer_user_access string.""" + return "customers/{customer_id}/customerUserAccesses/{user_id}".format( + customer_id=customer_id, + user_id=user_id, + ) + + @staticmethod + def parse_customer_user_access_path(path: str) -> Dict[str, str]: + """Parses a customer_user_access path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerUserAccesses/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomerUserAccessServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomerUserAccessServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CustomerUserAccessServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = CustomerUserAccessServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = CustomerUserAccessServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomerUserAccessServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomerUserAccessServiceTransport, + Callable[..., CustomerUserAccessServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customer user access service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomerUserAccessServiceTransport,Callable[..., CustomerUserAccessServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomerUserAccessServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomerUserAccessServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomerUserAccessServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomerUserAccessServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomerUserAccessServiceTransport + ) + if transport_provided: + # transport is a CustomerUserAccessServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CustomerUserAccessServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomerUserAccessServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomerUserAccessServiceTransport], + Callable[..., CustomerUserAccessServiceTransport], + ] = ( + CustomerUserAccessServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomerUserAccessServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomerUserAccessServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomerUserAccessService", + "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.ads.googleads.v23.services.CustomerUserAccessService", + "credentialsType": None, + } + ), + ) + + def mutate_customer_user_access( + self, + request: Optional[ + Union[ + customer_user_access_service.MutateCustomerUserAccessRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operation: Optional[ + customer_user_access_service.CustomerUserAccessOperation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customer_user_access_service.MutateCustomerUserAccessResponse: + r"""Updates, removes permission of a user on a given customer. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomerUserAccessError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomerUserAccessRequest, dict]): + The request object. Mutate Request for + [CustomerUserAccessService.MutateCustomerUserAccess][google.ads.googleads.v23.services.CustomerUserAccessService.MutateCustomerUserAccess]. + customer_id (str): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operation (google.ads.googleads.v23.services.types.CustomerUserAccessOperation): + Required. The operation to perform on + the customer + + This corresponds to the ``operation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomerUserAccessResponse: + Response message for customer user + access mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customer_user_access_service.MutateCustomerUserAccessRequest, + ): + request = ( + customer_user_access_service.MutateCustomerUserAccessRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operation is not None: + request.operation = operation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customer_user_access + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomerUserAccessServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomerUserAccessServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customer_user_access_service/transports/README.rst b/google/ads/googleads/v23/services/services/customer_user_access_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customer_user_access_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customer_user_access_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customer_user_access_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customer_user_access_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customer_user_access_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customer_user_access_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customer_user_access_service/transports/base.py b/google/ads/googleads/v23/services/services/customer_user_access_service/transports/base.py new file mode 100644 index 000000000..a4ed7f6e8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_user_access_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import customer_user_access_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomerUserAccessServiceTransport(abc.ABC): + """Abstract transport class for CustomerUserAccessService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customer_user_access: gapic_v1.method.wrap_method( + self.mutate_customer_user_access, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customer_user_access( + self, + ) -> Callable[ + [customer_user_access_service.MutateCustomerUserAccessRequest], + Union[ + customer_user_access_service.MutateCustomerUserAccessResponse, + Awaitable[ + customer_user_access_service.MutateCustomerUserAccessResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomerUserAccessServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_user_access_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customer_user_access_service/transports/grpc.py new file mode 100644 index 000000000..5ea28aaea --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_user_access_service/transports/grpc.py @@ -0,0 +1,392 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import customer_user_access_service +from .base import CustomerUserAccessServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomerUserAccessService", + "rpcName": str(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.ads.googleads.v23.services.CustomerUserAccessService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerUserAccessServiceGrpcTransport( + CustomerUserAccessServiceTransport +): + """gRPC backend transport for CustomerUserAccessService. + + This service manages the permissions of a user on a given + customer. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customer_user_access( + self, + ) -> Callable[ + [customer_user_access_service.MutateCustomerUserAccessRequest], + customer_user_access_service.MutateCustomerUserAccessResponse, + ]: + r"""Return a callable for the mutate customer user access method over gRPC. + + Updates, removes permission of a user on a given customer. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomerUserAccessError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerUserAccessRequest], + ~.MutateCustomerUserAccessResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_user_access" not in self._stubs: + self._stubs["mutate_customer_user_access"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerUserAccessService/MutateCustomerUserAccess", + request_serializer=customer_user_access_service.MutateCustomerUserAccessRequest.serialize, + response_deserializer=customer_user_access_service.MutateCustomerUserAccessResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_user_access"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomerUserAccessServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customer_user_access_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customer_user_access_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..835bcfce7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customer_user_access_service/transports/grpc_asyncio.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import customer_user_access_service +from .base import CustomerUserAccessServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomerUserAccessService", + "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.ads.googleads.v23.services.CustomerUserAccessService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomerUserAccessServiceGrpcAsyncIOTransport( + CustomerUserAccessServiceTransport +): + """gRPC AsyncIO backend transport for CustomerUserAccessService. + + This service manages the permissions of a user on a given + customer. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customer_user_access( + self, + ) -> Callable[ + [customer_user_access_service.MutateCustomerUserAccessRequest], + Awaitable[ + customer_user_access_service.MutateCustomerUserAccessResponse + ], + ]: + r"""Return a callable for the mutate customer user access method over gRPC. + + Updates, removes permission of a user on a given customer. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CustomerUserAccessError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.MutateCustomerUserAccessRequest], + Awaitable[~.MutateCustomerUserAccessResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customer_user_access" not in self._stubs: + self._stubs["mutate_customer_user_access"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomerUserAccessService/MutateCustomerUserAccess", + request_serializer=customer_user_access_service.MutateCustomerUserAccessRequest.serialize, + response_deserializer=customer_user_access_service.MutateCustomerUserAccessResponse.deserialize, + ) + ) + return self._stubs["mutate_customer_user_access"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customer_user_access: self._wrap_method( + self.mutate_customer_user_access, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomerUserAccessServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/customizer_attribute_service/__init__.py b/google/ads/googleads/v23/services/services/customizer_attribute_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customizer_attribute_service/__init__.py rename to google/ads/googleads/v23/services/services/customizer_attribute_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/customizer_attribute_service/async_client.py b/google/ads/googleads/v23/services/services/customizer_attribute_service/async_client.py new file mode 100644 index 000000000..7ea618485 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customizer_attribute_service/async_client.py @@ -0,0 +1,435 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import customizer_attribute_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomizerAttributeServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import CustomizerAttributeServiceClient + +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 CustomizerAttributeServiceAsyncClient: + """Service to manage customizer attribute""" + + _client: CustomizerAttributeServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = CustomizerAttributeServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + CustomizerAttributeServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + CustomizerAttributeServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = CustomizerAttributeServiceClient._DEFAULT_UNIVERSE + + customizer_attribute_path = staticmethod( + CustomizerAttributeServiceClient.customizer_attribute_path + ) + parse_customizer_attribute_path = staticmethod( + CustomizerAttributeServiceClient.parse_customizer_attribute_path + ) + common_billing_account_path = staticmethod( + CustomizerAttributeServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + CustomizerAttributeServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + CustomizerAttributeServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + CustomizerAttributeServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + CustomizerAttributeServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + CustomizerAttributeServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + CustomizerAttributeServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + CustomizerAttributeServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + CustomizerAttributeServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + CustomizerAttributeServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomizerAttributeServiceAsyncClient: The constructed client. + """ + return CustomizerAttributeServiceClient.from_service_account_info.__func__(CustomizerAttributeServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomizerAttributeServiceAsyncClient: The constructed client. + """ + return CustomizerAttributeServiceClient.from_service_account_file.__func__(CustomizerAttributeServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return CustomizerAttributeServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CustomizerAttributeServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomizerAttributeServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = CustomizerAttributeServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomizerAttributeServiceTransport, + Callable[..., CustomizerAttributeServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customizer attribute service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomizerAttributeServiceTransport,Callable[..., CustomizerAttributeServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomizerAttributeServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = CustomizerAttributeServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.CustomizerAttributeServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomizerAttributeService", + "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.ads.googleads.v23.services.CustomizerAttributeService", + "credentialsType": None, + } + ), + ) + + async def mutate_customizer_attributes( + self, + request: Optional[ + Union[ + customizer_attribute_service.MutateCustomizerAttributesRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customizer_attribute_service.CustomizerAttributeOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customizer_attribute_service.MutateCustomizerAttributesResponse: + r"""Creates, updates or removes customizer attributes. + Operation statuses are returned. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateCustomizerAttributesRequest, dict]]): + The request object. Request message for + [CustomizerAttributeService.MutateCustomizerAttributes][google.ads.googleads.v23.services.CustomizerAttributeService.MutateCustomizerAttributes]. + customer_id (:class:`str`): + Required. The ID of the customer + whose customizer attributes are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.CustomizerAttributeOperation]`): + Required. The list of operations to + perform on individual customizer + attributes. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomizerAttributesResponse: + Response message for a customizer + attribute mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customizer_attribute_service.MutateCustomizerAttributesRequest, + ): + request = ( + customizer_attribute_service.MutateCustomizerAttributesRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_customizer_attributes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CustomizerAttributeServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("CustomizerAttributeServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/customizer_attribute_service/client.py b/google/ads/googleads/v23/services/services/customizer_attribute_service/client.py new file mode 100644 index 000000000..2c49d0c10 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customizer_attribute_service/client.py @@ -0,0 +1,918 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import customizer_attribute_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + CustomizerAttributeServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import CustomizerAttributeServiceGrpcTransport +from .transports.grpc_asyncio import ( + CustomizerAttributeServiceGrpcAsyncIOTransport, +) + + +class CustomizerAttributeServiceClientMeta(type): + """Metaclass for the CustomizerAttributeService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[CustomizerAttributeServiceTransport]] + _transport_registry["grpc"] = CustomizerAttributeServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + CustomizerAttributeServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[CustomizerAttributeServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class CustomizerAttributeServiceClient( + metaclass=CustomizerAttributeServiceClientMeta +): + """Service to manage customizer attribute""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomizerAttributeServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CustomizerAttributeServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> CustomizerAttributeServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CustomizerAttributeServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customizer_attribute_path( + customer_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + CustomizerAttributeServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + CustomizerAttributeServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + CustomizerAttributeServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + CustomizerAttributeServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = CustomizerAttributeServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = CustomizerAttributeServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + CustomizerAttributeServiceTransport, + Callable[..., CustomizerAttributeServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the customizer attribute service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,CustomizerAttributeServiceTransport,Callable[..., CustomizerAttributeServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the CustomizerAttributeServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = CustomizerAttributeServiceClient._read_environment_variables() + self._client_cert_source = ( + CustomizerAttributeServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + CustomizerAttributeServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, CustomizerAttributeServiceTransport + ) + if transport_provided: + # transport is a CustomizerAttributeServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + CustomizerAttributeServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or CustomizerAttributeServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[CustomizerAttributeServiceTransport], + Callable[..., CustomizerAttributeServiceTransport], + ] = ( + CustomizerAttributeServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., CustomizerAttributeServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.CustomizerAttributeServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.CustomizerAttributeService", + "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.ads.googleads.v23.services.CustomizerAttributeService", + "credentialsType": None, + } + ), + ) + + def mutate_customizer_attributes( + self, + request: Optional[ + Union[ + customizer_attribute_service.MutateCustomizerAttributesRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + customizer_attribute_service.CustomizerAttributeOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> customizer_attribute_service.MutateCustomizerAttributesResponse: + r"""Creates, updates or removes customizer attributes. + Operation statuses are returned. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateCustomizerAttributesRequest, dict]): + The request object. Request message for + [CustomizerAttributeService.MutateCustomizerAttributes][google.ads.googleads.v23.services.CustomizerAttributeService.MutateCustomizerAttributes]. + customer_id (str): + Required. The ID of the customer + whose customizer attributes are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomizerAttributeOperation]): + Required. The list of operations to + perform on individual customizer + attributes. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateCustomizerAttributesResponse: + Response message for a customizer + attribute mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + customizer_attribute_service.MutateCustomizerAttributesRequest, + ): + request = ( + customizer_attribute_service.MutateCustomizerAttributesRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_customizer_attributes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CustomizerAttributeServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("CustomizerAttributeServiceClient",) diff --git a/google/ads/googleads/v19/services/services/customizer_attribute_service/transports/README.rst b/google/ads/googleads/v23/services/services/customizer_attribute_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/customizer_attribute_service/transports/README.rst rename to google/ads/googleads/v23/services/services/customizer_attribute_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/customizer_attribute_service/transports/__init__.py b/google/ads/googleads/v23/services/services/customizer_attribute_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/customizer_attribute_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/customizer_attribute_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/customizer_attribute_service/transports/base.py b/google/ads/googleads/v23/services/services/customizer_attribute_service/transports/base.py new file mode 100644 index 000000000..a383272b2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customizer_attribute_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import customizer_attribute_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class CustomizerAttributeServiceTransport(abc.ABC): + """Abstract transport class for CustomizerAttributeService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_customizer_attributes: gapic_v1.method.wrap_method( + self.mutate_customizer_attributes, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_customizer_attributes( + self, + ) -> Callable[ + [customizer_attribute_service.MutateCustomizerAttributesRequest], + Union[ + customizer_attribute_service.MutateCustomizerAttributesResponse, + Awaitable[ + customizer_attribute_service.MutateCustomizerAttributesResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("CustomizerAttributeServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/customizer_attribute_service/transports/grpc.py b/google/ads/googleads/v23/services/services/customizer_attribute_service/transports/grpc.py new file mode 100644 index 000000000..ccb87088a --- /dev/null +++ b/google/ads/googleads/v23/services/services/customizer_attribute_service/transports/grpc.py @@ -0,0 +1,386 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import customizer_attribute_service +from .base import CustomizerAttributeServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.CustomizerAttributeService", + "rpcName": str(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.ads.googleads.v23.services.CustomizerAttributeService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomizerAttributeServiceGrpcTransport( + CustomizerAttributeServiceTransport +): + """gRPC backend transport for CustomizerAttributeService. + + Service to manage customizer attribute + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_customizer_attributes( + self, + ) -> Callable[ + [customizer_attribute_service.MutateCustomizerAttributesRequest], + customizer_attribute_service.MutateCustomizerAttributesResponse, + ]: + r"""Return a callable for the mutate customizer attributes method over gRPC. + + Creates, updates or removes customizer attributes. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomizerAttributesRequest], + ~.MutateCustomizerAttributesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customizer_attributes" not in self._stubs: + self._stubs["mutate_customizer_attributes"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomizerAttributeService/MutateCustomizerAttributes", + request_serializer=customizer_attribute_service.MutateCustomizerAttributesRequest.serialize, + response_deserializer=customizer_attribute_service.MutateCustomizerAttributesResponse.deserialize, + ) + ) + return self._stubs["mutate_customizer_attributes"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("CustomizerAttributeServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/customizer_attribute_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/customizer_attribute_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..9862a3303 --- /dev/null +++ b/google/ads/googleads/v23/services/services/customizer_attribute_service/transports/grpc_asyncio.py @@ -0,0 +1,409 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import customizer_attribute_service +from .base import CustomizerAttributeServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.CustomizerAttributeService", + "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.ads.googleads.v23.services.CustomizerAttributeService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class CustomizerAttributeServiceGrpcAsyncIOTransport( + CustomizerAttributeServiceTransport +): + """gRPC AsyncIO backend transport for CustomizerAttributeService. + + Service to manage customizer attribute + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_customizer_attributes( + self, + ) -> Callable[ + [customizer_attribute_service.MutateCustomizerAttributesRequest], + Awaitable[ + customizer_attribute_service.MutateCustomizerAttributesResponse + ], + ]: + r"""Return a callable for the mutate customizer attributes method over gRPC. + + Creates, updates or removes customizer attributes. + Operation statuses are returned. + + Returns: + Callable[[~.MutateCustomizerAttributesRequest], + Awaitable[~.MutateCustomizerAttributesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_customizer_attributes" not in self._stubs: + self._stubs["mutate_customizer_attributes"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.CustomizerAttributeService/MutateCustomizerAttributes", + request_serializer=customizer_attribute_service.MutateCustomizerAttributesRequest.serialize, + response_deserializer=customizer_attribute_service.MutateCustomizerAttributesResponse.deserialize, + ) + ) + return self._stubs["mutate_customizer_attributes"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_customizer_attributes: self._wrap_method( + self.mutate_customizer_attributes, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("CustomizerAttributeServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/data_link_service/__init__.py b/google/ads/googleads/v23/services/services/data_link_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/data_link_service/__init__.py rename to google/ads/googleads/v23/services/services/data_link_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/data_link_service/async_client.py b/google/ads/googleads/v23/services/services/data_link_service/async_client.py new file mode 100644 index 000000000..489448b06 --- /dev/null +++ b/google/ads/googleads/v23/services/services/data_link_service/async_client.py @@ -0,0 +1,645 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.enums.types import ( + data_link_status as gage_data_link_status, +) +from google.ads.googleads.v23.resources.types import data_link as gagr_data_link +from google.ads.googleads.v23.services.types import data_link_service +from .transports.base import DataLinkServiceTransport, DEFAULT_CLIENT_INFO +from .client import DataLinkServiceClient + +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 DataLinkServiceAsyncClient: + """This service allows management of data links between a + Google Ads customer and another data entity. + """ + + _client: DataLinkServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = DataLinkServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = DataLinkServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + DataLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = DataLinkServiceClient._DEFAULT_UNIVERSE + + data_link_path = staticmethod(DataLinkServiceClient.data_link_path) + parse_data_link_path = staticmethod( + DataLinkServiceClient.parse_data_link_path + ) + common_billing_account_path = staticmethod( + DataLinkServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + DataLinkServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(DataLinkServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + DataLinkServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + DataLinkServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + DataLinkServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + DataLinkServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + DataLinkServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + DataLinkServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + DataLinkServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + DataLinkServiceAsyncClient: The constructed client. + """ + return DataLinkServiceClient.from_service_account_info.__func__(DataLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + DataLinkServiceAsyncClient: The constructed client. + """ + return DataLinkServiceClient.from_service_account_file.__func__(DataLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return DataLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> DataLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + DataLinkServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = DataLinkServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + DataLinkServiceTransport, + Callable[..., DataLinkServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the data link service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,DataLinkServiceTransport,Callable[..., DataLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the DataLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = DataLinkServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.DataLinkServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.DataLinkService", + "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.ads.googleads.v23.services.DataLinkService", + "credentialsType": None, + } + ), + ) + + async def create_data_link( + self, + request: Optional[ + Union[data_link_service.CreateDataLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + data_link: Optional[gagr_data_link.DataLink] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_link_service.CreateDataLinkResponse: + r"""Creates a data link. The requesting Google Ads account name and + account ID will be shared with the third party (such as YouTube + creators for video links) to whom you are creating the link + with. Only customers on the allow-list can create data links. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.CreateDataLinkRequest, dict]]): + The request object. Request message for + [DataLinkService.CreateDataLink][google.ads.googleads.v23.services.DataLinkService.CreateDataLink]. + customer_id (:class:`str`): + Required. The ID of the customer for + which the data link is created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + data_link (:class:`google.ads.googleads.v23.resources.types.DataLink`): + Required. The data link to be + created. + + This corresponds to the ``data_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateDataLinkResponse: + Response message for + [DataLinkService.CreateDataLink][google.ads.googleads.v23.services.DataLinkService.CreateDataLink]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, data_link] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_link_service.CreateDataLinkRequest): + request = data_link_service.CreateDataLinkRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if data_link is not None: + request.data_link = data_link + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_data_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def remove_data_link( + self, + request: Optional[ + Union[data_link_service.RemoveDataLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_link_service.RemoveDataLinkResponse: + r"""Remove a data link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.RemoveDataLinkRequest, dict]]): + The request object. Request message for + [DataLinkService.RemoveDataLink][google.ads.googleads.v23.services.DataLinkService.RemoveDataLink]. + customer_id (:class:`str`): + Required. The ID of the customer for + which the data link is updated. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + resource_name (:class:`str`): + Required. The data link is expected + to have a valid resource name. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.RemoveDataLinkResponse: + Response message for + [DataLinkService.RemoveDataLink][google.ads.googleads.v23.services.DataLinkService.RemoveDataLink]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_link_service.RemoveDataLinkRequest): + request = data_link_service.RemoveDataLinkRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.remove_data_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_data_link( + self, + request: Optional[ + Union[data_link_service.UpdateDataLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + data_link_status: Optional[ + gage_data_link_status.DataLinkStatusEnum.DataLinkStatus + ] = None, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_link_service.UpdateDataLinkResponse: + r"""Update a data link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.UpdateDataLinkRequest, dict]]): + The request object. Request message for + [DataLinkService.UpdateDataLink][google.ads.googleads.v23.services.DataLinkService.UpdateDataLink]. + customer_id (:class:`str`): + Required. The ID of the customer for + which the data link is created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + data_link_status (:class:`google.ads.googleads.v23.enums.types.DataLinkStatusEnum.DataLinkStatus`): + Required. The data link status to be + updated to. + + This corresponds to the ``data_link_status`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + resource_name (:class:`str`): + Required. The data link is expected + to have a valid resource name. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UpdateDataLinkResponse: + Response message for + [DataLinkService.UpdateDataLink][google.ads.googleads.v23.services.DataLinkService.UpdateDataLink]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, data_link_status, resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_link_service.UpdateDataLinkRequest): + request = data_link_service.UpdateDataLinkRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if data_link_status is not None: + request.data_link_status = data_link_status + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.update_data_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "DataLinkServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("DataLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/data_link_service/client.py b/google/ads/googleads/v23/services/services/data_link_service/client.py new file mode 100644 index 000000000..267a8a3d4 --- /dev/null +++ b/google/ads/googleads/v23/services/services/data_link_service/client.py @@ -0,0 +1,1097 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.enums.types import ( + data_link_status as gage_data_link_status, +) +from google.ads.googleads.v23.resources.types import data_link as gagr_data_link +from google.ads.googleads.v23.services.types import data_link_service +from .transports.base import DataLinkServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import DataLinkServiceGrpcTransport +from .transports.grpc_asyncio import DataLinkServiceGrpcAsyncIOTransport + + +class DataLinkServiceClientMeta(type): + """Metaclass for the DataLinkService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[DataLinkServiceTransport]] + _transport_registry["grpc"] = DataLinkServiceGrpcTransport + _transport_registry["grpc_asyncio"] = DataLinkServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[DataLinkServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class DataLinkServiceClient(metaclass=DataLinkServiceClientMeta): + """This service allows management of data links between a + Google Ads customer and another data entity. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + DataLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + DataLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> DataLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + DataLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def data_link_path( + customer_id: str, + product_link_id: str, + data_link_id: str, + ) -> str: + """Returns a fully-qualified data_link string.""" + return "customers/{customer_id}/dataLinks/{product_link_id}~{data_link_id}".format( + customer_id=customer_id, + product_link_id=product_link_id, + data_link_id=data_link_id, + ) + + @staticmethod + def parse_data_link_path(path: str) -> Dict[str, str]: + """Parses a data_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/dataLinks/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = DataLinkServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = DataLinkServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = DataLinkServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = DataLinkServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + DataLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = DataLinkServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + DataLinkServiceTransport, + Callable[..., DataLinkServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the data link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,DataLinkServiceTransport,Callable[..., DataLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the DataLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = DataLinkServiceClient._read_environment_variables() + self._client_cert_source = ( + DataLinkServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = DataLinkServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, DataLinkServiceTransport) + if transport_provided: + # transport is a DataLinkServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(DataLinkServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or DataLinkServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[DataLinkServiceTransport], + Callable[..., DataLinkServiceTransport], + ] = ( + DataLinkServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., DataLinkServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.DataLinkServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.DataLinkService", + "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.ads.googleads.v23.services.DataLinkService", + "credentialsType": None, + } + ), + ) + + def create_data_link( + self, + request: Optional[ + Union[data_link_service.CreateDataLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + data_link: Optional[gagr_data_link.DataLink] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_link_service.CreateDataLinkResponse: + r"""Creates a data link. The requesting Google Ads account name and + account ID will be shared with the third party (such as YouTube + creators for video links) to whom you are creating the link + with. Only customers on the allow-list can create data links. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.CreateDataLinkRequest, dict]): + The request object. Request message for + [DataLinkService.CreateDataLink][google.ads.googleads.v23.services.DataLinkService.CreateDataLink]. + customer_id (str): + Required. The ID of the customer for + which the data link is created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + data_link (google.ads.googleads.v23.resources.types.DataLink): + Required. The data link to be + created. + + This corresponds to the ``data_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateDataLinkResponse: + Response message for + [DataLinkService.CreateDataLink][google.ads.googleads.v23.services.DataLinkService.CreateDataLink]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, data_link] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_link_service.CreateDataLinkRequest): + request = data_link_service.CreateDataLinkRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if data_link is not None: + request.data_link = data_link + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_data_link] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def remove_data_link( + self, + request: Optional[ + Union[data_link_service.RemoveDataLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_link_service.RemoveDataLinkResponse: + r"""Remove a data link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.RemoveDataLinkRequest, dict]): + The request object. Request message for + [DataLinkService.RemoveDataLink][google.ads.googleads.v23.services.DataLinkService.RemoveDataLink]. + customer_id (str): + Required. The ID of the customer for + which the data link is updated. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + resource_name (str): + Required. The data link is expected + to have a valid resource name. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.RemoveDataLinkResponse: + Response message for + [DataLinkService.RemoveDataLink][google.ads.googleads.v23.services.DataLinkService.RemoveDataLink]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_link_service.RemoveDataLinkRequest): + request = data_link_service.RemoveDataLinkRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.remove_data_link] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_data_link( + self, + request: Optional[ + Union[data_link_service.UpdateDataLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + data_link_status: Optional[ + gage_data_link_status.DataLinkStatusEnum.DataLinkStatus + ] = None, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> data_link_service.UpdateDataLinkResponse: + r"""Update a data link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.UpdateDataLinkRequest, dict]): + The request object. Request message for + [DataLinkService.UpdateDataLink][google.ads.googleads.v23.services.DataLinkService.UpdateDataLink]. + customer_id (str): + Required. The ID of the customer for + which the data link is created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + data_link_status (google.ads.googleads.v23.enums.types.DataLinkStatusEnum.DataLinkStatus): + Required. The data link status to be + updated to. + + This corresponds to the ``data_link_status`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + resource_name (str): + Required. The data link is expected + to have a valid resource name. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UpdateDataLinkResponse: + Response message for + [DataLinkService.UpdateDataLink][google.ads.googleads.v23.services.DataLinkService.UpdateDataLink]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, data_link_status, resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, data_link_service.UpdateDataLinkRequest): + request = data_link_service.UpdateDataLinkRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if data_link_status is not None: + request.data_link_status = data_link_status + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_data_link] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "DataLinkServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("DataLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/data_link_service/transports/README.rst b/google/ads/googleads/v23/services/services/data_link_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/data_link_service/transports/README.rst rename to google/ads/googleads/v23/services/services/data_link_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/data_link_service/transports/__init__.py b/google/ads/googleads/v23/services/services/data_link_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/data_link_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/data_link_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/data_link_service/transports/base.py b/google/ads/googleads/v23/services/services/data_link_service/transports/base.py new file mode 100644 index 000000000..58fb6626e --- /dev/null +++ b/google/ads/googleads/v23/services/services/data_link_service/transports/base.py @@ -0,0 +1,207 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import data_link_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class DataLinkServiceTransport(abc.ABC): + """Abstract transport class for DataLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_data_link: gapic_v1.method.wrap_method( + self.create_data_link, + default_timeout=None, + client_info=client_info, + ), + self.remove_data_link: gapic_v1.method.wrap_method( + self.remove_data_link, + default_timeout=None, + client_info=client_info, + ), + self.update_data_link: gapic_v1.method.wrap_method( + self.update_data_link, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def create_data_link( + self, + ) -> Callable[ + [data_link_service.CreateDataLinkRequest], + Union[ + data_link_service.CreateDataLinkResponse, + Awaitable[data_link_service.CreateDataLinkResponse], + ], + ]: + raise NotImplementedError() + + @property + def remove_data_link( + self, + ) -> Callable[ + [data_link_service.RemoveDataLinkRequest], + Union[ + data_link_service.RemoveDataLinkResponse, + Awaitable[data_link_service.RemoveDataLinkResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_data_link( + self, + ) -> Callable[ + [data_link_service.UpdateDataLinkRequest], + Union[ + data_link_service.UpdateDataLinkResponse, + Awaitable[data_link_service.UpdateDataLinkResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("DataLinkServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/data_link_service/transports/grpc.py b/google/ads/googleads/v23/services/services/data_link_service/transports/grpc.py new file mode 100644 index 000000000..98fa6776d --- /dev/null +++ b/google/ads/googleads/v23/services/services/data_link_service/transports/grpc.py @@ -0,0 +1,461 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import data_link_service +from .base import DataLinkServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.DataLinkService", + "rpcName": str(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.ads.googleads.v23.services.DataLinkService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class DataLinkServiceGrpcTransport(DataLinkServiceTransport): + """gRPC backend transport for DataLinkService. + + This service allows management of data links between a + Google Ads customer and another data entity. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def create_data_link( + self, + ) -> Callable[ + [data_link_service.CreateDataLinkRequest], + data_link_service.CreateDataLinkResponse, + ]: + r"""Return a callable for the create data link method over gRPC. + + Creates a data link. The requesting Google Ads account name and + account ID will be shared with the third party (such as YouTube + creators for video links) to whom you are creating the link + with. Only customers on the allow-list can create data links. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.CreateDataLinkRequest], + ~.CreateDataLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_data_link" not in self._stubs: + self._stubs["create_data_link"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.DataLinkService/CreateDataLink", + request_serializer=data_link_service.CreateDataLinkRequest.serialize, + response_deserializer=data_link_service.CreateDataLinkResponse.deserialize, + ) + return self._stubs["create_data_link"] + + @property + def remove_data_link( + self, + ) -> Callable[ + [data_link_service.RemoveDataLinkRequest], + data_link_service.RemoveDataLinkResponse, + ]: + r"""Return a callable for the remove data link method over gRPC. + + Remove a data link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.RemoveDataLinkRequest], + ~.RemoveDataLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "remove_data_link" not in self._stubs: + self._stubs["remove_data_link"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.DataLinkService/RemoveDataLink", + request_serializer=data_link_service.RemoveDataLinkRequest.serialize, + response_deserializer=data_link_service.RemoveDataLinkResponse.deserialize, + ) + return self._stubs["remove_data_link"] + + @property + def update_data_link( + self, + ) -> Callable[ + [data_link_service.UpdateDataLinkRequest], + data_link_service.UpdateDataLinkResponse, + ]: + r"""Return a callable for the update data link method over gRPC. + + Update a data link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.UpdateDataLinkRequest], + ~.UpdateDataLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_data_link" not in self._stubs: + self._stubs["update_data_link"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.DataLinkService/UpdateDataLink", + request_serializer=data_link_service.UpdateDataLinkRequest.serialize, + response_deserializer=data_link_service.UpdateDataLinkResponse.deserialize, + ) + return self._stubs["update_data_link"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("DataLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/data_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/data_link_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..bc73831ce --- /dev/null +++ b/google/ads/googleads/v23/services/services/data_link_service/transports/grpc_asyncio.py @@ -0,0 +1,492 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import data_link_service +from .base import DataLinkServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.DataLinkService", + "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.ads.googleads.v23.services.DataLinkService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class DataLinkServiceGrpcAsyncIOTransport(DataLinkServiceTransport): + """gRPC AsyncIO backend transport for DataLinkService. + + This service allows management of data links between a + Google Ads customer and another data entity. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def create_data_link( + self, + ) -> Callable[ + [data_link_service.CreateDataLinkRequest], + Awaitable[data_link_service.CreateDataLinkResponse], + ]: + r"""Return a callable for the create data link method over gRPC. + + Creates a data link. The requesting Google Ads account name and + account ID will be shared with the third party (such as YouTube + creators for video links) to whom you are creating the link + with. Only customers on the allow-list can create data links. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.CreateDataLinkRequest], + Awaitable[~.CreateDataLinkResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_data_link" not in self._stubs: + self._stubs["create_data_link"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.DataLinkService/CreateDataLink", + request_serializer=data_link_service.CreateDataLinkRequest.serialize, + response_deserializer=data_link_service.CreateDataLinkResponse.deserialize, + ) + return self._stubs["create_data_link"] + + @property + def remove_data_link( + self, + ) -> Callable[ + [data_link_service.RemoveDataLinkRequest], + Awaitable[data_link_service.RemoveDataLinkResponse], + ]: + r"""Return a callable for the remove data link method over gRPC. + + Remove a data link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.RemoveDataLinkRequest], + Awaitable[~.RemoveDataLinkResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "remove_data_link" not in self._stubs: + self._stubs["remove_data_link"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.DataLinkService/RemoveDataLink", + request_serializer=data_link_service.RemoveDataLinkRequest.serialize, + response_deserializer=data_link_service.RemoveDataLinkResponse.deserialize, + ) + return self._stubs["remove_data_link"] + + @property + def update_data_link( + self, + ) -> Callable[ + [data_link_service.UpdateDataLinkRequest], + Awaitable[data_link_service.UpdateDataLinkResponse], + ]: + r"""Return a callable for the update data link method over gRPC. + + Update a data link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `DataLinkError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.UpdateDataLinkRequest], + Awaitable[~.UpdateDataLinkResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_data_link" not in self._stubs: + self._stubs["update_data_link"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.DataLinkService/UpdateDataLink", + request_serializer=data_link_service.UpdateDataLinkRequest.serialize, + response_deserializer=data_link_service.UpdateDataLinkResponse.deserialize, + ) + return self._stubs["update_data_link"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.create_data_link: self._wrap_method( + self.create_data_link, + default_timeout=None, + client_info=client_info, + ), + self.remove_data_link: self._wrap_method( + self.remove_data_link, + default_timeout=None, + client_info=client_info, + ), + self.update_data_link: self._wrap_method( + self.update_data_link, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("DataLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/experiment_arm_service/__init__.py b/google/ads/googleads/v23/services/services/experiment_arm_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/experiment_arm_service/__init__.py rename to google/ads/googleads/v23/services/services/experiment_arm_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/experiment_arm_service/async_client.py b/google/ads/googleads/v23/services/services/experiment_arm_service/async_client.py new file mode 100644 index 000000000..95dd095d5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/experiment_arm_service/async_client.py @@ -0,0 +1,433 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import experiment_arm_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ExperimentArmServiceTransport, DEFAULT_CLIENT_INFO +from .client import ExperimentArmServiceClient + +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 ExperimentArmServiceAsyncClient: + """Service to manage experiment arms.""" + + _client: ExperimentArmServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ExperimentArmServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ExperimentArmServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + ExperimentArmServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ExperimentArmServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod(ExperimentArmServiceClient.campaign_path) + parse_campaign_path = staticmethod( + ExperimentArmServiceClient.parse_campaign_path + ) + experiment_path = staticmethod(ExperimentArmServiceClient.experiment_path) + parse_experiment_path = staticmethod( + ExperimentArmServiceClient.parse_experiment_path + ) + experiment_arm_path = staticmethod( + ExperimentArmServiceClient.experiment_arm_path + ) + parse_experiment_arm_path = staticmethod( + ExperimentArmServiceClient.parse_experiment_arm_path + ) + common_billing_account_path = staticmethod( + ExperimentArmServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ExperimentArmServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ExperimentArmServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ExperimentArmServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ExperimentArmServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ExperimentArmServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ExperimentArmServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ExperimentArmServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ExperimentArmServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ExperimentArmServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentArmServiceAsyncClient: The constructed client. + """ + return ExperimentArmServiceClient.from_service_account_info.__func__(ExperimentArmServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentArmServiceAsyncClient: The constructed client. + """ + return ExperimentArmServiceClient.from_service_account_file.__func__(ExperimentArmServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ExperimentArmServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ExperimentArmServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ExperimentArmServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ExperimentArmServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ExperimentArmServiceTransport, + Callable[..., ExperimentArmServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the experiment arm service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ExperimentArmServiceTransport,Callable[..., ExperimentArmServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ExperimentArmServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ExperimentArmServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ExperimentArmServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ExperimentArmService", + "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.ads.googleads.v23.services.ExperimentArmService", + "credentialsType": None, + } + ), + ) + + async def mutate_experiment_arms( + self, + request: Optional[ + Union[experiment_arm_service.MutateExperimentArmsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[experiment_arm_service.ExperimentArmOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> experiment_arm_service.MutateExperimentArmsResponse: + r"""Creates, updates, or removes experiment arms. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentArmError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateExperimentArmsRequest, dict]]): + The request object. Request message for + [ExperimentArmService.MutateExperimentArms][google.ads.googleads.v23.services.ExperimentArmService.MutateExperimentArms]. + customer_id (:class:`str`): + Required. The ID of the customer + whose experiments are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.ExperimentArmOperation]`): + Required. The list of operations to + perform on individual experiment arm. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateExperimentArmsResponse: + Response message for experiment arm + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, experiment_arm_service.MutateExperimentArmsRequest + ): + request = experiment_arm_service.MutateExperimentArmsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_experiment_arms + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ExperimentArmServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ExperimentArmServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/experiment_arm_service/client.py b/google/ads/googleads/v23/services/services/experiment_arm_service/client.py new file mode 100644 index 000000000..0780dc92c --- /dev/null +++ b/google/ads/googleads/v23/services/services/experiment_arm_service/client.py @@ -0,0 +1,941 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import experiment_arm_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ExperimentArmServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ExperimentArmServiceGrpcTransport +from .transports.grpc_asyncio import ExperimentArmServiceGrpcAsyncIOTransport + + +class ExperimentArmServiceClientMeta(type): + """Metaclass for the ExperimentArmService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ExperimentArmServiceTransport]] + _transport_registry["grpc"] = ExperimentArmServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + ExperimentArmServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ExperimentArmServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ExperimentArmServiceClient(metaclass=ExperimentArmServiceClientMeta): + """Service to manage experiment arms.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentArmServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentArmServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ExperimentArmServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ExperimentArmServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_path( + customer_id: str, + trial_id: str, + ) -> str: + """Returns a fully-qualified experiment string.""" + return "customers/{customer_id}/experiments/{trial_id}".format( + customer_id=customer_id, + trial_id=trial_id, + ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str, str]: + """Parses a experiment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_arm_path( + customer_id: str, + trial_id: str, + trial_arm_id: str, + ) -> str: + """Returns a fully-qualified experiment_arm string.""" + return "customers/{customer_id}/experimentArms/{trial_id}~{trial_arm_id}".format( + customer_id=customer_id, + trial_id=trial_id, + trial_arm_id=trial_arm_id, + ) + + @staticmethod + def parse_experiment_arm_path(path: str) -> Dict[str, str]: + """Parses a experiment_arm path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experimentArms/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ExperimentArmServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ExperimentArmServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ExperimentArmServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ExperimentArmServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + ExperimentArmServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ExperimentArmServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ExperimentArmServiceTransport, + Callable[..., ExperimentArmServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the experiment arm service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ExperimentArmServiceTransport,Callable[..., ExperimentArmServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ExperimentArmServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ExperimentArmServiceClient._read_environment_variables() + self._client_cert_source = ( + ExperimentArmServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ExperimentArmServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ExperimentArmServiceTransport + ) + if transport_provided: + # transport is a ExperimentArmServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(ExperimentArmServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ExperimentArmServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ExperimentArmServiceTransport], + Callable[..., ExperimentArmServiceTransport], + ] = ( + ExperimentArmServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ExperimentArmServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ExperimentArmServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ExperimentArmService", + "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.ads.googleads.v23.services.ExperimentArmService", + "credentialsType": None, + } + ), + ) + + def mutate_experiment_arms( + self, + request: Optional[ + Union[experiment_arm_service.MutateExperimentArmsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[experiment_arm_service.ExperimentArmOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> experiment_arm_service.MutateExperimentArmsResponse: + r"""Creates, updates, or removes experiment arms. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentArmError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateExperimentArmsRequest, dict]): + The request object. Request message for + [ExperimentArmService.MutateExperimentArms][google.ads.googleads.v23.services.ExperimentArmService.MutateExperimentArms]. + customer_id (str): + Required. The ID of the customer + whose experiments are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.ExperimentArmOperation]): + Required. The list of operations to + perform on individual experiment arm. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateExperimentArmsResponse: + Response message for experiment arm + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, experiment_arm_service.MutateExperimentArmsRequest + ): + request = experiment_arm_service.MutateExperimentArmsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_experiment_arms + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ExperimentArmServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ExperimentArmServiceClient",) diff --git a/google/ads/googleads/v19/services/services/experiment_arm_service/transports/README.rst b/google/ads/googleads/v23/services/services/experiment_arm_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/experiment_arm_service/transports/README.rst rename to google/ads/googleads/v23/services/services/experiment_arm_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/experiment_arm_service/transports/__init__.py b/google/ads/googleads/v23/services/services/experiment_arm_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/experiment_arm_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/experiment_arm_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/experiment_arm_service/transports/base.py b/google/ads/googleads/v23/services/services/experiment_arm_service/transports/base.py new file mode 100644 index 000000000..a00057b52 --- /dev/null +++ b/google/ads/googleads/v23/services/services/experiment_arm_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import experiment_arm_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ExperimentArmServiceTransport(abc.ABC): + """Abstract transport class for ExperimentArmService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_experiment_arms: gapic_v1.method.wrap_method( + self.mutate_experiment_arms, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_experiment_arms( + self, + ) -> Callable[ + [experiment_arm_service.MutateExperimentArmsRequest], + Union[ + experiment_arm_service.MutateExperimentArmsResponse, + Awaitable[experiment_arm_service.MutateExperimentArmsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ExperimentArmServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/experiment_arm_service/transports/grpc.py b/google/ads/googleads/v23/services/services/experiment_arm_service/transports/grpc.py new file mode 100644 index 000000000..f62614026 --- /dev/null +++ b/google/ads/googleads/v23/services/services/experiment_arm_service/transports/grpc.py @@ -0,0 +1,389 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import experiment_arm_service +from .base import ExperimentArmServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ExperimentArmService", + "rpcName": str(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.ads.googleads.v23.services.ExperimentArmService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ExperimentArmServiceGrpcTransport(ExperimentArmServiceTransport): + """gRPC backend transport for ExperimentArmService. + + Service to manage experiment arms. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_experiment_arms( + self, + ) -> Callable[ + [experiment_arm_service.MutateExperimentArmsRequest], + experiment_arm_service.MutateExperimentArmsResponse, + ]: + r"""Return a callable for the mutate experiment arms method over gRPC. + + Creates, updates, or removes experiment arms. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentArmError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateExperimentArmsRequest], + ~.MutateExperimentArmsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_experiment_arms" not in self._stubs: + self._stubs["mutate_experiment_arms"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentArmService/MutateExperimentArms", + request_serializer=experiment_arm_service.MutateExperimentArmsRequest.serialize, + response_deserializer=experiment_arm_service.MutateExperimentArmsResponse.deserialize, + ) + ) + return self._stubs["mutate_experiment_arms"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ExperimentArmServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/experiment_arm_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/experiment_arm_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..5f1a54886 --- /dev/null +++ b/google/ads/googleads/v23/services/services/experiment_arm_service/transports/grpc_asyncio.py @@ -0,0 +1,410 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import experiment_arm_service +from .base import ExperimentArmServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ExperimentArmService", + "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.ads.googleads.v23.services.ExperimentArmService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ExperimentArmServiceGrpcAsyncIOTransport(ExperimentArmServiceTransport): + """gRPC AsyncIO backend transport for ExperimentArmService. + + Service to manage experiment arms. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_experiment_arms( + self, + ) -> Callable[ + [experiment_arm_service.MutateExperimentArmsRequest], + Awaitable[experiment_arm_service.MutateExperimentArmsResponse], + ]: + r"""Return a callable for the mutate experiment arms method over gRPC. + + Creates, updates, or removes experiment arms. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentArmError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateExperimentArmsRequest], + Awaitable[~.MutateExperimentArmsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_experiment_arms" not in self._stubs: + self._stubs["mutate_experiment_arms"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentArmService/MutateExperimentArms", + request_serializer=experiment_arm_service.MutateExperimentArmsRequest.serialize, + response_deserializer=experiment_arm_service.MutateExperimentArmsResponse.deserialize, + ) + ) + return self._stubs["mutate_experiment_arms"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_experiment_arms: self._wrap_method( + self.mutate_experiment_arms, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ExperimentArmServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/experiment_service/__init__.py b/google/ads/googleads/v23/services/services/experiment_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/experiment_service/__init__.py rename to google/ads/googleads/v23/services/services/experiment_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/experiment_service/async_client.py b/google/ads/googleads/v23/services/services/experiment_service/async_client.py new file mode 100644 index 000000000..7005aad83 --- /dev/null +++ b/google/ads/googleads/v23/services/services/experiment_service/async_client.py @@ -0,0 +1,977 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.services.experiment_service import pagers +from google.ads.googleads.v23.services.types import experiment_service +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ExperimentServiceTransport, DEFAULT_CLIENT_INFO +from .client import ExperimentServiceClient + +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 ExperimentServiceAsyncClient: + """Service to manage experiments.""" + + _client: ExperimentServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ExperimentServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ExperimentServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + ExperimentServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ExperimentServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod(ExperimentServiceClient.campaign_path) + parse_campaign_path = staticmethod( + ExperimentServiceClient.parse_campaign_path + ) + campaign_budget_path = staticmethod( + ExperimentServiceClient.campaign_budget_path + ) + parse_campaign_budget_path = staticmethod( + ExperimentServiceClient.parse_campaign_budget_path + ) + experiment_path = staticmethod(ExperimentServiceClient.experiment_path) + parse_experiment_path = staticmethod( + ExperimentServiceClient.parse_experiment_path + ) + common_billing_account_path = staticmethod( + ExperimentServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ExperimentServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ExperimentServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ExperimentServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ExperimentServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ExperimentServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ExperimentServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ExperimentServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ExperimentServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ExperimentServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentServiceAsyncClient: The constructed client. + """ + return ExperimentServiceClient.from_service_account_info.__func__(ExperimentServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentServiceAsyncClient: The constructed client. + """ + return ExperimentServiceClient.from_service_account_file.__func__(ExperimentServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ExperimentServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ExperimentServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ExperimentServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ExperimentServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ExperimentServiceTransport, + Callable[..., ExperimentServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the experiment service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ExperimentServiceTransport,Callable[..., ExperimentServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ExperimentServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ExperimentServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ExperimentServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ExperimentService", + "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.ads.googleads.v23.services.ExperimentService", + "credentialsType": None, + } + ), + ) + + async def mutate_experiments( + self, + request: Optional[ + Union[experiment_service.MutateExperimentsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[experiment_service.ExperimentOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> experiment_service.MutateExperimentsResponse: + r"""Creates, updates, or removes experiments. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateExperimentsRequest, dict]]): + The request object. Request message for + [ExperimentService.MutateExperiments][google.ads.googleads.v23.services.ExperimentService.MutateExperiments]. + customer_id (:class:`str`): + Required. The ID of the customer + whose experiments are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.ExperimentOperation]`): + Required. The list of operations to + perform on individual experiments. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateExperimentsResponse: + Response message for experiment + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, experiment_service.MutateExperimentsRequest): + request = experiment_service.MutateExperimentsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_experiments + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def end_experiment( + self, + request: Optional[ + Union[experiment_service.EndExperimentRequest, dict] + ] = None, + *, + experiment: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Immediately ends an experiment, changing the experiment's + scheduled end date and without waiting for end of day. End date + is updated to be the time of the request. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.EndExperimentRequest, dict]]): + The request object. Request message for + [ExperimentService.EndExperiment][google.ads.googleads.v23.services.ExperimentService.EndExperiment]. + experiment (:class:`str`): + Required. The resource name of the + campaign experiment to end. + + This corresponds to the ``experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 + # gotten any keyword arguments that map to the request. + flattened_params = [experiment] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, experiment_service.EndExperimentRequest): + request = experiment_service.EndExperimentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if experiment is not None: + request.experiment = experiment + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.end_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("experiment", request.experiment),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_experiment_async_errors( + self, + request: Optional[ + Union[experiment_service.ListExperimentAsyncErrorsRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListExperimentAsyncErrorsAsyncPager: + r"""Returns all errors that occurred during the last Experiment + update (either scheduling or promotion). Supports standard list + paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListExperimentAsyncErrorsRequest, dict]]): + The request object. Request message for + [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v23.services.ExperimentService.ListExperimentAsyncErrors]. + resource_name (:class:`str`): + Required. The name of the experiment + from which to retrieve the async errors. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.experiment_service.pagers.ListExperimentAsyncErrorsAsyncPager: + Response message for + [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v23.services.ExperimentService.ListExperimentAsyncErrors]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, experiment_service.ListExperimentAsyncErrorsRequest + ): + request = experiment_service.ListExperimentAsyncErrorsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_experiment_async_errors + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListExperimentAsyncErrorsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def graduate_experiment( + self, + request: Optional[ + Union[experiment_service.GraduateExperimentRequest, dict] + ] = None, + *, + experiment: Optional[str] = None, + campaign_budget_mappings: Optional[ + MutableSequence[experiment_service.CampaignBudgetMapping] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Graduates an experiment to a full campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GraduateExperimentRequest, dict]]): + The request object. Request message for + [ExperimentService.GraduateExperiment][google.ads.googleads.v23.services.ExperimentService.GraduateExperiment]. + experiment (:class:`str`): + Required. The experiment to be + graduated. + + This corresponds to the ``experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + campaign_budget_mappings (:class:`MutableSequence[google.ads.googleads.v23.services.types.CampaignBudgetMapping]`): + Required. List of campaign budget + mappings for graduation. Each campaign + that appears here will graduate, and + will be assigned a new budget that is + paired with it in the mapping. The + maximum size is one. + + This corresponds to the ``campaign_budget_mappings`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 + # gotten any keyword arguments that map to the request. + flattened_params = [experiment, campaign_budget_mappings] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, experiment_service.GraduateExperimentRequest + ): + request = experiment_service.GraduateExperimentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if experiment is not None: + request.experiment = experiment + if campaign_budget_mappings: + request.campaign_budget_mappings.extend(campaign_budget_mappings) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.graduate_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("experiment", request.experiment),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def schedule_experiment( + self, + request: Optional[ + Union[experiment_service.ScheduleExperimentRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Schedule an experiment. The in design campaign will be converted + into a real campaign (called the experiment campaign) that will + begin serving ads if successfully created. + + The experiment is scheduled immediately with status + INITIALIZING. This method returns a long running operation that + tracks the forking of the in design campaign. If the forking + fails, a list of errors can be retrieved using the + ListExperimentAsyncErrors method. The operation's metadata will + be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ScheduleExperimentRequest, dict]]): + The request object. Request message for + [ExperimentService.ScheduleExperiment][google.ads.googleads.v23.services.ExperimentService.ScheduleExperiment]. + resource_name (:class:`str`): + Required. The scheduled experiment. + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, experiment_service.ScheduleExperimentRequest + ): + request = experiment_service.ScheduleExperimentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.schedule_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=experiment_service.ScheduleExperimentMetadata, + ) + + # Done; return the response. + return response + + async def promote_experiment( + self, + request: Optional[ + Union[experiment_service.PromoteExperimentRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Promotes the trial campaign thus applying changes in the trial + campaign to the base campaign. This method returns a long + running operation that tracks the promotion of the experiment + campaign. If it fails, a list of errors can be retrieved using + the ListExperimentAsyncErrors method. The operation's metadata + will be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.PromoteExperimentRequest, dict]]): + The request object. Request message for + [ExperimentService.PromoteExperiment][google.ads.googleads.v23.services.ExperimentService.PromoteExperiment]. + resource_name (:class:`str`): + Required. The resource name of the + experiment to promote. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, experiment_service.PromoteExperimentRequest): + request = experiment_service.PromoteExperimentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.promote_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=experiment_service.PromoteExperimentMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ExperimentServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ExperimentServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/experiment_service/client.py b/google/ads/googleads/v23/services/services/experiment_service/client.py new file mode 100644 index 000000000..31e826854 --- /dev/null +++ b/google/ads/googleads/v23/services/services/experiment_service/client.py @@ -0,0 +1,1466 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.services.experiment_service import pagers +from google.ads.googleads.v23.services.types import experiment_service +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ExperimentServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ExperimentServiceGrpcTransport +from .transports.grpc_asyncio import ExperimentServiceGrpcAsyncIOTransport + + +class ExperimentServiceClientMeta(type): + """Metaclass for the ExperimentService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ExperimentServiceTransport]] + _transport_registry["grpc"] = ExperimentServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ExperimentServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ExperimentServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ExperimentServiceClient(metaclass=ExperimentServiceClientMeta): + """Service to manage experiments.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ExperimentServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ExperimentServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ExperimentServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_budget_path( + customer_id: str, + campaign_budget_id: str, + ) -> str: + """Returns a fully-qualified campaign_budget string.""" + return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( + customer_id=customer_id, + campaign_budget_id=campaign_budget_id, + ) + + @staticmethod + def parse_campaign_budget_path(path: str) -> Dict[str, str]: + """Parses a campaign_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_path( + customer_id: str, + trial_id: str, + ) -> str: + """Returns a fully-qualified experiment string.""" + return "customers/{customer_id}/experiments/{trial_id}".format( + customer_id=customer_id, + trial_id=trial_id, + ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str, str]: + """Parses a experiment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ExperimentServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ExperimentServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ExperimentServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ExperimentServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + ExperimentServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ExperimentServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ExperimentServiceTransport, + Callable[..., ExperimentServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the experiment service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ExperimentServiceTransport,Callable[..., ExperimentServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ExperimentServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ExperimentServiceClient._read_environment_variables() + self._client_cert_source = ( + ExperimentServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ExperimentServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, ExperimentServiceTransport) + if transport_provided: + # transport is a ExperimentServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(ExperimentServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ExperimentServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ExperimentServiceTransport], + Callable[..., ExperimentServiceTransport], + ] = ( + ExperimentServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., ExperimentServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ExperimentServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ExperimentService", + "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.ads.googleads.v23.services.ExperimentService", + "credentialsType": None, + } + ), + ) + + def mutate_experiments( + self, + request: Optional[ + Union[experiment_service.MutateExperimentsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[experiment_service.ExperimentOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> experiment_service.MutateExperimentsResponse: + r"""Creates, updates, or removes experiments. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateExperimentsRequest, dict]): + The request object. Request message for + [ExperimentService.MutateExperiments][google.ads.googleads.v23.services.ExperimentService.MutateExperiments]. + customer_id (str): + Required. The ID of the customer + whose experiments are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.ExperimentOperation]): + Required. The list of operations to + perform on individual experiments. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateExperimentsResponse: + Response message for experiment + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, experiment_service.MutateExperimentsRequest): + request = experiment_service.MutateExperimentsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_experiments + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def end_experiment( + self, + request: Optional[ + Union[experiment_service.EndExperimentRequest, dict] + ] = None, + *, + experiment: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Immediately ends an experiment, changing the experiment's + scheduled end date and without waiting for end of day. End date + is updated to be the time of the request. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.EndExperimentRequest, dict]): + The request object. Request message for + [ExperimentService.EndExperiment][google.ads.googleads.v23.services.ExperimentService.EndExperiment]. + experiment (str): + Required. The resource name of the + campaign experiment to end. + + This corresponds to the ``experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 + # gotten any keyword arguments that map to the request. + flattened_params = [experiment] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, experiment_service.EndExperimentRequest): + request = experiment_service.EndExperimentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if experiment is not None: + request.experiment = experiment + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.end_experiment] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("experiment", request.experiment),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def list_experiment_async_errors( + self, + request: Optional[ + Union[experiment_service.ListExperimentAsyncErrorsRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.ListExperimentAsyncErrorsPager: + r"""Returns all errors that occurred during the last Experiment + update (either scheduling or promotion). Supports standard list + paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListExperimentAsyncErrorsRequest, dict]): + The request object. Request message for + [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v23.services.ExperimentService.ListExperimentAsyncErrors]. + resource_name (str): + Required. The name of the experiment + from which to retrieve the async errors. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.experiment_service.pagers.ListExperimentAsyncErrorsPager: + Response message for + [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v23.services.ExperimentService.ListExperimentAsyncErrors]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, experiment_service.ListExperimentAsyncErrorsRequest + ): + request = experiment_service.ListExperimentAsyncErrorsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_experiment_async_errors + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.ListExperimentAsyncErrorsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def graduate_experiment( + self, + request: Optional[ + Union[experiment_service.GraduateExperimentRequest, dict] + ] = None, + *, + experiment: Optional[str] = None, + campaign_budget_mappings: Optional[ + MutableSequence[experiment_service.CampaignBudgetMapping] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Graduates an experiment to a full campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GraduateExperimentRequest, dict]): + The request object. Request message for + [ExperimentService.GraduateExperiment][google.ads.googleads.v23.services.ExperimentService.GraduateExperiment]. + experiment (str): + Required. The experiment to be + graduated. + + This corresponds to the ``experiment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + campaign_budget_mappings (MutableSequence[google.ads.googleads.v23.services.types.CampaignBudgetMapping]): + Required. List of campaign budget + mappings for graduation. Each campaign + that appears here will graduate, and + will be assigned a new budget that is + paired with it in the mapping. The + maximum size is one. + + This corresponds to the ``campaign_budget_mappings`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 + # gotten any keyword arguments that map to the request. + flattened_params = [experiment, campaign_budget_mappings] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, experiment_service.GraduateExperimentRequest + ): + request = experiment_service.GraduateExperimentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if experiment is not None: + request.experiment = experiment + if campaign_budget_mappings is not None: + request.campaign_budget_mappings = campaign_budget_mappings + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.graduate_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("experiment", request.experiment),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def schedule_experiment( + self, + request: Optional[ + Union[experiment_service.ScheduleExperimentRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Schedule an experiment. The in design campaign will be converted + into a real campaign (called the experiment campaign) that will + begin serving ads if successfully created. + + The experiment is scheduled immediately with status + INITIALIZING. This method returns a long running operation that + tracks the forking of the in design campaign. If the forking + fails, a list of errors can be retrieved using the + ListExperimentAsyncErrors method. The operation's metadata will + be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ScheduleExperimentRequest, dict]): + The request object. Request message for + [ExperimentService.ScheduleExperiment][google.ads.googleads.v23.services.ExperimentService.ScheduleExperiment]. + resource_name (str): + Required. The scheduled experiment. + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, experiment_service.ScheduleExperimentRequest + ): + request = experiment_service.ScheduleExperimentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.schedule_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=experiment_service.ScheduleExperimentMetadata, + ) + + # Done; return the response. + return response + + def promote_experiment( + self, + request: Optional[ + Union[experiment_service.PromoteExperimentRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Promotes the trial campaign thus applying changes in the trial + campaign to the base campaign. This method returns a long + running operation that tracks the promotion of the experiment + campaign. If it fails, a list of errors can be retrieved using + the ListExperimentAsyncErrors method. The operation's metadata + will be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.PromoteExperimentRequest, dict]): + The request object. Request message for + [ExperimentService.PromoteExperiment][google.ads.googleads.v23.services.ExperimentService.PromoteExperiment]. + resource_name (str): + Required. The resource name of the + experiment to promote. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, experiment_service.PromoteExperimentRequest): + request = experiment_service.PromoteExperimentRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.promote_experiment + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=experiment_service.PromoteExperimentMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ExperimentServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ExperimentServiceClient",) diff --git a/google/ads/googleads/v23/services/services/experiment_service/pagers.py b/google/ads/googleads/v23/services/services/experiment_service/pagers.py new file mode 100644 index 000000000..ef82a5ec0 --- /dev/null +++ b/google/ads/googleads/v23/services/services/experiment_service/pagers.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Sequence, + Tuple, + Iterator, + Union, +) + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import experiment_service +from google.rpc import status_pb2 # type: ignore + + +class ListExperimentAsyncErrorsPager: + """A pager for iterating through ``list_experiment_async_errors`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.ListExperimentAsyncErrorsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``errors`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListExperimentAsyncErrors`` requests and continue to iterate + through the ``errors`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.ListExperimentAsyncErrorsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., experiment_service.ListExperimentAsyncErrorsResponse + ], + request: experiment_service.ListExperimentAsyncErrorsRequest, + response: experiment_service.ListExperimentAsyncErrorsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.ListExperimentAsyncErrorsRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.ListExperimentAsyncErrorsResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = experiment_service.ListExperimentAsyncErrorsRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[experiment_service.ListExperimentAsyncErrorsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[status_pb2.Status]: + for page in self.pages: + yield from page.errors + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListExperimentAsyncErrorsAsyncPager: + """A pager for iterating through ``list_experiment_async_errors`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.ListExperimentAsyncErrorsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``errors`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListExperimentAsyncErrors`` requests and continue to iterate + through the ``errors`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.ListExperimentAsyncErrorsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[experiment_service.ListExperimentAsyncErrorsResponse] + ], + request: experiment_service.ListExperimentAsyncErrorsRequest, + response: experiment_service.ListExperimentAsyncErrorsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.ListExperimentAsyncErrorsRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.ListExperimentAsyncErrorsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = experiment_service.ListExperimentAsyncErrorsRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[experiment_service.ListExperimentAsyncErrorsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[status_pb2.Status]: + async def async_generator(): + async for page in self.pages: + for response in page.errors: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/experiment_service/transports/README.rst b/google/ads/googleads/v23/services/services/experiment_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/experiment_service/transports/README.rst rename to google/ads/googleads/v23/services/services/experiment_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/experiment_service/transports/__init__.py b/google/ads/googleads/v23/services/services/experiment_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/experiment_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/experiment_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/experiment_service/transports/base.py b/google/ads/googleads/v23/services/services/experiment_service/transports/base.py new file mode 100644 index 000000000..24b6c6cd8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/experiment_service/transports/base.py @@ -0,0 +1,253 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import experiment_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ExperimentServiceTransport(abc.ABC): + """Abstract transport class for ExperimentService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_experiments: gapic_v1.method.wrap_method( + self.mutate_experiments, + default_timeout=None, + client_info=client_info, + ), + self.end_experiment: gapic_v1.method.wrap_method( + self.end_experiment, + default_timeout=None, + client_info=client_info, + ), + self.list_experiment_async_errors: gapic_v1.method.wrap_method( + self.list_experiment_async_errors, + default_timeout=None, + client_info=client_info, + ), + self.graduate_experiment: gapic_v1.method.wrap_method( + self.graduate_experiment, + default_timeout=None, + client_info=client_info, + ), + self.schedule_experiment: gapic_v1.method.wrap_method( + self.schedule_experiment, + default_timeout=None, + client_info=client_info, + ), + self.promote_experiment: gapic_v1.method.wrap_method( + self.promote_experiment, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def mutate_experiments( + self, + ) -> Callable[ + [experiment_service.MutateExperimentsRequest], + Union[ + experiment_service.MutateExperimentsResponse, + Awaitable[experiment_service.MutateExperimentsResponse], + ], + ]: + raise NotImplementedError() + + @property + def end_experiment( + self, + ) -> Callable[ + [experiment_service.EndExperimentRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def list_experiment_async_errors( + self, + ) -> Callable[ + [experiment_service.ListExperimentAsyncErrorsRequest], + Union[ + experiment_service.ListExperimentAsyncErrorsResponse, + Awaitable[experiment_service.ListExperimentAsyncErrorsResponse], + ], + ]: + raise NotImplementedError() + + @property + def graduate_experiment( + self, + ) -> Callable[ + [experiment_service.GraduateExperimentRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def schedule_experiment( + self, + ) -> Callable[ + [experiment_service.ScheduleExperimentRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def promote_experiment( + self, + ) -> Callable[ + [experiment_service.PromoteExperimentRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ExperimentServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/experiment_service/transports/grpc.py b/google/ads/googleads/v23/services/services/experiment_service/transports/grpc.py new file mode 100644 index 000000000..98b6dcdb3 --- /dev/null +++ b/google/ads/googleads/v23/services/services/experiment_service/transports/grpc.py @@ -0,0 +1,601 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import experiment_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ExperimentServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ExperimentService", + "rpcName": str(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.ads.googleads.v23.services.ExperimentService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ExperimentServiceGrpcTransport(ExperimentServiceTransport): + """gRPC backend transport for ExperimentService. + + Service to manage experiments. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # 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._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def mutate_experiments( + self, + ) -> Callable[ + [experiment_service.MutateExperimentsRequest], + experiment_service.MutateExperimentsResponse, + ]: + r"""Return a callable for the mutate experiments method over gRPC. + + Creates, updates, or removes experiments. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateExperimentsRequest], + ~.MutateExperimentsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_experiments" not in self._stubs: + self._stubs["mutate_experiments"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/MutateExperiments", + request_serializer=experiment_service.MutateExperimentsRequest.serialize, + response_deserializer=experiment_service.MutateExperimentsResponse.deserialize, + ) + ) + return self._stubs["mutate_experiments"] + + @property + def end_experiment( + self, + ) -> Callable[[experiment_service.EndExperimentRequest], empty_pb2.Empty]: + r"""Return a callable for the end experiment method over gRPC. + + Immediately ends an experiment, changing the experiment's + scheduled end date and without waiting for end of day. End date + is updated to be the time of the request. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.EndExperimentRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "end_experiment" not in self._stubs: + self._stubs["end_experiment"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/EndExperiment", + request_serializer=experiment_service.EndExperimentRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["end_experiment"] + + @property + def list_experiment_async_errors( + self, + ) -> Callable[ + [experiment_service.ListExperimentAsyncErrorsRequest], + experiment_service.ListExperimentAsyncErrorsResponse, + ]: + r"""Return a callable for the list experiment async errors method over gRPC. + + Returns all errors that occurred during the last Experiment + update (either scheduling or promotion). Supports standard list + paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListExperimentAsyncErrorsRequest], + ~.ListExperimentAsyncErrorsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_experiment_async_errors" not in self._stubs: + self._stubs["list_experiment_async_errors"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/ListExperimentAsyncErrors", + request_serializer=experiment_service.ListExperimentAsyncErrorsRequest.serialize, + response_deserializer=experiment_service.ListExperimentAsyncErrorsResponse.deserialize, + ) + ) + return self._stubs["list_experiment_async_errors"] + + @property + def graduate_experiment( + self, + ) -> Callable[ + [experiment_service.GraduateExperimentRequest], empty_pb2.Empty + ]: + r"""Return a callable for the graduate experiment method over gRPC. + + Graduates an experiment to a full campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GraduateExperimentRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "graduate_experiment" not in self._stubs: + self._stubs["graduate_experiment"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/GraduateExperiment", + request_serializer=experiment_service.GraduateExperimentRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + ) + return self._stubs["graduate_experiment"] + + @property + def schedule_experiment( + self, + ) -> Callable[ + [experiment_service.ScheduleExperimentRequest], operations_pb2.Operation + ]: + r"""Return a callable for the schedule experiment method over gRPC. + + Schedule an experiment. The in design campaign will be converted + into a real campaign (called the experiment campaign) that will + begin serving ads if successfully created. + + The experiment is scheduled immediately with status + INITIALIZING. This method returns a long running operation that + tracks the forking of the in design campaign. If the forking + fails, a list of errors can be retrieved using the + ListExperimentAsyncErrors method. The operation's metadata will + be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ScheduleExperimentRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "schedule_experiment" not in self._stubs: + self._stubs["schedule_experiment"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/ScheduleExperiment", + request_serializer=experiment_service.ScheduleExperimentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["schedule_experiment"] + + @property + def promote_experiment( + self, + ) -> Callable[ + [experiment_service.PromoteExperimentRequest], operations_pb2.Operation + ]: + r"""Return a callable for the promote experiment method over gRPC. + + Promotes the trial campaign thus applying changes in the trial + campaign to the base campaign. This method returns a long + running operation that tracks the promotion of the experiment + campaign. If it fails, a list of errors can be retrieved using + the ListExperimentAsyncErrors method. The operation's metadata + will be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.PromoteExperimentRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "promote_experiment" not in self._stubs: + self._stubs["promote_experiment"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/PromoteExperiment", + request_serializer=experiment_service.PromoteExperimentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["promote_experiment"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ExperimentServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/experiment_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/experiment_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..bd3ba61b1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/experiment_service/transports/grpc_asyncio.py @@ -0,0 +1,654 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import experiment_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ExperimentServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ExperimentService", + "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.ads.googleads.v23.services.ExperimentService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ExperimentServiceGrpcAsyncIOTransport(ExperimentServiceTransport): + """gRPC AsyncIO backend transport for ExperimentService. + + Service to manage experiments. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[ + operations_v1.OperationsAsyncClient + ] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # 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._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def mutate_experiments( + self, + ) -> Callable[ + [experiment_service.MutateExperimentsRequest], + Awaitable[experiment_service.MutateExperimentsResponse], + ]: + r"""Return a callable for the mutate experiments method over gRPC. + + Creates, updates, or removes experiments. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateExperimentsRequest], + Awaitable[~.MutateExperimentsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_experiments" not in self._stubs: + self._stubs["mutate_experiments"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/MutateExperiments", + request_serializer=experiment_service.MutateExperimentsRequest.serialize, + response_deserializer=experiment_service.MutateExperimentsResponse.deserialize, + ) + ) + return self._stubs["mutate_experiments"] + + @property + def end_experiment( + self, + ) -> Callable[ + [experiment_service.EndExperimentRequest], Awaitable[empty_pb2.Empty] + ]: + r"""Return a callable for the end experiment method over gRPC. + + Immediately ends an experiment, changing the experiment's + scheduled end date and without waiting for end of day. End date + is updated to be the time of the request. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.EndExperimentRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "end_experiment" not in self._stubs: + self._stubs["end_experiment"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/EndExperiment", + request_serializer=experiment_service.EndExperimentRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["end_experiment"] + + @property + def list_experiment_async_errors( + self, + ) -> Callable[ + [experiment_service.ListExperimentAsyncErrorsRequest], + Awaitable[experiment_service.ListExperimentAsyncErrorsResponse], + ]: + r"""Return a callable for the list experiment async errors method over gRPC. + + Returns all errors that occurred during the last Experiment + update (either scheduling or promotion). Supports standard list + paging. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListExperimentAsyncErrorsRequest], + Awaitable[~.ListExperimentAsyncErrorsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_experiment_async_errors" not in self._stubs: + self._stubs["list_experiment_async_errors"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/ListExperimentAsyncErrors", + request_serializer=experiment_service.ListExperimentAsyncErrorsRequest.serialize, + response_deserializer=experiment_service.ListExperimentAsyncErrorsResponse.deserialize, + ) + ) + return self._stubs["list_experiment_async_errors"] + + @property + def graduate_experiment( + self, + ) -> Callable[ + [experiment_service.GraduateExperimentRequest], + Awaitable[empty_pb2.Empty], + ]: + r"""Return a callable for the graduate experiment method over gRPC. + + Graduates an experiment to a full campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GraduateExperimentRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "graduate_experiment" not in self._stubs: + self._stubs["graduate_experiment"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/GraduateExperiment", + request_serializer=experiment_service.GraduateExperimentRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + ) + return self._stubs["graduate_experiment"] + + @property + def schedule_experiment( + self, + ) -> Callable[ + [experiment_service.ScheduleExperimentRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the schedule experiment method over gRPC. + + Schedule an experiment. The in design campaign will be converted + into a real campaign (called the experiment campaign) that will + begin serving ads if successfully created. + + The experiment is scheduled immediately with status + INITIALIZING. This method returns a long running operation that + tracks the forking of the in design campaign. If the forking + fails, a list of errors can be retrieved using the + ListExperimentAsyncErrors method. The operation's metadata will + be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ScheduleExperimentRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "schedule_experiment" not in self._stubs: + self._stubs["schedule_experiment"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/ScheduleExperiment", + request_serializer=experiment_service.ScheduleExperimentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["schedule_experiment"] + + @property + def promote_experiment( + self, + ) -> Callable[ + [experiment_service.PromoteExperimentRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the promote experiment method over gRPC. + + Promotes the trial campaign thus applying changes in the trial + campaign to the base campaign. This method returns a long + running operation that tracks the promotion of the experiment + campaign. If it fails, a list of errors can be retrieved using + the ListExperimentAsyncErrors method. The operation's metadata + will be a string containing the resource name of the created + experiment. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ExperimentError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.PromoteExperimentRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "promote_experiment" not in self._stubs: + self._stubs["promote_experiment"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ExperimentService/PromoteExperiment", + request_serializer=experiment_service.PromoteExperimentRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["promote_experiment"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_experiments: self._wrap_method( + self.mutate_experiments, + default_timeout=None, + client_info=client_info, + ), + self.end_experiment: self._wrap_method( + self.end_experiment, + default_timeout=None, + client_info=client_info, + ), + self.list_experiment_async_errors: self._wrap_method( + self.list_experiment_async_errors, + default_timeout=None, + client_info=client_info, + ), + self.graduate_experiment: self._wrap_method( + self.graduate_experiment, + default_timeout=None, + client_info=client_info, + ), + self.schedule_experiment: self._wrap_method( + self.schedule_experiment, + default_timeout=None, + client_info=client_info, + ), + self.promote_experiment: self._wrap_method( + self.promote_experiment, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ExperimentServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/geo_target_constant_service/__init__.py b/google/ads/googleads/v23/services/services/geo_target_constant_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/geo_target_constant_service/__init__.py rename to google/ads/googleads/v23/services/services/geo_target_constant_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/geo_target_constant_service/async_client.py b/google/ads/googleads/v23/services/services/geo_target_constant_service/async_client.py new file mode 100644 index 000000000..eb79a065a --- /dev/null +++ b/google/ads/googleads/v23/services/services/geo_target_constant_service/async_client.py @@ -0,0 +1,388 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import geo_target_constant_service +from .transports.base import ( + GeoTargetConstantServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import GeoTargetConstantServiceClient + +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 GeoTargetConstantServiceAsyncClient: + """Service to fetch geo target constants.""" + + _client: GeoTargetConstantServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = GeoTargetConstantServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = GeoTargetConstantServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + GeoTargetConstantServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = GeoTargetConstantServiceClient._DEFAULT_UNIVERSE + + geo_target_constant_path = staticmethod( + GeoTargetConstantServiceClient.geo_target_constant_path + ) + parse_geo_target_constant_path = staticmethod( + GeoTargetConstantServiceClient.parse_geo_target_constant_path + ) + common_billing_account_path = staticmethod( + GeoTargetConstantServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + GeoTargetConstantServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + GeoTargetConstantServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + GeoTargetConstantServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + GeoTargetConstantServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + GeoTargetConstantServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + GeoTargetConstantServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + GeoTargetConstantServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + GeoTargetConstantServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + GeoTargetConstantServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GeoTargetConstantServiceAsyncClient: The constructed client. + """ + return GeoTargetConstantServiceClient.from_service_account_info.__func__(GeoTargetConstantServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GeoTargetConstantServiceAsyncClient: The constructed client. + """ + return GeoTargetConstantServiceClient.from_service_account_file.__func__(GeoTargetConstantServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return GeoTargetConstantServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> GeoTargetConstantServiceTransport: + """Returns the transport used by the client instance. + + Returns: + GeoTargetConstantServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = GeoTargetConstantServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + GeoTargetConstantServiceTransport, + Callable[..., GeoTargetConstantServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the geo target constant service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,GeoTargetConstantServiceTransport,Callable[..., GeoTargetConstantServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the GeoTargetConstantServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = GeoTargetConstantServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.GeoTargetConstantServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.GeoTargetConstantService", + "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.ads.googleads.v23.services.GeoTargetConstantService", + "credentialsType": None, + } + ), + ) + + async def suggest_geo_target_constants( + self, + request: Optional[ + Union[ + geo_target_constant_service.SuggestGeoTargetConstantsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> geo_target_constant_service.SuggestGeoTargetConstantsResponse: + r"""Returns GeoTargetConstant suggestions by location name or by + resource name. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `GeoTargetConstantSuggestionError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.SuggestGeoTargetConstantsRequest, dict]]): + The request object. Request message for + [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v23.services.GeoTargetConstantService.SuggestGeoTargetConstants]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestGeoTargetConstantsResponse: + Response message for + [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v23.services.GeoTargetConstantService.SuggestGeoTargetConstants]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + geo_target_constant_service.SuggestGeoTargetConstantsRequest, + ): + request = ( + geo_target_constant_service.SuggestGeoTargetConstantsRequest( + request + ) + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.suggest_geo_target_constants + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "GeoTargetConstantServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("GeoTargetConstantServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/geo_target_constant_service/client.py b/google/ads/googleads/v23/services/services/geo_target_constant_service/client.py new file mode 100644 index 000000000..1e783dcf3 --- /dev/null +++ b/google/ads/googleads/v23/services/services/geo_target_constant_service/client.py @@ -0,0 +1,852 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import geo_target_constant_service +from .transports.base import ( + GeoTargetConstantServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import GeoTargetConstantServiceGrpcTransport +from .transports.grpc_asyncio import ( + GeoTargetConstantServiceGrpcAsyncIOTransport, +) + + +class GeoTargetConstantServiceClientMeta(type): + """Metaclass for the GeoTargetConstantService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[GeoTargetConstantServiceTransport]] + _transport_registry["grpc"] = GeoTargetConstantServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + GeoTargetConstantServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[GeoTargetConstantServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class GeoTargetConstantServiceClient( + metaclass=GeoTargetConstantServiceClientMeta +): + """Service to fetch geo target constants.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GeoTargetConstantServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GeoTargetConstantServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> GeoTargetConstantServiceTransport: + """Returns the transport used by the client instance. + + Returns: + GeoTargetConstantServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def geo_target_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + GeoTargetConstantServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + GeoTargetConstantServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = GeoTargetConstantServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = GeoTargetConstantServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = GeoTargetConstantServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = GeoTargetConstantServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + GeoTargetConstantServiceTransport, + Callable[..., GeoTargetConstantServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the geo target constant service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,GeoTargetConstantServiceTransport,Callable[..., GeoTargetConstantServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the GeoTargetConstantServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = GeoTargetConstantServiceClient._read_environment_variables() + self._client_cert_source = ( + GeoTargetConstantServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + GeoTargetConstantServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, GeoTargetConstantServiceTransport + ) + if transport_provided: + # transport is a GeoTargetConstantServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(GeoTargetConstantServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or GeoTargetConstantServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[GeoTargetConstantServiceTransport], + Callable[..., GeoTargetConstantServiceTransport], + ] = ( + GeoTargetConstantServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., GeoTargetConstantServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.GeoTargetConstantServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.GeoTargetConstantService", + "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.ads.googleads.v23.services.GeoTargetConstantService", + "credentialsType": None, + } + ), + ) + + def suggest_geo_target_constants( + self, + request: Optional[ + Union[ + geo_target_constant_service.SuggestGeoTargetConstantsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> geo_target_constant_service.SuggestGeoTargetConstantsResponse: + r"""Returns GeoTargetConstant suggestions by location name or by + resource name. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `GeoTargetConstantSuggestionError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.SuggestGeoTargetConstantsRequest, dict]): + The request object. Request message for + [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v23.services.GeoTargetConstantService.SuggestGeoTargetConstants]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestGeoTargetConstantsResponse: + Response message for + [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v23.services.GeoTargetConstantService.SuggestGeoTargetConstants]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + geo_target_constant_service.SuggestGeoTargetConstantsRequest, + ): + request = ( + geo_target_constant_service.SuggestGeoTargetConstantsRequest( + request + ) + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.suggest_geo_target_constants + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "GeoTargetConstantServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("GeoTargetConstantServiceClient",) diff --git a/google/ads/googleads/v19/services/services/geo_target_constant_service/transports/README.rst b/google/ads/googleads/v23/services/services/geo_target_constant_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/geo_target_constant_service/transports/README.rst rename to google/ads/googleads/v23/services/services/geo_target_constant_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/geo_target_constant_service/transports/__init__.py b/google/ads/googleads/v23/services/services/geo_target_constant_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/geo_target_constant_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/geo_target_constant_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/geo_target_constant_service/transports/base.py b/google/ads/googleads/v23/services/services/geo_target_constant_service/transports/base.py new file mode 100644 index 000000000..f982c5aa4 --- /dev/null +++ b/google/ads/googleads/v23/services/services/geo_target_constant_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import geo_target_constant_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class GeoTargetConstantServiceTransport(abc.ABC): + """Abstract transport class for GeoTargetConstantService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.suggest_geo_target_constants: gapic_v1.method.wrap_method( + self.suggest_geo_target_constants, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def suggest_geo_target_constants( + self, + ) -> Callable[ + [geo_target_constant_service.SuggestGeoTargetConstantsRequest], + Union[ + geo_target_constant_service.SuggestGeoTargetConstantsResponse, + Awaitable[ + geo_target_constant_service.SuggestGeoTargetConstantsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("GeoTargetConstantServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/geo_target_constant_service/transports/grpc.py b/google/ads/googleads/v23/services/services/geo_target_constant_service/transports/grpc.py new file mode 100644 index 000000000..6b25235c2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/geo_target_constant_service/transports/grpc.py @@ -0,0 +1,389 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import geo_target_constant_service +from .base import GeoTargetConstantServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.GeoTargetConstantService", + "rpcName": str(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.ads.googleads.v23.services.GeoTargetConstantService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class GeoTargetConstantServiceGrpcTransport(GeoTargetConstantServiceTransport): + """gRPC backend transport for GeoTargetConstantService. + + Service to fetch geo target constants. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def suggest_geo_target_constants( + self, + ) -> Callable[ + [geo_target_constant_service.SuggestGeoTargetConstantsRequest], + geo_target_constant_service.SuggestGeoTargetConstantsResponse, + ]: + r"""Return a callable for the suggest geo target constants method over gRPC. + + Returns GeoTargetConstant suggestions by location name or by + resource name. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `GeoTargetConstantSuggestionError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SuggestGeoTargetConstantsRequest], + ~.SuggestGeoTargetConstantsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_geo_target_constants" not in self._stubs: + self._stubs["suggest_geo_target_constants"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GeoTargetConstantService/SuggestGeoTargetConstants", + request_serializer=geo_target_constant_service.SuggestGeoTargetConstantsRequest.serialize, + response_deserializer=geo_target_constant_service.SuggestGeoTargetConstantsResponse.deserialize, + ) + ) + return self._stubs["suggest_geo_target_constants"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("GeoTargetConstantServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/geo_target_constant_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/geo_target_constant_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..22d21024e --- /dev/null +++ b/google/ads/googleads/v23/services/services/geo_target_constant_service/transports/grpc_asyncio.py @@ -0,0 +1,414 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import geo_target_constant_service +from .base import GeoTargetConstantServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.GeoTargetConstantService", + "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.ads.googleads.v23.services.GeoTargetConstantService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class GeoTargetConstantServiceGrpcAsyncIOTransport( + GeoTargetConstantServiceTransport +): + """gRPC AsyncIO backend transport for GeoTargetConstantService. + + Service to fetch geo target constants. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def suggest_geo_target_constants( + self, + ) -> Callable[ + [geo_target_constant_service.SuggestGeoTargetConstantsRequest], + Awaitable[ + geo_target_constant_service.SuggestGeoTargetConstantsResponse + ], + ]: + r"""Return a callable for the suggest geo target constants method over gRPC. + + Returns GeoTargetConstant suggestions by location name or by + resource name. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ + `GeoTargetConstantSuggestionError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SuggestGeoTargetConstantsRequest], + Awaitable[~.SuggestGeoTargetConstantsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_geo_target_constants" not in self._stubs: + self._stubs["suggest_geo_target_constants"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GeoTargetConstantService/SuggestGeoTargetConstants", + request_serializer=geo_target_constant_service.SuggestGeoTargetConstantsRequest.serialize, + response_deserializer=geo_target_constant_service.SuggestGeoTargetConstantsResponse.deserialize, + ) + ) + return self._stubs["suggest_geo_target_constants"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.suggest_geo_target_constants: self._wrap_method( + self.suggest_geo_target_constants, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("GeoTargetConstantServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v23/services/services/goal_service/__init__.py b/google/ads/googleads/v23/services/services/goal_service/__init__.py new file mode 100644 index 000000000..f4aca1827 --- /dev/null +++ b/google/ads/googleads/v23/services/services/goal_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import GoalServiceClient +from .async_client import GoalServiceAsyncClient + +__all__ = ( + "GoalServiceClient", + "GoalServiceAsyncClient", +) diff --git a/google/ads/googleads/v23/services/services/goal_service/async_client.py b/google/ads/googleads/v23/services/services/goal_service/async_client.py new file mode 100644 index 000000000..8905c061d --- /dev/null +++ b/google/ads/googleads/v23/services/services/goal_service/async_client.py @@ -0,0 +1,404 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import goal_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import GoalServiceTransport, DEFAULT_CLIENT_INFO +from .client import GoalServiceClient + +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 GoalServiceAsyncClient: + """Service to manage goals.""" + + _client: GoalServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = GoalServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = GoalServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = GoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = GoalServiceClient._DEFAULT_UNIVERSE + + customer_path = staticmethod(GoalServiceClient.customer_path) + parse_customer_path = staticmethod(GoalServiceClient.parse_customer_path) + goal_path = staticmethod(GoalServiceClient.goal_path) + parse_goal_path = staticmethod(GoalServiceClient.parse_goal_path) + common_billing_account_path = staticmethod( + GoalServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + GoalServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(GoalServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + GoalServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + GoalServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + GoalServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(GoalServiceClient.common_project_path) + parse_common_project_path = staticmethod( + GoalServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(GoalServiceClient.common_location_path) + parse_common_location_path = staticmethod( + GoalServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoalServiceAsyncClient: The constructed client. + """ + return GoalServiceClient.from_service_account_info.__func__(GoalServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoalServiceAsyncClient: The constructed client. + """ + return GoalServiceClient.from_service_account_file.__func__(GoalServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return GoalServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> GoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + GoalServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = GoalServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, GoalServiceTransport, Callable[..., GoalServiceTransport] + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the goal service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,GoalServiceTransport,Callable[..., GoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the GoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = GoalServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.GoalServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.GoalService", + "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.ads.googleads.v23.services.GoalService", + "credentialsType": None, + } + ), + ) + + async def mutate_goals( + self, + request: Optional[Union[goal_service.MutateGoalsRequest, dict]] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[goal_service.GoalOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goal_service.MutateGoalsResponse: + r"""Create or update goals. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `GoalError <>`__ `GoalServicesError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateGoalsRequest, dict]]): + The request object. Request message for + [GoalService.MutateGoals][google.ads.googleads.v23.services.GoalService.MutateGoals]. + customer_id (:class:`str`): + Required. The ID of the customer + whose goals are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.GoalOperation]`): + Required. The list of operations to + perform on the goals. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateGoalsResponse: + Response message for a goal mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, goal_service.MutateGoalsRequest): + request = goal_service.MutateGoalsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_goals + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "GoalServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("GoalServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/goal_service/client.py b/google/ads/googleads/v23/services/services/goal_service/client.py new file mode 100644 index 000000000..84cba6304 --- /dev/null +++ b/google/ads/googleads/v23/services/services/goal_service/client.py @@ -0,0 +1,886 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import goal_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import GoalServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import GoalServiceGrpcTransport +from .transports.grpc_asyncio import GoalServiceGrpcAsyncIOTransport + + +class GoalServiceClientMeta(type): + """Metaclass for the GoalService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[GoalServiceTransport]] + _transport_registry["grpc"] = GoalServiceGrpcTransport + _transport_registry["grpc_asyncio"] = GoalServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[GoalServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class GoalServiceClient(metaclass=GoalServiceClientMeta): + """Service to manage goals.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoalServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> GoalServiceTransport: + """Returns the transport used by the client instance. + + Returns: + GoalServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def goal_path( + customer_id: str, + unified_goal_id: str, + ) -> str: + """Returns a fully-qualified goal string.""" + return "customers/{customer_id}/goals/{unified_goal_id}".format( + customer_id=customer_id, + unified_goal_id=unified_goal_id, + ) + + @staticmethod + def parse_goal_path(path: str) -> Dict[str, str]: + """Parses a goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/goals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = GoalServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = GoalServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = GoalServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = GoalServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = GoalServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = GoalServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, GoalServiceTransport, Callable[..., GoalServiceTransport] + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the goal service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,GoalServiceTransport,Callable[..., GoalServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the GoalServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = GoalServiceClient._read_environment_variables() + self._client_cert_source = GoalServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = GoalServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, GoalServiceTransport) + if transport_provided: + # transport is a GoalServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(GoalServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or GoalServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[GoalServiceTransport], Callable[..., GoalServiceTransport] + ] = ( + GoalServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., GoalServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.GoalServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.GoalService", + "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.ads.googleads.v23.services.GoalService", + "credentialsType": None, + } + ), + ) + + def mutate_goals( + self, + request: Optional[Union[goal_service.MutateGoalsRequest, dict]] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[goal_service.GoalOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> goal_service.MutateGoalsResponse: + r"""Create or update goals. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `GoalError <>`__ `GoalServicesError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateGoalsRequest, dict]): + The request object. Request message for + [GoalService.MutateGoals][google.ads.googleads.v23.services.GoalService.MutateGoals]. + customer_id (str): + Required. The ID of the customer + whose goals are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.GoalOperation]): + Required. The list of operations to + perform on the goals. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateGoalsResponse: + Response message for a goal mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, goal_service.MutateGoalsRequest): + request = goal_service.MutateGoalsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_goals] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "GoalServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("GoalServiceClient",) diff --git a/google/ads/googleads/v23/services/services/goal_service/transports/README.rst b/google/ads/googleads/v23/services/services/goal_service/transports/README.rst new file mode 100644 index 000000000..829459e5e --- /dev/null +++ b/google/ads/googleads/v23/services/services/goal_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`GoalServiceTransport` is the ABC for all transports. +- public child `GoalServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `GoalServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseGoalServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `GoalServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/google/ads/googleads/v23/services/services/goal_service/transports/__init__.py b/google/ads/googleads/v23/services/services/goal_service/transports/__init__.py new file mode 100644 index 000000000..bad9461b5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/goal_service/transports/__init__.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict + +from .base import GoalServiceTransport +from .grpc import GoalServiceGrpcTransport +from .grpc_asyncio import GoalServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[GoalServiceTransport]] +_transport_registry["grpc"] = GoalServiceGrpcTransport +_transport_registry["grpc_asyncio"] = GoalServiceGrpcAsyncIOTransport + +__all__ = ( + "GoalServiceTransport", + "GoalServiceGrpcTransport", + "GoalServiceGrpcAsyncIOTransport", +) diff --git a/google/ads/googleads/v23/services/services/goal_service/transports/base.py b/google/ads/googleads/v23/services/services/goal_service/transports/base.py new file mode 100644 index 000000000..e7e242ddb --- /dev/null +++ b/google/ads/googleads/v23/services/services/goal_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import goal_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class GoalServiceTransport(abc.ABC): + """Abstract transport class for GoalService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_goals: gapic_v1.method.wrap_method( + self.mutate_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_goals( + self, + ) -> Callable[ + [goal_service.MutateGoalsRequest], + Union[ + goal_service.MutateGoalsResponse, + Awaitable[goal_service.MutateGoalsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("GoalServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/goal_service/transports/grpc.py b/google/ads/googleads/v23/services/services/goal_service/transports/grpc.py new file mode 100644 index 000000000..9acfcb8c9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/goal_service/transports/grpc.py @@ -0,0 +1,385 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import goal_service +from .base import GoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.GoalService", + "rpcName": str(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.ads.googleads.v23.services.GoalService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class GoalServiceGrpcTransport(GoalServiceTransport): + """gRPC backend transport for GoalService. + + Service to manage goals. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_goals( + self, + ) -> Callable[ + [goal_service.MutateGoalsRequest], goal_service.MutateGoalsResponse + ]: + r"""Return a callable for the mutate goals method over gRPC. + + Create or update goals. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `GoalError <>`__ `GoalServicesError <>`__ + + Returns: + Callable[[~.MutateGoalsRequest], + ~.MutateGoalsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_goals" not in self._stubs: + self._stubs["mutate_goals"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GoalService/MutateGoals", + request_serializer=goal_service.MutateGoalsRequest.serialize, + response_deserializer=goal_service.MutateGoalsResponse.deserialize, + ) + return self._stubs["mutate_goals"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("GoalServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/goal_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/goal_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..99f273d2d --- /dev/null +++ b/google/ads/googleads/v23/services/services/goal_service/transports/grpc_asyncio.py @@ -0,0 +1,407 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import goal_service +from .base import GoalServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.GoalService", + "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.ads.googleads.v23.services.GoalService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class GoalServiceGrpcAsyncIOTransport(GoalServiceTransport): + """gRPC AsyncIO backend transport for GoalService. + + Service to manage goals. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_goals( + self, + ) -> Callable[ + [goal_service.MutateGoalsRequest], + Awaitable[goal_service.MutateGoalsResponse], + ]: + r"""Return a callable for the mutate goals method over gRPC. + + Create or update goals. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + `GoalError <>`__ `GoalServicesError <>`__ + + Returns: + Callable[[~.MutateGoalsRequest], + Awaitable[~.MutateGoalsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_goals" not in self._stubs: + self._stubs["mutate_goals"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GoalService/MutateGoals", + request_serializer=goal_service.MutateGoalsRequest.serialize, + response_deserializer=goal_service.MutateGoalsResponse.deserialize, + ) + return self._stubs["mutate_goals"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_goals: self._wrap_method( + self.mutate_goals, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("GoalServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/google_ads_field_service/__init__.py b/google/ads/googleads/v23/services/services/google_ads_field_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/google_ads_field_service/__init__.py rename to google/ads/googleads/v23/services/services/google_ads_field_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/google_ads_field_service/async_client.py b/google/ads/googleads/v23/services/services/google_ads_field_service/async_client.py new file mode 100644 index 000000000..1b0b90919 --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_field_service/async_client.py @@ -0,0 +1,514 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.resources.types import google_ads_field +from google.ads.googleads.v23.services.services.google_ads_field_service import ( + pagers, +) +from google.ads.googleads.v23.services.types import google_ads_field_service +from .transports.base import GoogleAdsFieldServiceTransport, DEFAULT_CLIENT_INFO +from .client import GoogleAdsFieldServiceClient + +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 GoogleAdsFieldServiceAsyncClient: + """Service to fetch Google Ads API fields.""" + + _client: GoogleAdsFieldServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = GoogleAdsFieldServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = GoogleAdsFieldServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + GoogleAdsFieldServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = GoogleAdsFieldServiceClient._DEFAULT_UNIVERSE + + google_ads_field_path = staticmethod( + GoogleAdsFieldServiceClient.google_ads_field_path + ) + parse_google_ads_field_path = staticmethod( + GoogleAdsFieldServiceClient.parse_google_ads_field_path + ) + common_billing_account_path = staticmethod( + GoogleAdsFieldServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + GoogleAdsFieldServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + GoogleAdsFieldServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + GoogleAdsFieldServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + GoogleAdsFieldServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + GoogleAdsFieldServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + GoogleAdsFieldServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + GoogleAdsFieldServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + GoogleAdsFieldServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + GoogleAdsFieldServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsFieldServiceAsyncClient: The constructed client. + """ + return GoogleAdsFieldServiceClient.from_service_account_info.__func__(GoogleAdsFieldServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsFieldServiceAsyncClient: The constructed client. + """ + return GoogleAdsFieldServiceClient.from_service_account_file.__func__(GoogleAdsFieldServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return GoogleAdsFieldServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> GoogleAdsFieldServiceTransport: + """Returns the transport used by the client instance. + + Returns: + GoogleAdsFieldServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = GoogleAdsFieldServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + GoogleAdsFieldServiceTransport, + Callable[..., GoogleAdsFieldServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the google ads field service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,GoogleAdsFieldServiceTransport,Callable[..., GoogleAdsFieldServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the GoogleAdsFieldServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = GoogleAdsFieldServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.GoogleAdsFieldServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.GoogleAdsFieldService", + "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.ads.googleads.v23.services.GoogleAdsFieldService", + "credentialsType": None, + } + ), + ) + + async def get_google_ads_field( + self, + request: Optional[ + Union[google_ads_field_service.GetGoogleAdsFieldRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> google_ads_field.GoogleAdsField: + r"""Returns just the requested field. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GetGoogleAdsFieldRequest, dict]]): + The request object. Request message for + [GoogleAdsFieldService.GetGoogleAdsField][google.ads.googleads.v23.services.GoogleAdsFieldService.GetGoogleAdsField]. + resource_name (:class:`str`): + Required. The resource name of the + field to get. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.resources.types.GoogleAdsField: + A field or resource (artifact) used + by GoogleAdsService. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, google_ads_field_service.GetGoogleAdsFieldRequest + ): + request = google_ads_field_service.GetGoogleAdsFieldRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.get_google_ads_field + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def search_google_ads_fields( + self, + request: Optional[ + Union[google_ads_field_service.SearchGoogleAdsFieldsRequest, dict] + ] = None, + *, + query: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.SearchGoogleAdsFieldsAsyncPager: + r"""Returns all fields that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QueryError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.SearchGoogleAdsFieldsRequest, dict]]): + The request object. Request message for + [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v23.services.GoogleAdsFieldService.SearchGoogleAdsFields]. + query (:class:`str`): + Required. The query string. + This corresponds to the ``query`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.google_ads_field_service.pagers.SearchGoogleAdsFieldsAsyncPager: + Response message for + [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v23.services.GoogleAdsFieldService.SearchGoogleAdsFields]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [query] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, google_ads_field_service.SearchGoogleAdsFieldsRequest + ): + request = google_ads_field_service.SearchGoogleAdsFieldsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if query is not None: + request.query = query + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.search_google_ads_fields + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.SearchGoogleAdsFieldsAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "GoogleAdsFieldServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("GoogleAdsFieldServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/google_ads_field_service/client.py b/google/ads/googleads/v23/services/services/google_ads_field_service/client.py new file mode 100644 index 000000000..2b7bd239d --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_field_service/client.py @@ -0,0 +1,974 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.resources.types import google_ads_field +from google.ads.googleads.v23.services.services.google_ads_field_service import ( + pagers, +) +from google.ads.googleads.v23.services.types import google_ads_field_service +from .transports.base import GoogleAdsFieldServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import GoogleAdsFieldServiceGrpcTransport +from .transports.grpc_asyncio import GoogleAdsFieldServiceGrpcAsyncIOTransport + + +class GoogleAdsFieldServiceClientMeta(type): + """Metaclass for the GoogleAdsFieldService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[GoogleAdsFieldServiceTransport]] + _transport_registry["grpc"] = GoogleAdsFieldServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + GoogleAdsFieldServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[GoogleAdsFieldServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class GoogleAdsFieldServiceClient(metaclass=GoogleAdsFieldServiceClientMeta): + """Service to fetch Google Ads API fields.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsFieldServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsFieldServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> GoogleAdsFieldServiceTransport: + """Returns the transport used by the client instance. + + Returns: + GoogleAdsFieldServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def google_ads_field_path( + google_ads_field: str, + ) -> str: + """Returns a fully-qualified google_ads_field string.""" + return "googleAdsFields/{google_ads_field}".format( + google_ads_field=google_ads_field, + ) + + @staticmethod + def parse_google_ads_field_path(path: str) -> Dict[str, str]: + """Parses a google_ads_field path into its component segments.""" + m = re.match(r"^googleAdsFields/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + GoogleAdsFieldServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + GoogleAdsFieldServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = GoogleAdsFieldServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = GoogleAdsFieldServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + GoogleAdsFieldServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = GoogleAdsFieldServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + GoogleAdsFieldServiceTransport, + Callable[..., GoogleAdsFieldServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the google ads field service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,GoogleAdsFieldServiceTransport,Callable[..., GoogleAdsFieldServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the GoogleAdsFieldServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = GoogleAdsFieldServiceClient._read_environment_variables() + self._client_cert_source = ( + GoogleAdsFieldServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + GoogleAdsFieldServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, GoogleAdsFieldServiceTransport + ) + if transport_provided: + # transport is a GoogleAdsFieldServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(GoogleAdsFieldServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or GoogleAdsFieldServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[GoogleAdsFieldServiceTransport], + Callable[..., GoogleAdsFieldServiceTransport], + ] = ( + GoogleAdsFieldServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., GoogleAdsFieldServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.GoogleAdsFieldServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.GoogleAdsFieldService", + "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.ads.googleads.v23.services.GoogleAdsFieldService", + "credentialsType": None, + } + ), + ) + + def get_google_ads_field( + self, + request: Optional[ + Union[google_ads_field_service.GetGoogleAdsFieldRequest, dict] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> google_ads_field.GoogleAdsField: + r"""Returns just the requested field. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GetGoogleAdsFieldRequest, dict]): + The request object. Request message for + [GoogleAdsFieldService.GetGoogleAdsField][google.ads.googleads.v23.services.GoogleAdsFieldService.GetGoogleAdsField]. + resource_name (str): + Required. The resource name of the + field to get. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.resources.types.GoogleAdsField: + A field or resource (artifact) used + by GoogleAdsService. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, google_ads_field_service.GetGoogleAdsFieldRequest + ): + request = google_ads_field_service.GetGoogleAdsFieldRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.get_google_ads_field + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def search_google_ads_fields( + self, + request: Optional[ + Union[google_ads_field_service.SearchGoogleAdsFieldsRequest, dict] + ] = None, + *, + query: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.SearchGoogleAdsFieldsPager: + r"""Returns all fields that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QueryError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.SearchGoogleAdsFieldsRequest, dict]): + The request object. Request message for + [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v23.services.GoogleAdsFieldService.SearchGoogleAdsFields]. + query (str): + Required. The query string. + This corresponds to the ``query`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.google_ads_field_service.pagers.SearchGoogleAdsFieldsPager: + Response message for + [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v23.services.GoogleAdsFieldService.SearchGoogleAdsFields]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [query] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, google_ads_field_service.SearchGoogleAdsFieldsRequest + ): + request = google_ads_field_service.SearchGoogleAdsFieldsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if query is not None: + request.query = query + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.search_google_ads_fields + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.SearchGoogleAdsFieldsPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "GoogleAdsFieldServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("GoogleAdsFieldServiceClient",) diff --git a/google/ads/googleads/v23/services/services/google_ads_field_service/pagers.py b/google/ads/googleads/v23/services/services/google_ads_field_service/pagers.py new file mode 100644 index 000000000..7a799536d --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_field_service/pagers.py @@ -0,0 +1,209 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Sequence, + Tuple, + Iterator, + Union, +) + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.resources.types import google_ads_field +from google.ads.googleads.v23.services.types import google_ads_field_service + + +class SearchGoogleAdsFieldsPager: + """A pager for iterating through ``search_google_ads_fields`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.SearchGoogleAdsFieldsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``SearchGoogleAdsFields`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.SearchGoogleAdsFieldsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., google_ads_field_service.SearchGoogleAdsFieldsResponse + ], + request: google_ads_field_service.SearchGoogleAdsFieldsRequest, + response: google_ads_field_service.SearchGoogleAdsFieldsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.SearchGoogleAdsFieldsRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.SearchGoogleAdsFieldsResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = google_ads_field_service.SearchGoogleAdsFieldsRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[google_ads_field_service.SearchGoogleAdsFieldsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[google_ads_field.GoogleAdsField]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class SearchGoogleAdsFieldsAsyncPager: + """A pager for iterating through ``search_google_ads_fields`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.SearchGoogleAdsFieldsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``SearchGoogleAdsFields`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.SearchGoogleAdsFieldsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., + Awaitable[google_ads_field_service.SearchGoogleAdsFieldsResponse], + ], + request: google_ads_field_service.SearchGoogleAdsFieldsRequest, + response: google_ads_field_service.SearchGoogleAdsFieldsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.SearchGoogleAdsFieldsRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.SearchGoogleAdsFieldsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = google_ads_field_service.SearchGoogleAdsFieldsRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[google_ads_field_service.SearchGoogleAdsFieldsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[google_ads_field.GoogleAdsField]: + async def async_generator(): + async for page in self.pages: + for response in page.results: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/google_ads_field_service/transports/README.rst b/google/ads/googleads/v23/services/services/google_ads_field_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/google_ads_field_service/transports/README.rst rename to google/ads/googleads/v23/services/services/google_ads_field_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/google_ads_field_service/transports/__init__.py b/google/ads/googleads/v23/services/services/google_ads_field_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/google_ads_field_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/google_ads_field_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/google_ads_field_service/transports/base.py b/google/ads/googleads/v23/services/services/google_ads_field_service/transports/base.py new file mode 100644 index 000000000..6c69b734e --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_field_service/transports/base.py @@ -0,0 +1,191 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.resources.types import google_ads_field +from google.ads.googleads.v23.services.types import google_ads_field_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class GoogleAdsFieldServiceTransport(abc.ABC): + """Abstract transport class for GoogleAdsFieldService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.get_google_ads_field: gapic_v1.method.wrap_method( + self.get_google_ads_field, + default_timeout=None, + client_info=client_info, + ), + self.search_google_ads_fields: gapic_v1.method.wrap_method( + self.search_google_ads_fields, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def get_google_ads_field( + self, + ) -> Callable[ + [google_ads_field_service.GetGoogleAdsFieldRequest], + Union[ + google_ads_field.GoogleAdsField, + Awaitable[google_ads_field.GoogleAdsField], + ], + ]: + raise NotImplementedError() + + @property + def search_google_ads_fields( + self, + ) -> Callable[ + [google_ads_field_service.SearchGoogleAdsFieldsRequest], + Union[ + google_ads_field_service.SearchGoogleAdsFieldsResponse, + Awaitable[google_ads_field_service.SearchGoogleAdsFieldsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("GoogleAdsFieldServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/google_ads_field_service/transports/grpc.py b/google/ads/googleads/v23/services/services/google_ads_field_service/transports/grpc.py new file mode 100644 index 000000000..7894e1b36 --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_field_service/transports/grpc.py @@ -0,0 +1,424 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.resources.types import google_ads_field +from google.ads.googleads.v23.services.types import google_ads_field_service +from .base import GoogleAdsFieldServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.GoogleAdsFieldService", + "rpcName": str(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.ads.googleads.v23.services.GoogleAdsFieldService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class GoogleAdsFieldServiceGrpcTransport(GoogleAdsFieldServiceTransport): + """gRPC backend transport for GoogleAdsFieldService. + + Service to fetch Google Ads API fields. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def get_google_ads_field( + self, + ) -> Callable[ + [google_ads_field_service.GetGoogleAdsFieldRequest], + google_ads_field.GoogleAdsField, + ]: + r"""Return a callable for the get google ads field method over gRPC. + + Returns just the requested field. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GetGoogleAdsFieldRequest], + ~.GoogleAdsField]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_google_ads_field" not in self._stubs: + self._stubs["get_google_ads_field"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GoogleAdsFieldService/GetGoogleAdsField", + request_serializer=google_ads_field_service.GetGoogleAdsFieldRequest.serialize, + response_deserializer=google_ads_field.GoogleAdsField.deserialize, + ) + ) + return self._stubs["get_google_ads_field"] + + @property + def search_google_ads_fields( + self, + ) -> Callable[ + [google_ads_field_service.SearchGoogleAdsFieldsRequest], + google_ads_field_service.SearchGoogleAdsFieldsResponse, + ]: + r"""Return a callable for the search google ads fields method over gRPC. + + Returns all fields that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QueryError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.SearchGoogleAdsFieldsRequest], + ~.SearchGoogleAdsFieldsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "search_google_ads_fields" not in self._stubs: + self._stubs["search_google_ads_fields"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GoogleAdsFieldService/SearchGoogleAdsFields", + request_serializer=google_ads_field_service.SearchGoogleAdsFieldsRequest.serialize, + response_deserializer=google_ads_field_service.SearchGoogleAdsFieldsResponse.deserialize, + ) + ) + return self._stubs["search_google_ads_fields"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("GoogleAdsFieldServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/google_ads_field_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/google_ads_field_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..acae120eb --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_field_service/transports/grpc_asyncio.py @@ -0,0 +1,450 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.resources.types import google_ads_field +from google.ads.googleads.v23.services.types import google_ads_field_service +from .base import GoogleAdsFieldServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.GoogleAdsFieldService", + "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.ads.googleads.v23.services.GoogleAdsFieldService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class GoogleAdsFieldServiceGrpcAsyncIOTransport(GoogleAdsFieldServiceTransport): + """gRPC AsyncIO backend transport for GoogleAdsFieldService. + + Service to fetch Google Ads API fields. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def get_google_ads_field( + self, + ) -> Callable[ + [google_ads_field_service.GetGoogleAdsFieldRequest], + Awaitable[google_ads_field.GoogleAdsField], + ]: + r"""Return a callable for the get google ads field method over gRPC. + + Returns just the requested field. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GetGoogleAdsFieldRequest], + Awaitable[~.GoogleAdsField]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_google_ads_field" not in self._stubs: + self._stubs["get_google_ads_field"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GoogleAdsFieldService/GetGoogleAdsField", + request_serializer=google_ads_field_service.GetGoogleAdsFieldRequest.serialize, + response_deserializer=google_ads_field.GoogleAdsField.deserialize, + ) + ) + return self._stubs["get_google_ads_field"] + + @property + def search_google_ads_fields( + self, + ) -> Callable[ + [google_ads_field_service.SearchGoogleAdsFieldsRequest], + Awaitable[google_ads_field_service.SearchGoogleAdsFieldsResponse], + ]: + r"""Return a callable for the search google ads fields method over gRPC. + + Returns all fields that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QueryError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.SearchGoogleAdsFieldsRequest], + Awaitable[~.SearchGoogleAdsFieldsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "search_google_ads_fields" not in self._stubs: + self._stubs["search_google_ads_fields"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GoogleAdsFieldService/SearchGoogleAdsFields", + request_serializer=google_ads_field_service.SearchGoogleAdsFieldsRequest.serialize, + response_deserializer=google_ads_field_service.SearchGoogleAdsFieldsResponse.deserialize, + ) + ) + return self._stubs["search_google_ads_fields"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.get_google_ads_field: self._wrap_method( + self.get_google_ads_field, + default_timeout=None, + client_info=client_info, + ), + self.search_google_ads_fields: self._wrap_method( + self.search_google_ads_fields, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("GoogleAdsFieldServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/google_ads_service/__init__.py b/google/ads/googleads/v23/services/services/google_ads_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/google_ads_service/__init__.py rename to google/ads/googleads/v23/services/services/google_ads_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/google_ads_service/async_client.py b/google/ads/googleads/v23/services/services/google_ads_service/async_client.py new file mode 100644 index 000000000..ce9102f85 --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_service/async_client.py @@ -0,0 +1,1721 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import ( + Callable, + MutableSequence, + Optional, + AsyncIterable, + Awaitable, + Sequence, + Tuple, + Union, +) + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.services.google_ads_service import pagers +from google.ads.googleads.v23.services.types import google_ads_service +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import GoogleAdsServiceTransport, DEFAULT_CLIENT_INFO +from .client import GoogleAdsServiceClient + +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 GoogleAdsServiceAsyncClient: + """Service to fetch data and metrics across resources.""" + + _client: GoogleAdsServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = GoogleAdsServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = GoogleAdsServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + GoogleAdsServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = GoogleAdsServiceClient._DEFAULT_UNIVERSE + + accessible_bidding_strategy_path = staticmethod( + GoogleAdsServiceClient.accessible_bidding_strategy_path + ) + parse_accessible_bidding_strategy_path = staticmethod( + GoogleAdsServiceClient.parse_accessible_bidding_strategy_path + ) + account_budget_path = staticmethod( + GoogleAdsServiceClient.account_budget_path + ) + parse_account_budget_path = staticmethod( + GoogleAdsServiceClient.parse_account_budget_path + ) + account_budget_proposal_path = staticmethod( + GoogleAdsServiceClient.account_budget_proposal_path + ) + parse_account_budget_proposal_path = staticmethod( + GoogleAdsServiceClient.parse_account_budget_proposal_path + ) + account_link_path = staticmethod(GoogleAdsServiceClient.account_link_path) + parse_account_link_path = staticmethod( + GoogleAdsServiceClient.parse_account_link_path + ) + ad_path = staticmethod(GoogleAdsServiceClient.ad_path) + parse_ad_path = staticmethod(GoogleAdsServiceClient.parse_ad_path) + ad_group_path = staticmethod(GoogleAdsServiceClient.ad_group_path) + parse_ad_group_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_path + ) + ad_group_ad_path = staticmethod(GoogleAdsServiceClient.ad_group_ad_path) + parse_ad_group_ad_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_ad_path + ) + ad_group_ad_asset_combination_view_path = staticmethod( + GoogleAdsServiceClient.ad_group_ad_asset_combination_view_path + ) + parse_ad_group_ad_asset_combination_view_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_ad_asset_combination_view_path + ) + ad_group_ad_asset_view_path = staticmethod( + GoogleAdsServiceClient.ad_group_ad_asset_view_path + ) + parse_ad_group_ad_asset_view_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_ad_asset_view_path + ) + ad_group_ad_label_path = staticmethod( + GoogleAdsServiceClient.ad_group_ad_label_path + ) + parse_ad_group_ad_label_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_ad_label_path + ) + ad_group_asset_path = staticmethod( + GoogleAdsServiceClient.ad_group_asset_path + ) + parse_ad_group_asset_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_asset_path + ) + ad_group_asset_set_path = staticmethod( + GoogleAdsServiceClient.ad_group_asset_set_path + ) + parse_ad_group_asset_set_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_asset_set_path + ) + ad_group_audience_view_path = staticmethod( + GoogleAdsServiceClient.ad_group_audience_view_path + ) + parse_ad_group_audience_view_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_audience_view_path + ) + ad_group_bid_modifier_path = staticmethod( + GoogleAdsServiceClient.ad_group_bid_modifier_path + ) + parse_ad_group_bid_modifier_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_bid_modifier_path + ) + ad_group_criterion_path = staticmethod( + GoogleAdsServiceClient.ad_group_criterion_path + ) + parse_ad_group_criterion_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_criterion_path + ) + ad_group_criterion_customizer_path = staticmethod( + GoogleAdsServiceClient.ad_group_criterion_customizer_path + ) + parse_ad_group_criterion_customizer_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_criterion_customizer_path + ) + ad_group_criterion_label_path = staticmethod( + GoogleAdsServiceClient.ad_group_criterion_label_path + ) + parse_ad_group_criterion_label_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_criterion_label_path + ) + ad_group_criterion_simulation_path = staticmethod( + GoogleAdsServiceClient.ad_group_criterion_simulation_path + ) + parse_ad_group_criterion_simulation_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_criterion_simulation_path + ) + ad_group_customizer_path = staticmethod( + GoogleAdsServiceClient.ad_group_customizer_path + ) + parse_ad_group_customizer_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_customizer_path + ) + ad_group_label_path = staticmethod( + GoogleAdsServiceClient.ad_group_label_path + ) + parse_ad_group_label_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_label_path + ) + ad_group_simulation_path = staticmethod( + GoogleAdsServiceClient.ad_group_simulation_path + ) + parse_ad_group_simulation_path = staticmethod( + GoogleAdsServiceClient.parse_ad_group_simulation_path + ) + ad_parameter_path = staticmethod(GoogleAdsServiceClient.ad_parameter_path) + parse_ad_parameter_path = staticmethod( + GoogleAdsServiceClient.parse_ad_parameter_path + ) + ad_schedule_view_path = staticmethod( + GoogleAdsServiceClient.ad_schedule_view_path + ) + parse_ad_schedule_view_path = staticmethod( + GoogleAdsServiceClient.parse_ad_schedule_view_path + ) + age_range_view_path = staticmethod( + GoogleAdsServiceClient.age_range_view_path + ) + parse_age_range_view_path = staticmethod( + GoogleAdsServiceClient.parse_age_range_view_path + ) + ai_max_search_term_ad_combination_view_path = staticmethod( + GoogleAdsServiceClient.ai_max_search_term_ad_combination_view_path + ) + parse_ai_max_search_term_ad_combination_view_path = staticmethod( + GoogleAdsServiceClient.parse_ai_max_search_term_ad_combination_view_path + ) + android_privacy_shared_key_google_ad_group_path = staticmethod( + GoogleAdsServiceClient.android_privacy_shared_key_google_ad_group_path + ) + parse_android_privacy_shared_key_google_ad_group_path = staticmethod( + GoogleAdsServiceClient.parse_android_privacy_shared_key_google_ad_group_path + ) + android_privacy_shared_key_google_campaign_path = staticmethod( + GoogleAdsServiceClient.android_privacy_shared_key_google_campaign_path + ) + parse_android_privacy_shared_key_google_campaign_path = staticmethod( + GoogleAdsServiceClient.parse_android_privacy_shared_key_google_campaign_path + ) + android_privacy_shared_key_google_network_type_path = staticmethod( + GoogleAdsServiceClient.android_privacy_shared_key_google_network_type_path + ) + parse_android_privacy_shared_key_google_network_type_path = staticmethod( + GoogleAdsServiceClient.parse_android_privacy_shared_key_google_network_type_path + ) + applied_incentive_path = staticmethod( + GoogleAdsServiceClient.applied_incentive_path + ) + parse_applied_incentive_path = staticmethod( + GoogleAdsServiceClient.parse_applied_incentive_path + ) + asset_path = staticmethod(GoogleAdsServiceClient.asset_path) + parse_asset_path = staticmethod(GoogleAdsServiceClient.parse_asset_path) + asset_field_type_view_path = staticmethod( + GoogleAdsServiceClient.asset_field_type_view_path + ) + parse_asset_field_type_view_path = staticmethod( + GoogleAdsServiceClient.parse_asset_field_type_view_path + ) + asset_group_path = staticmethod(GoogleAdsServiceClient.asset_group_path) + parse_asset_group_path = staticmethod( + GoogleAdsServiceClient.parse_asset_group_path + ) + asset_group_asset_path = staticmethod( + GoogleAdsServiceClient.asset_group_asset_path + ) + parse_asset_group_asset_path = staticmethod( + GoogleAdsServiceClient.parse_asset_group_asset_path + ) + asset_group_listing_group_filter_path = staticmethod( + GoogleAdsServiceClient.asset_group_listing_group_filter_path + ) + parse_asset_group_listing_group_filter_path = staticmethod( + GoogleAdsServiceClient.parse_asset_group_listing_group_filter_path + ) + asset_group_product_group_view_path = staticmethod( + GoogleAdsServiceClient.asset_group_product_group_view_path + ) + parse_asset_group_product_group_view_path = staticmethod( + GoogleAdsServiceClient.parse_asset_group_product_group_view_path + ) + asset_group_signal_path = staticmethod( + GoogleAdsServiceClient.asset_group_signal_path + ) + parse_asset_group_signal_path = staticmethod( + GoogleAdsServiceClient.parse_asset_group_signal_path + ) + asset_group_top_combination_view_path = staticmethod( + GoogleAdsServiceClient.asset_group_top_combination_view_path + ) + parse_asset_group_top_combination_view_path = staticmethod( + GoogleAdsServiceClient.parse_asset_group_top_combination_view_path + ) + asset_set_path = staticmethod(GoogleAdsServiceClient.asset_set_path) + parse_asset_set_path = staticmethod( + GoogleAdsServiceClient.parse_asset_set_path + ) + asset_set_asset_path = staticmethod( + GoogleAdsServiceClient.asset_set_asset_path + ) + parse_asset_set_asset_path = staticmethod( + GoogleAdsServiceClient.parse_asset_set_asset_path + ) + asset_set_type_view_path = staticmethod( + GoogleAdsServiceClient.asset_set_type_view_path + ) + parse_asset_set_type_view_path = staticmethod( + GoogleAdsServiceClient.parse_asset_set_type_view_path + ) + audience_path = staticmethod(GoogleAdsServiceClient.audience_path) + parse_audience_path = staticmethod( + GoogleAdsServiceClient.parse_audience_path + ) + batch_job_path = staticmethod(GoogleAdsServiceClient.batch_job_path) + parse_batch_job_path = staticmethod( + GoogleAdsServiceClient.parse_batch_job_path + ) + bidding_data_exclusion_path = staticmethod( + GoogleAdsServiceClient.bidding_data_exclusion_path + ) + parse_bidding_data_exclusion_path = staticmethod( + GoogleAdsServiceClient.parse_bidding_data_exclusion_path + ) + bidding_seasonality_adjustment_path = staticmethod( + GoogleAdsServiceClient.bidding_seasonality_adjustment_path + ) + parse_bidding_seasonality_adjustment_path = staticmethod( + GoogleAdsServiceClient.parse_bidding_seasonality_adjustment_path + ) + bidding_strategy_path = staticmethod( + GoogleAdsServiceClient.bidding_strategy_path + ) + parse_bidding_strategy_path = staticmethod( + GoogleAdsServiceClient.parse_bidding_strategy_path + ) + bidding_strategy_simulation_path = staticmethod( + GoogleAdsServiceClient.bidding_strategy_simulation_path + ) + parse_bidding_strategy_simulation_path = staticmethod( + GoogleAdsServiceClient.parse_bidding_strategy_simulation_path + ) + billing_setup_path = staticmethod(GoogleAdsServiceClient.billing_setup_path) + parse_billing_setup_path = staticmethod( + GoogleAdsServiceClient.parse_billing_setup_path + ) + call_view_path = staticmethod(GoogleAdsServiceClient.call_view_path) + parse_call_view_path = staticmethod( + GoogleAdsServiceClient.parse_call_view_path + ) + campaign_path = staticmethod(GoogleAdsServiceClient.campaign_path) + parse_campaign_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_path + ) + campaign_aggregate_asset_view_path = staticmethod( + GoogleAdsServiceClient.campaign_aggregate_asset_view_path + ) + parse_campaign_aggregate_asset_view_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_aggregate_asset_view_path + ) + campaign_asset_path = staticmethod( + GoogleAdsServiceClient.campaign_asset_path + ) + parse_campaign_asset_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_asset_path + ) + campaign_asset_set_path = staticmethod( + GoogleAdsServiceClient.campaign_asset_set_path + ) + parse_campaign_asset_set_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_asset_set_path + ) + campaign_audience_view_path = staticmethod( + GoogleAdsServiceClient.campaign_audience_view_path + ) + parse_campaign_audience_view_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_audience_view_path + ) + campaign_bid_modifier_path = staticmethod( + GoogleAdsServiceClient.campaign_bid_modifier_path + ) + parse_campaign_bid_modifier_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_bid_modifier_path + ) + campaign_budget_path = staticmethod( + GoogleAdsServiceClient.campaign_budget_path + ) + parse_campaign_budget_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_budget_path + ) + campaign_conversion_goal_path = staticmethod( + GoogleAdsServiceClient.campaign_conversion_goal_path + ) + parse_campaign_conversion_goal_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_conversion_goal_path + ) + campaign_criterion_path = staticmethod( + GoogleAdsServiceClient.campaign_criterion_path + ) + parse_campaign_criterion_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_criterion_path + ) + campaign_customizer_path = staticmethod( + GoogleAdsServiceClient.campaign_customizer_path + ) + parse_campaign_customizer_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_customizer_path + ) + campaign_draft_path = staticmethod( + GoogleAdsServiceClient.campaign_draft_path + ) + parse_campaign_draft_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_draft_path + ) + campaign_goal_config_path = staticmethod( + GoogleAdsServiceClient.campaign_goal_config_path + ) + parse_campaign_goal_config_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_goal_config_path + ) + campaign_group_path = staticmethod( + GoogleAdsServiceClient.campaign_group_path + ) + parse_campaign_group_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_group_path + ) + campaign_label_path = staticmethod( + GoogleAdsServiceClient.campaign_label_path + ) + parse_campaign_label_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_label_path + ) + campaign_lifecycle_goal_path = staticmethod( + GoogleAdsServiceClient.campaign_lifecycle_goal_path + ) + parse_campaign_lifecycle_goal_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_lifecycle_goal_path + ) + campaign_search_term_insight_path = staticmethod( + GoogleAdsServiceClient.campaign_search_term_insight_path + ) + parse_campaign_search_term_insight_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_search_term_insight_path + ) + campaign_search_term_view_path = staticmethod( + GoogleAdsServiceClient.campaign_search_term_view_path + ) + parse_campaign_search_term_view_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_search_term_view_path + ) + campaign_shared_set_path = staticmethod( + GoogleAdsServiceClient.campaign_shared_set_path + ) + parse_campaign_shared_set_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_shared_set_path + ) + campaign_simulation_path = staticmethod( + GoogleAdsServiceClient.campaign_simulation_path + ) + parse_campaign_simulation_path = staticmethod( + GoogleAdsServiceClient.parse_campaign_simulation_path + ) + carrier_constant_path = staticmethod( + GoogleAdsServiceClient.carrier_constant_path + ) + parse_carrier_constant_path = staticmethod( + GoogleAdsServiceClient.parse_carrier_constant_path + ) + change_event_path = staticmethod(GoogleAdsServiceClient.change_event_path) + parse_change_event_path = staticmethod( + GoogleAdsServiceClient.parse_change_event_path + ) + change_status_path = staticmethod(GoogleAdsServiceClient.change_status_path) + parse_change_status_path = staticmethod( + GoogleAdsServiceClient.parse_change_status_path + ) + channel_aggregate_asset_view_path = staticmethod( + GoogleAdsServiceClient.channel_aggregate_asset_view_path + ) + parse_channel_aggregate_asset_view_path = staticmethod( + GoogleAdsServiceClient.parse_channel_aggregate_asset_view_path + ) + click_view_path = staticmethod(GoogleAdsServiceClient.click_view_path) + parse_click_view_path = staticmethod( + GoogleAdsServiceClient.parse_click_view_path + ) + combined_audience_path = staticmethod( + GoogleAdsServiceClient.combined_audience_path + ) + parse_combined_audience_path = staticmethod( + GoogleAdsServiceClient.parse_combined_audience_path + ) + content_criterion_view_path = staticmethod( + GoogleAdsServiceClient.content_criterion_view_path + ) + parse_content_criterion_view_path = staticmethod( + GoogleAdsServiceClient.parse_content_criterion_view_path + ) + conversion_action_path = staticmethod( + GoogleAdsServiceClient.conversion_action_path + ) + parse_conversion_action_path = staticmethod( + GoogleAdsServiceClient.parse_conversion_action_path + ) + conversion_custom_variable_path = staticmethod( + GoogleAdsServiceClient.conversion_custom_variable_path + ) + parse_conversion_custom_variable_path = staticmethod( + GoogleAdsServiceClient.parse_conversion_custom_variable_path + ) + conversion_goal_campaign_config_path = staticmethod( + GoogleAdsServiceClient.conversion_goal_campaign_config_path + ) + parse_conversion_goal_campaign_config_path = staticmethod( + GoogleAdsServiceClient.parse_conversion_goal_campaign_config_path + ) + conversion_value_rule_path = staticmethod( + GoogleAdsServiceClient.conversion_value_rule_path + ) + parse_conversion_value_rule_path = staticmethod( + GoogleAdsServiceClient.parse_conversion_value_rule_path + ) + conversion_value_rule_set_path = staticmethod( + GoogleAdsServiceClient.conversion_value_rule_set_path + ) + parse_conversion_value_rule_set_path = staticmethod( + GoogleAdsServiceClient.parse_conversion_value_rule_set_path + ) + currency_constant_path = staticmethod( + GoogleAdsServiceClient.currency_constant_path + ) + parse_currency_constant_path = staticmethod( + GoogleAdsServiceClient.parse_currency_constant_path + ) + custom_audience_path = staticmethod( + GoogleAdsServiceClient.custom_audience_path + ) + parse_custom_audience_path = staticmethod( + GoogleAdsServiceClient.parse_custom_audience_path + ) + custom_conversion_goal_path = staticmethod( + GoogleAdsServiceClient.custom_conversion_goal_path + ) + parse_custom_conversion_goal_path = staticmethod( + GoogleAdsServiceClient.parse_custom_conversion_goal_path + ) + customer_path = staticmethod(GoogleAdsServiceClient.customer_path) + parse_customer_path = staticmethod( + GoogleAdsServiceClient.parse_customer_path + ) + customer_asset_path = staticmethod( + GoogleAdsServiceClient.customer_asset_path + ) + parse_customer_asset_path = staticmethod( + GoogleAdsServiceClient.parse_customer_asset_path + ) + customer_asset_set_path = staticmethod( + GoogleAdsServiceClient.customer_asset_set_path + ) + parse_customer_asset_set_path = staticmethod( + GoogleAdsServiceClient.parse_customer_asset_set_path + ) + customer_client_path = staticmethod( + GoogleAdsServiceClient.customer_client_path + ) + parse_customer_client_path = staticmethod( + GoogleAdsServiceClient.parse_customer_client_path + ) + customer_client_link_path = staticmethod( + GoogleAdsServiceClient.customer_client_link_path + ) + parse_customer_client_link_path = staticmethod( + GoogleAdsServiceClient.parse_customer_client_link_path + ) + customer_conversion_goal_path = staticmethod( + GoogleAdsServiceClient.customer_conversion_goal_path + ) + parse_customer_conversion_goal_path = staticmethod( + GoogleAdsServiceClient.parse_customer_conversion_goal_path + ) + customer_customizer_path = staticmethod( + GoogleAdsServiceClient.customer_customizer_path + ) + parse_customer_customizer_path = staticmethod( + GoogleAdsServiceClient.parse_customer_customizer_path + ) + customer_label_path = staticmethod( + GoogleAdsServiceClient.customer_label_path + ) + parse_customer_label_path = staticmethod( + GoogleAdsServiceClient.parse_customer_label_path + ) + customer_lifecycle_goal_path = staticmethod( + GoogleAdsServiceClient.customer_lifecycle_goal_path + ) + parse_customer_lifecycle_goal_path = staticmethod( + GoogleAdsServiceClient.parse_customer_lifecycle_goal_path + ) + customer_manager_link_path = staticmethod( + GoogleAdsServiceClient.customer_manager_link_path + ) + parse_customer_manager_link_path = staticmethod( + GoogleAdsServiceClient.parse_customer_manager_link_path + ) + customer_negative_criterion_path = staticmethod( + GoogleAdsServiceClient.customer_negative_criterion_path + ) + parse_customer_negative_criterion_path = staticmethod( + GoogleAdsServiceClient.parse_customer_negative_criterion_path + ) + customer_search_term_insight_path = staticmethod( + GoogleAdsServiceClient.customer_search_term_insight_path + ) + parse_customer_search_term_insight_path = staticmethod( + GoogleAdsServiceClient.parse_customer_search_term_insight_path + ) + customer_user_access_path = staticmethod( + GoogleAdsServiceClient.customer_user_access_path + ) + parse_customer_user_access_path = staticmethod( + GoogleAdsServiceClient.parse_customer_user_access_path + ) + customer_user_access_invitation_path = staticmethod( + GoogleAdsServiceClient.customer_user_access_invitation_path + ) + parse_customer_user_access_invitation_path = staticmethod( + GoogleAdsServiceClient.parse_customer_user_access_invitation_path + ) + custom_interest_path = staticmethod( + GoogleAdsServiceClient.custom_interest_path + ) + parse_custom_interest_path = staticmethod( + GoogleAdsServiceClient.parse_custom_interest_path + ) + customizer_attribute_path = staticmethod( + GoogleAdsServiceClient.customizer_attribute_path + ) + parse_customizer_attribute_path = staticmethod( + GoogleAdsServiceClient.parse_customizer_attribute_path + ) + data_link_path = staticmethod(GoogleAdsServiceClient.data_link_path) + parse_data_link_path = staticmethod( + GoogleAdsServiceClient.parse_data_link_path + ) + detail_content_suitability_placement_view_path = staticmethod( + GoogleAdsServiceClient.detail_content_suitability_placement_view_path + ) + parse_detail_content_suitability_placement_view_path = staticmethod( + GoogleAdsServiceClient.parse_detail_content_suitability_placement_view_path + ) + detailed_demographic_path = staticmethod( + GoogleAdsServiceClient.detailed_demographic_path + ) + parse_detailed_demographic_path = staticmethod( + GoogleAdsServiceClient.parse_detailed_demographic_path + ) + detail_placement_view_path = staticmethod( + GoogleAdsServiceClient.detail_placement_view_path + ) + parse_detail_placement_view_path = staticmethod( + GoogleAdsServiceClient.parse_detail_placement_view_path + ) + display_keyword_view_path = staticmethod( + GoogleAdsServiceClient.display_keyword_view_path + ) + parse_display_keyword_view_path = staticmethod( + GoogleAdsServiceClient.parse_display_keyword_view_path + ) + distance_view_path = staticmethod(GoogleAdsServiceClient.distance_view_path) + parse_distance_view_path = staticmethod( + GoogleAdsServiceClient.parse_distance_view_path + ) + domain_category_path = staticmethod( + GoogleAdsServiceClient.domain_category_path + ) + parse_domain_category_path = staticmethod( + GoogleAdsServiceClient.parse_domain_category_path + ) + dynamic_search_ads_search_term_view_path = staticmethod( + GoogleAdsServiceClient.dynamic_search_ads_search_term_view_path + ) + parse_dynamic_search_ads_search_term_view_path = staticmethod( + GoogleAdsServiceClient.parse_dynamic_search_ads_search_term_view_path + ) + expanded_landing_page_view_path = staticmethod( + GoogleAdsServiceClient.expanded_landing_page_view_path + ) + parse_expanded_landing_page_view_path = staticmethod( + GoogleAdsServiceClient.parse_expanded_landing_page_view_path + ) + experiment_path = staticmethod(GoogleAdsServiceClient.experiment_path) + parse_experiment_path = staticmethod( + GoogleAdsServiceClient.parse_experiment_path + ) + experiment_arm_path = staticmethod( + GoogleAdsServiceClient.experiment_arm_path + ) + parse_experiment_arm_path = staticmethod( + GoogleAdsServiceClient.parse_experiment_arm_path + ) + final_url_expansion_asset_view_path = staticmethod( + GoogleAdsServiceClient.final_url_expansion_asset_view_path + ) + parse_final_url_expansion_asset_view_path = staticmethod( + GoogleAdsServiceClient.parse_final_url_expansion_asset_view_path + ) + gender_view_path = staticmethod(GoogleAdsServiceClient.gender_view_path) + parse_gender_view_path = staticmethod( + GoogleAdsServiceClient.parse_gender_view_path + ) + geographic_view_path = staticmethod( + GoogleAdsServiceClient.geographic_view_path + ) + parse_geographic_view_path = staticmethod( + GoogleAdsServiceClient.parse_geographic_view_path + ) + geo_target_constant_path = staticmethod( + GoogleAdsServiceClient.geo_target_constant_path + ) + parse_geo_target_constant_path = staticmethod( + GoogleAdsServiceClient.parse_geo_target_constant_path + ) + goal_path = staticmethod(GoogleAdsServiceClient.goal_path) + parse_goal_path = staticmethod(GoogleAdsServiceClient.parse_goal_path) + group_content_suitability_placement_view_path = staticmethod( + GoogleAdsServiceClient.group_content_suitability_placement_view_path + ) + parse_group_content_suitability_placement_view_path = staticmethod( + GoogleAdsServiceClient.parse_group_content_suitability_placement_view_path + ) + group_placement_view_path = staticmethod( + GoogleAdsServiceClient.group_placement_view_path + ) + parse_group_placement_view_path = staticmethod( + GoogleAdsServiceClient.parse_group_placement_view_path + ) + hotel_group_view_path = staticmethod( + GoogleAdsServiceClient.hotel_group_view_path + ) + parse_hotel_group_view_path = staticmethod( + GoogleAdsServiceClient.parse_hotel_group_view_path + ) + hotel_performance_view_path = staticmethod( + GoogleAdsServiceClient.hotel_performance_view_path + ) + parse_hotel_performance_view_path = staticmethod( + GoogleAdsServiceClient.parse_hotel_performance_view_path + ) + hotel_reconciliation_path = staticmethod( + GoogleAdsServiceClient.hotel_reconciliation_path + ) + parse_hotel_reconciliation_path = staticmethod( + GoogleAdsServiceClient.parse_hotel_reconciliation_path + ) + income_range_view_path = staticmethod( + GoogleAdsServiceClient.income_range_view_path + ) + parse_income_range_view_path = staticmethod( + GoogleAdsServiceClient.parse_income_range_view_path + ) + keyword_plan_path = staticmethod(GoogleAdsServiceClient.keyword_plan_path) + parse_keyword_plan_path = staticmethod( + GoogleAdsServiceClient.parse_keyword_plan_path + ) + keyword_plan_ad_group_path = staticmethod( + GoogleAdsServiceClient.keyword_plan_ad_group_path + ) + parse_keyword_plan_ad_group_path = staticmethod( + GoogleAdsServiceClient.parse_keyword_plan_ad_group_path + ) + keyword_plan_ad_group_keyword_path = staticmethod( + GoogleAdsServiceClient.keyword_plan_ad_group_keyword_path + ) + parse_keyword_plan_ad_group_keyword_path = staticmethod( + GoogleAdsServiceClient.parse_keyword_plan_ad_group_keyword_path + ) + keyword_plan_campaign_path = staticmethod( + GoogleAdsServiceClient.keyword_plan_campaign_path + ) + parse_keyword_plan_campaign_path = staticmethod( + GoogleAdsServiceClient.parse_keyword_plan_campaign_path + ) + keyword_plan_campaign_keyword_path = staticmethod( + GoogleAdsServiceClient.keyword_plan_campaign_keyword_path + ) + parse_keyword_plan_campaign_keyword_path = staticmethod( + GoogleAdsServiceClient.parse_keyword_plan_campaign_keyword_path + ) + keyword_theme_constant_path = staticmethod( + GoogleAdsServiceClient.keyword_theme_constant_path + ) + parse_keyword_theme_constant_path = staticmethod( + GoogleAdsServiceClient.parse_keyword_theme_constant_path + ) + keyword_view_path = staticmethod(GoogleAdsServiceClient.keyword_view_path) + parse_keyword_view_path = staticmethod( + GoogleAdsServiceClient.parse_keyword_view_path + ) + label_path = staticmethod(GoogleAdsServiceClient.label_path) + parse_label_path = staticmethod(GoogleAdsServiceClient.parse_label_path) + landing_page_view_path = staticmethod( + GoogleAdsServiceClient.landing_page_view_path + ) + parse_landing_page_view_path = staticmethod( + GoogleAdsServiceClient.parse_landing_page_view_path + ) + language_constant_path = staticmethod( + GoogleAdsServiceClient.language_constant_path + ) + parse_language_constant_path = staticmethod( + GoogleAdsServiceClient.parse_language_constant_path + ) + lead_form_submission_data_path = staticmethod( + GoogleAdsServiceClient.lead_form_submission_data_path + ) + parse_lead_form_submission_data_path = staticmethod( + GoogleAdsServiceClient.parse_lead_form_submission_data_path + ) + life_event_path = staticmethod(GoogleAdsServiceClient.life_event_path) + parse_life_event_path = staticmethod( + GoogleAdsServiceClient.parse_life_event_path + ) + local_services_employee_path = staticmethod( + GoogleAdsServiceClient.local_services_employee_path + ) + parse_local_services_employee_path = staticmethod( + GoogleAdsServiceClient.parse_local_services_employee_path + ) + local_services_lead_path = staticmethod( + GoogleAdsServiceClient.local_services_lead_path + ) + parse_local_services_lead_path = staticmethod( + GoogleAdsServiceClient.parse_local_services_lead_path + ) + local_services_lead_conversation_path = staticmethod( + GoogleAdsServiceClient.local_services_lead_conversation_path + ) + parse_local_services_lead_conversation_path = staticmethod( + GoogleAdsServiceClient.parse_local_services_lead_conversation_path + ) + local_services_verification_artifact_path = staticmethod( + GoogleAdsServiceClient.local_services_verification_artifact_path + ) + parse_local_services_verification_artifact_path = staticmethod( + GoogleAdsServiceClient.parse_local_services_verification_artifact_path + ) + location_interest_view_path = staticmethod( + GoogleAdsServiceClient.location_interest_view_path + ) + parse_location_interest_view_path = staticmethod( + GoogleAdsServiceClient.parse_location_interest_view_path + ) + location_view_path = staticmethod(GoogleAdsServiceClient.location_view_path) + parse_location_view_path = staticmethod( + GoogleAdsServiceClient.parse_location_view_path + ) + managed_placement_view_path = staticmethod( + GoogleAdsServiceClient.managed_placement_view_path + ) + parse_managed_placement_view_path = staticmethod( + GoogleAdsServiceClient.parse_managed_placement_view_path + ) + matched_location_interest_view_path = staticmethod( + GoogleAdsServiceClient.matched_location_interest_view_path + ) + parse_matched_location_interest_view_path = staticmethod( + GoogleAdsServiceClient.parse_matched_location_interest_view_path + ) + media_file_path = staticmethod(GoogleAdsServiceClient.media_file_path) + parse_media_file_path = staticmethod( + GoogleAdsServiceClient.parse_media_file_path + ) + mobile_app_category_constant_path = staticmethod( + GoogleAdsServiceClient.mobile_app_category_constant_path + ) + parse_mobile_app_category_constant_path = staticmethod( + GoogleAdsServiceClient.parse_mobile_app_category_constant_path + ) + mobile_device_constant_path = staticmethod( + GoogleAdsServiceClient.mobile_device_constant_path + ) + parse_mobile_device_constant_path = staticmethod( + GoogleAdsServiceClient.parse_mobile_device_constant_path + ) + offline_conversion_upload_client_summary_path = staticmethod( + GoogleAdsServiceClient.offline_conversion_upload_client_summary_path + ) + parse_offline_conversion_upload_client_summary_path = staticmethod( + GoogleAdsServiceClient.parse_offline_conversion_upload_client_summary_path + ) + offline_conversion_upload_conversion_action_summary_path = staticmethod( + GoogleAdsServiceClient.offline_conversion_upload_conversion_action_summary_path + ) + parse_offline_conversion_upload_conversion_action_summary_path = staticmethod( + GoogleAdsServiceClient.parse_offline_conversion_upload_conversion_action_summary_path + ) + offline_user_data_job_path = staticmethod( + GoogleAdsServiceClient.offline_user_data_job_path + ) + parse_offline_user_data_job_path = staticmethod( + GoogleAdsServiceClient.parse_offline_user_data_job_path + ) + operating_system_version_constant_path = staticmethod( + GoogleAdsServiceClient.operating_system_version_constant_path + ) + parse_operating_system_version_constant_path = staticmethod( + GoogleAdsServiceClient.parse_operating_system_version_constant_path + ) + paid_organic_search_term_view_path = staticmethod( + GoogleAdsServiceClient.paid_organic_search_term_view_path + ) + parse_paid_organic_search_term_view_path = staticmethod( + GoogleAdsServiceClient.parse_paid_organic_search_term_view_path + ) + parental_status_view_path = staticmethod( + GoogleAdsServiceClient.parental_status_view_path + ) + parse_parental_status_view_path = staticmethod( + GoogleAdsServiceClient.parse_parental_status_view_path + ) + payments_account_path = staticmethod( + GoogleAdsServiceClient.payments_account_path + ) + parse_payments_account_path = staticmethod( + GoogleAdsServiceClient.parse_payments_account_path + ) + performance_max_placement_view_path = staticmethod( + GoogleAdsServiceClient.performance_max_placement_view_path + ) + parse_performance_max_placement_view_path = staticmethod( + GoogleAdsServiceClient.parse_performance_max_placement_view_path + ) + per_store_view_path = staticmethod( + GoogleAdsServiceClient.per_store_view_path + ) + parse_per_store_view_path = staticmethod( + GoogleAdsServiceClient.parse_per_store_view_path + ) + product_category_constant_path = staticmethod( + GoogleAdsServiceClient.product_category_constant_path + ) + parse_product_category_constant_path = staticmethod( + GoogleAdsServiceClient.parse_product_category_constant_path + ) + product_group_view_path = staticmethod( + GoogleAdsServiceClient.product_group_view_path + ) + parse_product_group_view_path = staticmethod( + GoogleAdsServiceClient.parse_product_group_view_path + ) + product_link_path = staticmethod(GoogleAdsServiceClient.product_link_path) + parse_product_link_path = staticmethod( + GoogleAdsServiceClient.parse_product_link_path + ) + product_link_invitation_path = staticmethod( + GoogleAdsServiceClient.product_link_invitation_path + ) + parse_product_link_invitation_path = staticmethod( + GoogleAdsServiceClient.parse_product_link_invitation_path + ) + qualifying_question_path = staticmethod( + GoogleAdsServiceClient.qualifying_question_path + ) + parse_qualifying_question_path = staticmethod( + GoogleAdsServiceClient.parse_qualifying_question_path + ) + recommendation_path = staticmethod( + GoogleAdsServiceClient.recommendation_path + ) + parse_recommendation_path = staticmethod( + GoogleAdsServiceClient.parse_recommendation_path + ) + recommendation_subscription_path = staticmethod( + GoogleAdsServiceClient.recommendation_subscription_path + ) + parse_recommendation_subscription_path = staticmethod( + GoogleAdsServiceClient.parse_recommendation_subscription_path + ) + remarketing_action_path = staticmethod( + GoogleAdsServiceClient.remarketing_action_path + ) + parse_remarketing_action_path = staticmethod( + GoogleAdsServiceClient.parse_remarketing_action_path + ) + search_term_view_path = staticmethod( + GoogleAdsServiceClient.search_term_view_path + ) + parse_search_term_view_path = staticmethod( + GoogleAdsServiceClient.parse_search_term_view_path + ) + shared_criterion_path = staticmethod( + GoogleAdsServiceClient.shared_criterion_path + ) + parse_shared_criterion_path = staticmethod( + GoogleAdsServiceClient.parse_shared_criterion_path + ) + shared_set_path = staticmethod(GoogleAdsServiceClient.shared_set_path) + parse_shared_set_path = staticmethod( + GoogleAdsServiceClient.parse_shared_set_path + ) + shopping_performance_view_path = staticmethod( + GoogleAdsServiceClient.shopping_performance_view_path + ) + parse_shopping_performance_view_path = staticmethod( + GoogleAdsServiceClient.parse_shopping_performance_view_path + ) + shopping_product_path = staticmethod( + GoogleAdsServiceClient.shopping_product_path + ) + parse_shopping_product_path = staticmethod( + GoogleAdsServiceClient.parse_shopping_product_path + ) + smart_campaign_search_term_view_path = staticmethod( + GoogleAdsServiceClient.smart_campaign_search_term_view_path + ) + parse_smart_campaign_search_term_view_path = staticmethod( + GoogleAdsServiceClient.parse_smart_campaign_search_term_view_path + ) + smart_campaign_setting_path = staticmethod( + GoogleAdsServiceClient.smart_campaign_setting_path + ) + parse_smart_campaign_setting_path = staticmethod( + GoogleAdsServiceClient.parse_smart_campaign_setting_path + ) + targeting_expansion_view_path = staticmethod( + GoogleAdsServiceClient.targeting_expansion_view_path + ) + parse_targeting_expansion_view_path = staticmethod( + GoogleAdsServiceClient.parse_targeting_expansion_view_path + ) + third_party_app_analytics_link_path = staticmethod( + GoogleAdsServiceClient.third_party_app_analytics_link_path + ) + parse_third_party_app_analytics_link_path = staticmethod( + GoogleAdsServiceClient.parse_third_party_app_analytics_link_path + ) + topic_constant_path = staticmethod( + GoogleAdsServiceClient.topic_constant_path + ) + parse_topic_constant_path = staticmethod( + GoogleAdsServiceClient.parse_topic_constant_path + ) + topic_view_path = staticmethod(GoogleAdsServiceClient.topic_view_path) + parse_topic_view_path = staticmethod( + GoogleAdsServiceClient.parse_topic_view_path + ) + travel_activity_group_view_path = staticmethod( + GoogleAdsServiceClient.travel_activity_group_view_path + ) + parse_travel_activity_group_view_path = staticmethod( + GoogleAdsServiceClient.parse_travel_activity_group_view_path + ) + travel_activity_performance_view_path = staticmethod( + GoogleAdsServiceClient.travel_activity_performance_view_path + ) + parse_travel_activity_performance_view_path = staticmethod( + GoogleAdsServiceClient.parse_travel_activity_performance_view_path + ) + user_interest_path = staticmethod(GoogleAdsServiceClient.user_interest_path) + parse_user_interest_path = staticmethod( + GoogleAdsServiceClient.parse_user_interest_path + ) + user_list_path = staticmethod(GoogleAdsServiceClient.user_list_path) + parse_user_list_path = staticmethod( + GoogleAdsServiceClient.parse_user_list_path + ) + user_list_customer_type_path = staticmethod( + GoogleAdsServiceClient.user_list_customer_type_path + ) + parse_user_list_customer_type_path = staticmethod( + GoogleAdsServiceClient.parse_user_list_customer_type_path + ) + user_location_view_path = staticmethod( + GoogleAdsServiceClient.user_location_view_path + ) + parse_user_location_view_path = staticmethod( + GoogleAdsServiceClient.parse_user_location_view_path + ) + video_path = staticmethod(GoogleAdsServiceClient.video_path) + parse_video_path = staticmethod(GoogleAdsServiceClient.parse_video_path) + webpage_view_path = staticmethod(GoogleAdsServiceClient.webpage_view_path) + parse_webpage_view_path = staticmethod( + GoogleAdsServiceClient.parse_webpage_view_path + ) + common_billing_account_path = staticmethod( + GoogleAdsServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + GoogleAdsServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(GoogleAdsServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + GoogleAdsServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + GoogleAdsServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + GoogleAdsServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + GoogleAdsServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + GoogleAdsServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + GoogleAdsServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + GoogleAdsServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsServiceAsyncClient: The constructed client. + """ + return GoogleAdsServiceClient.from_service_account_info.__func__(GoogleAdsServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsServiceAsyncClient: The constructed client. + """ + return GoogleAdsServiceClient.from_service_account_file.__func__(GoogleAdsServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return GoogleAdsServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> GoogleAdsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + GoogleAdsServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = GoogleAdsServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + GoogleAdsServiceTransport, + Callable[..., GoogleAdsServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the google ads service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,GoogleAdsServiceTransport,Callable[..., GoogleAdsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the GoogleAdsServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = GoogleAdsServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.GoogleAdsServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.GoogleAdsService", + "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.ads.googleads.v23.services.GoogleAdsService", + "credentialsType": None, + } + ), + ) + + async def search( + self, + request: Optional[ + Union[google_ads_service.SearchGoogleAdsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + query: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.SearchAsyncPager: + r"""Returns all rows that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.SearchGoogleAdsRequest, dict]]): + The request object. Request message for + [GoogleAdsService.Search][google.ads.googleads.v23.services.GoogleAdsService.Search]. + customer_id (:class:`str`): + Required. The ID of the customer + being queried. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + query (:class:`str`): + Required. The query string. + This corresponds to the ``query`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.google_ads_service.pagers.SearchAsyncPager: + Response message for + [GoogleAdsService.Search][google.ads.googleads.v23.services.GoogleAdsService.Search]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, query] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, google_ads_service.SearchGoogleAdsRequest): + request = google_ads_service.SearchGoogleAdsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if query is not None: + request.query = query + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.search + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.SearchAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def search_stream( + self, + request: Optional[ + Union[google_ads_service.SearchGoogleAdsStreamRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + query: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> Awaitable[ + AsyncIterable[google_ads_service.SearchGoogleAdsStreamResponse] + ]: + r"""Returns all rows that match the search stream query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.SearchGoogleAdsStreamRequest, dict]]): + The request object. Request message for + [GoogleAdsService.SearchStream][google.ads.googleads.v23.services.GoogleAdsService.SearchStream]. + customer_id (:class:`str`): + Required. The ID of the customer + being queried. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + query (:class:`str`): + Required. The query string. + This corresponds to the ``query`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SearchGoogleAdsStreamResponse]: + Response message for + [GoogleAdsService.SearchStream][google.ads.googleads.v23.services.GoogleAdsService.SearchStream]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, query] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, google_ads_service.SearchGoogleAdsStreamRequest + ): + request = google_ads_service.SearchGoogleAdsStreamRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if query is not None: + request.query = query + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.search_stream + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def mutate( + self, + request: Optional[ + Union[google_ads_service.MutateGoogleAdsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + mutate_operations: Optional[ + MutableSequence[google_ads_service.MutateOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> google_ads_service.MutateGoogleAdsResponse: + r"""Creates, updates, or removes resources. This method supports + atomic transactions with multiple types of resources. For + example, you can atomically create a campaign and a campaign + budget, or perform up to thousands of mutates atomically. + + This method is essentially a wrapper around a series of mutate + methods. The only features it offers over calling those methods + directly are: + + - Atomic transactions + - Temp resource names (described below) + - Somewhat reduced latency over making a series of mutate calls + + Note: Only resources that support atomic transactions are + included, so this method can't replace all calls to individual + services. + + Atomic Transaction Benefits + --------------------------- + + Atomicity makes error handling much easier. If you're making a + series of changes and one fails, it can leave your account in an + inconsistent state. With atomicity, you either reach the chosen + state directly, or the request fails and you can retry. + + Temp Resource Names + ------------------- + + Temp resource names are a special type of resource name used to + create a resource and reference that resource in the same + request. For example, if a campaign budget is created with + ``resource_name`` equal to ``customers/123/campaignBudgets/-1``, + that resource name can be reused in the ``Campaign.budget`` + field in the same request. That way, the two resources are + created and linked atomically. + + To create a temp resource name, put a negative number in the + part of the name that the server would normally allocate. + + Note: + + - Resources must be created with a temp name before the name can + be reused. For example, the previous CampaignBudget+Campaign + example would fail if the mutate order was reversed. + - Temp names are not remembered across requests. + - There's no limit to the number of temp names in a request. + - Each temp name must use a unique negative number, even if the + resource types differ. + + Latency + ------- + + It's important to group mutates by resource type or the request + may time out and fail. Latency is roughly equal to a series of + calls to individual mutate methods, where each change in + resource type is a new call. For example, mutating 10 campaigns + then 10 ad groups is like 2 calls, while mutating 1 campaign, 1 + ad group, 1 campaign, 1 ad group is like 4 calls. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdGroupCriterionError <>`__ + `AdGroupError <>`__ `AssetError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `CampaignBudgetError <>`__ `CampaignCriterionError <>`__ + `CampaignError <>`__ `CampaignExperimentError <>`__ + `CampaignSharedSetError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `ConversionActionError <>`__ + `CriterionError <>`__ `CustomerFeedError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `DistinctError <>`__ `ExtensionFeedItemError <>`__ + `ExtensionSettingError <>`__ `FeedAttributeReferenceError <>`__ + `FeedError <>`__ `FeedItemError <>`__ `FeedItemSetError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `ImageError <>`__ + `InternalError <>`__ `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `LabelError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SharedSetError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `UserListError <>`__ + `YoutubeVideoRegistrationError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateGoogleAdsRequest, dict]]): + The request object. Request message for + [GoogleAdsService.Mutate][google.ads.googleads.v23.services.GoogleAdsService.Mutate]. + customer_id (:class:`str`): + Required. The ID of the customer + whose resources are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mutate_operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.MutateOperation]`): + Required. The list of operations to + perform on individual resources. + + This corresponds to the ``mutate_operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateGoogleAdsResponse: + Response message for + [GoogleAdsService.Mutate][google.ads.googleads.v23.services.GoogleAdsService.Mutate]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, mutate_operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, google_ads_service.MutateGoogleAdsRequest): + request = google_ads_service.MutateGoogleAdsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if mutate_operations: + request.mutate_operations.extend(mutate_operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "GoogleAdsServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("GoogleAdsServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/google_ads_service/client.py b/google/ads/googleads/v23/services/services/google_ads_service/client.py new file mode 100644 index 000000000..0116aab2c --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_service/client.py @@ -0,0 +1,4997 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Iterable, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.services.google_ads_service import pagers +from google.ads.googleads.v23.services.types import google_ads_service +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import GoogleAdsServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import GoogleAdsServiceGrpcTransport +from .transports.grpc_asyncio import GoogleAdsServiceGrpcAsyncIOTransport + + +class GoogleAdsServiceClientMeta(type): + """Metaclass for the GoogleAdsService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[GoogleAdsServiceTransport]] + _transport_registry["grpc"] = GoogleAdsServiceGrpcTransport + _transport_registry["grpc_asyncio"] = GoogleAdsServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[GoogleAdsServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class GoogleAdsServiceClient(metaclass=GoogleAdsServiceClientMeta): + """Service to fetch data and metrics across resources.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + GoogleAdsServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> GoogleAdsServiceTransport: + """Returns the transport used by the client instance. + + Returns: + GoogleAdsServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def accessible_bidding_strategy_path( + customer_id: str, + bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified accessible_bidding_strategy string.""" + return "customers/{customer_id}/accessibleBiddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, + bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_accessible_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a accessible_bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accessibleBiddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def account_budget_path( + customer_id: str, + account_budget_id: str, + ) -> str: + """Returns a fully-qualified account_budget string.""" + return ( + "customers/{customer_id}/accountBudgets/{account_budget_id}".format( + customer_id=customer_id, + account_budget_id=account_budget_id, + ) + ) + + @staticmethod + def parse_account_budget_path(path: str) -> Dict[str, str]: + """Parses a account_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def account_budget_proposal_path( + customer_id: str, + account_budget_proposal_id: str, + ) -> str: + """Returns a fully-qualified account_budget_proposal string.""" + return "customers/{customer_id}/accountBudgetProposals/{account_budget_proposal_id}".format( + customer_id=customer_id, + account_budget_proposal_id=account_budget_proposal_id, + ) + + @staticmethod + def parse_account_budget_proposal_path(path: str) -> Dict[str, str]: + """Parses a account_budget_proposal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountBudgetProposals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def account_link_path( + customer_id: str, + account_link_id: str, + ) -> str: + """Returns a fully-qualified account_link string.""" + return "customers/{customer_id}/accountLinks/{account_link_id}".format( + customer_id=customer_id, + account_link_id=account_link_id, + ) + + @staticmethod + def parse_account_link_path(path: str) -> Dict[str, str]: + """Parses a account_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/accountLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_path( + customer_id: str, + ad_id: str, + ) -> str: + """Returns a fully-qualified ad string.""" + return "customers/{customer_id}/ads/{ad_id}".format( + customer_id=customer_id, + ad_id=ad_id, + ) + + @staticmethod + def parse_ad_path(path: str) -> Dict[str, str]: + """Parses a ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ads/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_path( + customer_id: str, + ad_group_id: str, + ) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad string.""" + return ( + "customers/{customer_id}/adGroupAds/{ad_group_id}~{ad_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + ) + ) + + @staticmethod + def parse_ad_group_ad_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAds/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_asset_combination_view_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + asset_combination_id_low: str, + asset_combination_id_high: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_asset_combination_view string.""" + return "customers/{customer_id}/adGroupAdAssetCombinationViews/{ad_group_id}~{ad_id}~{asset_combination_id_low}~{asset_combination_id_high}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + asset_combination_id_low=asset_combination_id_low, + asset_combination_id_high=asset_combination_id_high, + ) + + @staticmethod + def parse_ad_group_ad_asset_combination_view_path( + path: str, + ) -> Dict[str, str]: + """Parses a ad_group_ad_asset_combination_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdAssetCombinationViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_asset_view_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_asset_view string.""" + return "customers/{customer_id}/adGroupAdAssetViews/{ad_group_id}~{ad_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_ad_group_ad_asset_view_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad_asset_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdAssetViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_ad_label_path( + customer_id: str, + ad_group_id: str, + ad_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_ad_label string.""" + return "customers/{customer_id}/adGroupAdLabels/{ad_group_id}~{ad_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ad_id=ad_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_ad_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_ad_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAdLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_asset_path( + customer_id: str, + ad_group_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified ad_group_asset string.""" + return "customers/{customer_id}/adGroupAssets/{ad_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_ad_group_asset_path(path: str) -> Dict[str, str]: + """Parses a ad_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_asset_set_path( + customer_id: str, + ad_group_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified ad_group_asset_set string.""" + return "customers/{customer_id}/adGroupAssetSets/{ad_group_id}~{asset_set_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_ad_group_asset_set_path(path: str) -> Dict[str, str]: + """Parses a ad_group_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAssetSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_audience_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_audience_view string.""" + return "customers/{customer_id}/adGroupAudienceViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_audience_view_path(path: str) -> Dict[str, str]: + """Parses a ad_group_audience_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupAudienceViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_bid_modifier_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_bid_modifier string.""" + return "customers/{customer_id}/adGroupBidModifiers/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a ad_group_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion string.""" + return "customers/{customer_id}/adGroupCriteria/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_group_criterion_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_customizer_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_customizer string.""" + return "customers/{customer_id}/adGroupCriterionCustomizers/{ad_group_id}~{criterion_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_criterion_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionCustomizers/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_label_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_label string.""" + return "customers/{customer_id}/adGroupCriterionLabels/{ad_group_id}~{criterion_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_criterion_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionLabels/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_criterion_simulation_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + type: str, + modification_method: str, + start_date: str, + end_date: str, + ) -> str: + """Returns a fully-qualified ad_group_criterion_simulation string.""" + return "customers/{customer_id}/adGroupCriterionSimulations/{ad_group_id}~{criterion_id}~{type}~{modification_method}~{start_date}~{end_date}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + type=type, + modification_method=modification_method, + start_date=start_date, + end_date=end_date, + ) + + @staticmethod + def parse_ad_group_criterion_simulation_path(path: str) -> Dict[str, str]: + """Parses a ad_group_criterion_simulation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCriterionSimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_customizer_path( + customer_id: str, + ad_group_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified ad_group_customizer string.""" + return "customers/{customer_id}/adGroupCustomizers/{ad_group_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_ad_group_customizer_path(path: str) -> Dict[str, str]: + """Parses a ad_group_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_label_path( + customer_id: str, + ad_group_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified ad_group_label string.""" + return "customers/{customer_id}/adGroupLabels/{ad_group_id}~{label_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + label_id=label_id, + ) + + @staticmethod + def parse_ad_group_label_path(path: str) -> Dict[str, str]: + """Parses a ad_group_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_simulation_path( + customer_id: str, + ad_group_id: str, + type: str, + modification_method: str, + start_date: str, + end_date: str, + ) -> str: + """Returns a fully-qualified ad_group_simulation string.""" + return "customers/{customer_id}/adGroupSimulations/{ad_group_id}~{type}~{modification_method}~{start_date}~{end_date}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + type=type, + modification_method=modification_method, + start_date=start_date, + end_date=end_date, + ) + + @staticmethod + def parse_ad_group_simulation_path(path: str) -> Dict[str, str]: + """Parses a ad_group_simulation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroupSimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_parameter_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + parameter_index: str, + ) -> str: + """Returns a fully-qualified ad_parameter string.""" + return "customers/{customer_id}/adParameters/{ad_group_id}~{criterion_id}~{parameter_index}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + parameter_index=parameter_index, + ) + + @staticmethod + def parse_ad_parameter_path(path: str) -> Dict[str, str]: + """Parses a ad_parameter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adParameters/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_schedule_view_path( + customer_id: str, + campaign_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified ad_schedule_view string.""" + return "customers/{customer_id}/adScheduleViews/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_ad_schedule_view_path(path: str) -> Dict[str, str]: + """Parses a ad_schedule_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adScheduleViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def age_range_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified age_range_view string.""" + return "customers/{customer_id}/ageRangeViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_age_range_view_path(path: str) -> Dict[str, str]: + """Parses a age_range_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ageRangeViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def ai_max_search_term_ad_combination_view_path( + customer_id: str, + ad_group_id: str, + search_term: str, + landing_page: str, + headline: str, + ) -> str: + """Returns a fully-qualified ai_max_search_term_ad_combination_view string.""" + return "customers/{customer_id}/aiMaxSearchTermAdCombinationViews/{ad_group_id}~{search_term}~{landing_page}~{headline}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + search_term=search_term, + landing_page=landing_page, + headline=headline, + ) + + @staticmethod + def parse_ai_max_search_term_ad_combination_view_path( + path: str, + ) -> Dict[str, str]: + """Parses a ai_max_search_term_ad_combination_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/aiMaxSearchTermAdCombinationViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def android_privacy_shared_key_google_ad_group_path( + customer_id: str, + campaign_id: str, + ad_group_id: str, + android_privacy_interaction_type: str, + android_privacy_network_type: str, + android_privacy_interaction_date: str, + ) -> str: + """Returns a fully-qualified android_privacy_shared_key_google_ad_group string.""" + return "customers/{customer_id}/androidPrivacySharedKeyGoogleAdGroups/{campaign_id}~{ad_group_id}~{android_privacy_interaction_type}~{android_privacy_network_type}~{android_privacy_interaction_date}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ad_group_id=ad_group_id, + android_privacy_interaction_type=android_privacy_interaction_type, + android_privacy_network_type=android_privacy_network_type, + android_privacy_interaction_date=android_privacy_interaction_date, + ) + + @staticmethod + def parse_android_privacy_shared_key_google_ad_group_path( + path: str, + ) -> Dict[str, str]: + """Parses a android_privacy_shared_key_google_ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/androidPrivacySharedKeyGoogleAdGroups/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def android_privacy_shared_key_google_campaign_path( + customer_id: str, + campaign_id: str, + android_privacy_interaction_type: str, + android_privacy_interaction_date: str, + ) -> str: + """Returns a fully-qualified android_privacy_shared_key_google_campaign string.""" + return "customers/{customer_id}/androidPrivacySharedKeyGoogleCampaigns/{campaign_id}~{android_privacy_interaction_type}~{android_privacy_interaction_date}".format( + customer_id=customer_id, + campaign_id=campaign_id, + android_privacy_interaction_type=android_privacy_interaction_type, + android_privacy_interaction_date=android_privacy_interaction_date, + ) + + @staticmethod + def parse_android_privacy_shared_key_google_campaign_path( + path: str, + ) -> Dict[str, str]: + """Parses a android_privacy_shared_key_google_campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/androidPrivacySharedKeyGoogleCampaigns/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def android_privacy_shared_key_google_network_type_path( + customer_id: str, + campaign_id: str, + android_privacy_interaction_type: str, + android_privacy_network_type: str, + android_privacy_interaction_date: str, + ) -> str: + """Returns a fully-qualified android_privacy_shared_key_google_network_type string.""" + return "customers/{customer_id}/androidPrivacySharedKeyGoogleNetworkTypes/{campaign_id}~{android_privacy_interaction_type}~{android_privacy_network_type}~{android_privacy_interaction_date}".format( + customer_id=customer_id, + campaign_id=campaign_id, + android_privacy_interaction_type=android_privacy_interaction_type, + android_privacy_network_type=android_privacy_network_type, + android_privacy_interaction_date=android_privacy_interaction_date, + ) + + @staticmethod + def parse_android_privacy_shared_key_google_network_type_path( + path: str, + ) -> Dict[str, str]: + """Parses a android_privacy_shared_key_google_network_type path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/androidPrivacySharedKeyGoogleNetworkTypes/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def applied_incentive_path( + customer_id: str, + coupon_code: str, + ) -> str: + """Returns a fully-qualified applied_incentive string.""" + return "customers/{customer_id}/appliedIncentives/{coupon_code}".format( + customer_id=customer_id, + coupon_code=coupon_code, + ) + + @staticmethod + def parse_applied_incentive_path(path: str) -> Dict[str, str]: + """Parses a applied_incentive path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/appliedIncentives/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_path( + customer_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_field_type_view_path( + customer_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified asset_field_type_view string.""" + return ( + "customers/{customer_id}/assetFieldTypeViews/{field_type}".format( + customer_id=customer_id, + field_type=field_type, + ) + ) + + @staticmethod + def parse_asset_field_type_view_path(path: str) -> Dict[str, str]: + """Parses a asset_field_type_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetFieldTypeViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_path( + customer_id: str, + asset_group_id: str, + ) -> str: + """Returns a fully-qualified asset_group string.""" + return "customers/{customer_id}/assetGroups/{asset_group_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + ) + + @staticmethod + def parse_asset_group_path(path: str) -> Dict[str, str]: + """Parses a asset_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_asset_path( + customer_id: str, + asset_group_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified asset_group_asset string.""" + return "customers/{customer_id}/assetGroupAssets/{asset_group_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_asset_group_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_group_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_listing_group_filter_path( + customer_id: str, + asset_group_id: str, + listing_group_filter_id: str, + ) -> str: + """Returns a fully-qualified asset_group_listing_group_filter string.""" + return "customers/{customer_id}/assetGroupListingGroupFilters/{asset_group_id}~{listing_group_filter_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + listing_group_filter_id=listing_group_filter_id, + ) + + @staticmethod + def parse_asset_group_listing_group_filter_path( + path: str, + ) -> Dict[str, str]: + """Parses a asset_group_listing_group_filter path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupListingGroupFilters/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_product_group_view_path( + customer_id: str, + asset_group_id: str, + listing_group_filter_id: str, + ) -> str: + """Returns a fully-qualified asset_group_product_group_view string.""" + return "customers/{customer_id}/assetGroupProductGroupViews/{asset_group_id}~{listing_group_filter_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + listing_group_filter_id=listing_group_filter_id, + ) + + @staticmethod + def parse_asset_group_product_group_view_path(path: str) -> Dict[str, str]: + """Parses a asset_group_product_group_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupProductGroupViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_signal_path( + customer_id: str, + asset_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified asset_group_signal string.""" + return "customers/{customer_id}/assetGroupSignals/{asset_group_id}~{criterion_id}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_asset_group_signal_path(path: str) -> Dict[str, str]: + """Parses a asset_group_signal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupSignals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_group_top_combination_view_path( + customer_id: str, + asset_group_id: str, + asset_combination_category: str, + ) -> str: + """Returns a fully-qualified asset_group_top_combination_view string.""" + return "customers/{customer_id}/assetGroupTopCombinationViews/{asset_group_id}~{asset_combination_category}".format( + customer_id=customer_id, + asset_group_id=asset_group_id, + asset_combination_category=asset_combination_category, + ) + + @staticmethod + def parse_asset_group_top_combination_view_path( + path: str, + ) -> Dict[str, str]: + """Parses a asset_group_top_combination_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetGroupTopCombinationViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_path( + customer_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified asset_set string.""" + return "customers/{customer_id}/assetSets/{asset_set_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_asset_set_path(path: str) -> Dict[str, str]: + """Parses a asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_asset_path( + customer_id: str, + asset_set_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset_set_asset string.""" + return "customers/{customer_id}/assetSetAssets/{asset_set_id}~{asset_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_set_asset_path(path: str) -> Dict[str, str]: + """Parses a asset_set_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSetAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_set_type_view_path( + customer_id: str, + asset_set_type: str, + ) -> str: + """Returns a fully-qualified asset_set_type_view string.""" + return ( + "customers/{customer_id}/assetSetTypeViews/{asset_set_type}".format( + customer_id=customer_id, + asset_set_type=asset_set_type, + ) + ) + + @staticmethod + def parse_asset_set_type_view_path(path: str) -> Dict[str, str]: + """Parses a asset_set_type_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assetSetTypeViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def audience_path( + customer_id: str, + audience_id: str, + ) -> str: + """Returns a fully-qualified audience string.""" + return "customers/{customer_id}/audiences/{audience_id}".format( + customer_id=customer_id, + audience_id=audience_id, + ) + + @staticmethod + def parse_audience_path(path: str) -> Dict[str, str]: + """Parses a audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/audiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def batch_job_path( + customer_id: str, + batch_job_id: str, + ) -> str: + """Returns a fully-qualified batch_job string.""" + return "customers/{customer_id}/batchJobs/{batch_job_id}".format( + customer_id=customer_id, + batch_job_id=batch_job_id, + ) + + @staticmethod + def parse_batch_job_path(path: str) -> Dict[str, str]: + """Parses a batch_job path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/batchJobs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_data_exclusion_path( + customer_id: str, + seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_data_exclusion string.""" + return "customers/{customer_id}/biddingDataExclusions/{seasonality_event_id}".format( + customer_id=customer_id, + seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_data_exclusion_path(path: str) -> Dict[str, str]: + """Parses a bidding_data_exclusion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingDataExclusions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_seasonality_adjustment_path( + customer_id: str, + seasonality_event_id: str, + ) -> str: + """Returns a fully-qualified bidding_seasonality_adjustment string.""" + return "customers/{customer_id}/biddingSeasonalityAdjustments/{seasonality_event_id}".format( + customer_id=customer_id, + seasonality_event_id=seasonality_event_id, + ) + + @staticmethod + def parse_bidding_seasonality_adjustment_path(path: str) -> Dict[str, str]: + """Parses a bidding_seasonality_adjustment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingSeasonalityAdjustments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_strategy_path( + customer_id: str, + bidding_strategy_id: str, + ) -> str: + """Returns a fully-qualified bidding_strategy string.""" + return "customers/{customer_id}/biddingStrategies/{bidding_strategy_id}".format( + customer_id=customer_id, + bidding_strategy_id=bidding_strategy_id, + ) + + @staticmethod + def parse_bidding_strategy_path(path: str) -> Dict[str, str]: + """Parses a bidding_strategy path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingStrategies/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def bidding_strategy_simulation_path( + customer_id: str, + bidding_strategy_id: str, + type: str, + modification_method: str, + start_date: str, + end_date: str, + ) -> str: + """Returns a fully-qualified bidding_strategy_simulation string.""" + return "customers/{customer_id}/biddingStrategySimulations/{bidding_strategy_id}~{type}~{modification_method}~{start_date}~{end_date}".format( + customer_id=customer_id, + bidding_strategy_id=bidding_strategy_id, + type=type, + modification_method=modification_method, + start_date=start_date, + end_date=end_date, + ) + + @staticmethod + def parse_bidding_strategy_simulation_path(path: str) -> Dict[str, str]: + """Parses a bidding_strategy_simulation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/biddingStrategySimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def billing_setup_path( + customer_id: str, + billing_setup_id: str, + ) -> str: + """Returns a fully-qualified billing_setup string.""" + return ( + "customers/{customer_id}/billingSetups/{billing_setup_id}".format( + customer_id=customer_id, + billing_setup_id=billing_setup_id, + ) + ) + + @staticmethod + def parse_billing_setup_path(path: str) -> Dict[str, str]: + """Parses a billing_setup path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/billingSetups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def call_view_path( + customer_id: str, + call_detail_id: str, + ) -> str: + """Returns a fully-qualified call_view string.""" + return "customers/{customer_id}/callViews/{call_detail_id}".format( + customer_id=customer_id, + call_detail_id=call_detail_id, + ) + + @staticmethod + def parse_call_view_path(path: str) -> Dict[str, str]: + """Parses a call_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/callViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_aggregate_asset_view_path( + customer_id: str, + campaign_id: str, + asset_id: str, + asset_link_source: str, + field_type: str, + ) -> str: + """Returns a fully-qualified campaign_aggregate_asset_view string.""" + return "customers/{customer_id}/campaignAggregateAssetViews/{campaign_id}~{asset_id}~{asset_link_source}~{field_type}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_id=asset_id, + asset_link_source=asset_link_source, + field_type=field_type, + ) + + @staticmethod + def parse_campaign_aggregate_asset_view_path(path: str) -> Dict[str, str]: + """Parses a campaign_aggregate_asset_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAggregateAssetViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_path( + customer_id: str, + campaign_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified campaign_asset string.""" + return "customers/{customer_id}/campaignAssets/{campaign_id}~{asset_id}~{field_type}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_campaign_asset_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssets/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_asset_set_path( + customer_id: str, + campaign_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_asset_set string.""" + return "customers/{customer_id}/campaignAssetSets/{campaign_id}~{asset_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_set_id=asset_set_id, + ) + + @staticmethod + def parse_campaign_asset_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAssetSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_audience_view_path( + customer_id: str, + campaign_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_audience_view string.""" + return "customers/{customer_id}/campaignAudienceViews/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_audience_view_path(path: str) -> Dict[str, str]: + """Parses a campaign_audience_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignAudienceViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_bid_modifier_path( + customer_id: str, + campaign_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_bid_modifier string.""" + return "customers/{customer_id}/campaignBidModifiers/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_bid_modifier_path(path: str) -> Dict[str, str]: + """Parses a campaign_bid_modifier path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBidModifiers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_budget_path( + customer_id: str, + campaign_budget_id: str, + ) -> str: + """Returns a fully-qualified campaign_budget string.""" + return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( + customer_id=customer_id, + campaign_budget_id=campaign_budget_id, + ) + + @staticmethod + def parse_campaign_budget_path(path: str) -> Dict[str, str]: + """Parses a campaign_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_conversion_goal_path( + customer_id: str, + campaign_id: str, + category: str, + source: str, + ) -> str: + """Returns a fully-qualified campaign_conversion_goal string.""" + return "customers/{customer_id}/campaignConversionGoals/{campaign_id}~{category}~{source}".format( + customer_id=customer_id, + campaign_id=campaign_id, + category=category, + source=source, + ) + + @staticmethod + def parse_campaign_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a campaign_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignConversionGoals/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_criterion_path( + customer_id: str, + campaign_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified campaign_criterion string.""" + return "customers/{customer_id}/campaignCriteria/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_campaign_criterion_path(path: str) -> Dict[str, str]: + """Parses a campaign_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_customizer_path( + customer_id: str, + campaign_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified campaign_customizer string.""" + return "customers/{customer_id}/campaignCustomizers/{campaign_id}~{customizer_attribute_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_campaign_customizer_path(path: str) -> Dict[str, str]: + """Parses a campaign_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignCustomizers/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_draft_path( + customer_id: str, + base_campaign_id: str, + draft_id: str, + ) -> str: + """Returns a fully-qualified campaign_draft string.""" + return "customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}".format( + customer_id=customer_id, + base_campaign_id=base_campaign_id, + draft_id=draft_id, + ) + + @staticmethod + def parse_campaign_draft_path(path: str) -> Dict[str, str]: + """Parses a campaign_draft path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignDrafts/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_goal_config_path( + customer_id: str, + campaign_id: str, + unified_goal_id: str, + ) -> str: + """Returns a fully-qualified campaign_goal_config string.""" + return "customers/{customer_id}/campaignGoalConfigs/{campaign_id}~{unified_goal_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + unified_goal_id=unified_goal_id, + ) + + @staticmethod + def parse_campaign_goal_config_path(path: str) -> Dict[str, str]: + """Parses a campaign_goal_config path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignGoalConfigs/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_group_path( + customer_id: str, + campaign_group_id: str, + ) -> str: + """Returns a fully-qualified campaign_group string.""" + return ( + "customers/{customer_id}/campaignGroups/{campaign_group_id}".format( + customer_id=customer_id, + campaign_group_id=campaign_group_id, + ) + ) + + @staticmethod + def parse_campaign_group_path(path: str) -> Dict[str, str]: + """Parses a campaign_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_label_path( + customer_id: str, + campaign_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified campaign_label string.""" + return "customers/{customer_id}/campaignLabels/{campaign_id}~{label_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + label_id=label_id, + ) + + @staticmethod + def parse_campaign_label_path(path: str) -> Dict[str, str]: + """Parses a campaign_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignLabels/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_lifecycle_goal_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign_lifecycle_goal string.""" + return "customers/{customer_id}/campaignLifecycleGoals/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_lifecycle_goal_path(path: str) -> Dict[str, str]: + """Parses a campaign_lifecycle_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignLifecycleGoals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_search_term_insight_path( + customer_id: str, + campaign_id: str, + cluster_id: str, + ) -> str: + """Returns a fully-qualified campaign_search_term_insight string.""" + return "customers/{customer_id}/campaignSearchTermInsights/{campaign_id}~{cluster_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + cluster_id=cluster_id, + ) + + @staticmethod + def parse_campaign_search_term_insight_path(path: str) -> Dict[str, str]: + """Parses a campaign_search_term_insight path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignSearchTermInsights/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_search_term_view_path( + customer_id: str, + campaign_id: str, + query: str, + ) -> str: + """Returns a fully-qualified campaign_search_term_view string.""" + return "customers/{customer_id}/campaignSearchTermViews/{campaign_id}~{query}".format( + customer_id=customer_id, + campaign_id=campaign_id, + query=query, + ) + + @staticmethod + def parse_campaign_search_term_view_path(path: str) -> Dict[str, str]: + """Parses a campaign_search_term_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignSearchTermViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_shared_set_path( + customer_id: str, + campaign_id: str, + shared_set_id: str, + ) -> str: + """Returns a fully-qualified campaign_shared_set string.""" + return "customers/{customer_id}/campaignSharedSets/{campaign_id}~{shared_set_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_campaign_shared_set_path(path: str) -> Dict[str, str]: + """Parses a campaign_shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignSharedSets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_simulation_path( + customer_id: str, + campaign_id: str, + type: str, + modification_method: str, + start_date: str, + end_date: str, + ) -> str: + """Returns a fully-qualified campaign_simulation string.""" + return "customers/{customer_id}/campaignSimulations/{campaign_id}~{type}~{modification_method}~{start_date}~{end_date}".format( + customer_id=customer_id, + campaign_id=campaign_id, + type=type, + modification_method=modification_method, + start_date=start_date, + end_date=end_date, + ) + + @staticmethod + def parse_campaign_simulation_path(path: str) -> Dict[str, str]: + """Parses a campaign_simulation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignSimulations/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def carrier_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified carrier_constant string.""" + return "carrierConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_carrier_constant_path(path: str) -> Dict[str, str]: + """Parses a carrier_constant path into its component segments.""" + m = re.match(r"^carrierConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def change_event_path( + customer_id: str, + timestamp_micros: str, + command_index: str, + mutate_index: str, + ) -> str: + """Returns a fully-qualified change_event string.""" + return "customers/{customer_id}/changeEvents/{timestamp_micros}~{command_index}~{mutate_index}".format( + customer_id=customer_id, + timestamp_micros=timestamp_micros, + command_index=command_index, + mutate_index=mutate_index, + ) + + @staticmethod + def parse_change_event_path(path: str) -> Dict[str, str]: + """Parses a change_event path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/changeEvents/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def change_status_path( + customer_id: str, + change_status_id: str, + ) -> str: + """Returns a fully-qualified change_status string.""" + return "customers/{customer_id}/changeStatus/{change_status_id}".format( + customer_id=customer_id, + change_status_id=change_status_id, + ) + + @staticmethod + def parse_change_status_path(path: str) -> Dict[str, str]: + """Parses a change_status path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/changeStatus/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def channel_aggregate_asset_view_path( + customer_id: str, + advertising_channel_type: str, + asset_id: str, + asset_source: str, + field_type: str, + ) -> str: + """Returns a fully-qualified channel_aggregate_asset_view string.""" + return "customers/{customer_id}/channelAggregateAssetViews/{advertising_channel_type}~{asset_id}~{asset_source}~{field_type}".format( + customer_id=customer_id, + advertising_channel_type=advertising_channel_type, + asset_id=asset_id, + asset_source=asset_source, + field_type=field_type, + ) + + @staticmethod + def parse_channel_aggregate_asset_view_path(path: str) -> Dict[str, str]: + """Parses a channel_aggregate_asset_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/channelAggregateAssetViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def click_view_path( + customer_id: str, + date: str, + gclid: str, + ) -> str: + """Returns a fully-qualified click_view string.""" + return "customers/{customer_id}/clickViews/{date}~{gclid}".format( + customer_id=customer_id, + date=date, + gclid=gclid, + ) + + @staticmethod + def parse_click_view_path(path: str) -> Dict[str, str]: + """Parses a click_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/clickViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def combined_audience_path( + customer_id: str, + combined_audience_id: str, + ) -> str: + """Returns a fully-qualified combined_audience string.""" + return "customers/{customer_id}/combinedAudiences/{combined_audience_id}".format( + customer_id=customer_id, + combined_audience_id=combined_audience_id, + ) + + @staticmethod + def parse_combined_audience_path(path: str) -> Dict[str, str]: + """Parses a combined_audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/combinedAudiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def content_criterion_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified content_criterion_view string.""" + return "customers/{customer_id}/contentCriterionViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_content_criterion_view_path(path: str) -> Dict[str, str]: + """Parses a content_criterion_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/contentCriterionViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_action_path( + customer_id: str, + conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, + conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_custom_variable_path( + customer_id: str, + conversion_custom_variable_id: str, + ) -> str: + """Returns a fully-qualified conversion_custom_variable string.""" + return "customers/{customer_id}/conversionCustomVariables/{conversion_custom_variable_id}".format( + customer_id=customer_id, + conversion_custom_variable_id=conversion_custom_variable_id, + ) + + @staticmethod + def parse_conversion_custom_variable_path(path: str) -> Dict[str, str]: + """Parses a conversion_custom_variable path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionCustomVariables/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_goal_campaign_config_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified conversion_goal_campaign_config string.""" + return "customers/{customer_id}/conversionGoalCampaignConfigs/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_conversion_goal_campaign_config_path(path: str) -> Dict[str, str]: + """Parses a conversion_goal_campaign_config path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionGoalCampaignConfigs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_path( + customer_id: str, + conversion_value_rule_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule string.""" + return "customers/{customer_id}/conversionValueRules/{conversion_value_rule_id}".format( + customer_id=customer_id, + conversion_value_rule_id=conversion_value_rule_id, + ) + + @staticmethod + def parse_conversion_value_rule_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRules/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_value_rule_set_path( + customer_id: str, + conversion_value_rule_set_id: str, + ) -> str: + """Returns a fully-qualified conversion_value_rule_set string.""" + return "customers/{customer_id}/conversionValueRuleSets/{conversion_value_rule_set_id}".format( + customer_id=customer_id, + conversion_value_rule_set_id=conversion_value_rule_set_id, + ) + + @staticmethod + def parse_conversion_value_rule_set_path(path: str) -> Dict[str, str]: + """Parses a conversion_value_rule_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionValueRuleSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def currency_constant_path( + code: str, + ) -> str: + """Returns a fully-qualified currency_constant string.""" + return "currencyConstants/{code}".format( + code=code, + ) + + @staticmethod + def parse_currency_constant_path(path: str) -> Dict[str, str]: + """Parses a currency_constant path into its component segments.""" + m = re.match(r"^currencyConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def custom_audience_path( + customer_id: str, + custom_audience_id: str, + ) -> str: + """Returns a fully-qualified custom_audience string.""" + return "customers/{customer_id}/customAudiences/{custom_audience_id}".format( + customer_id=customer_id, + custom_audience_id=custom_audience_id, + ) + + @staticmethod + def parse_custom_audience_path(path: str) -> Dict[str, str]: + """Parses a custom_audience path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customAudiences/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def custom_conversion_goal_path( + customer_id: str, + goal_id: str, + ) -> str: + """Returns a fully-qualified custom_conversion_goal string.""" + return "customers/{customer_id}/customConversionGoals/{goal_id}".format( + customer_id=customer_id, + goal_id=goal_id, + ) + + @staticmethod + def parse_custom_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a custom_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customConversionGoals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def customer_asset_path( + customer_id: str, + asset_id: str, + field_type: str, + ) -> str: + """Returns a fully-qualified customer_asset string.""" + return "customers/{customer_id}/customerAssets/{asset_id}~{field_type}".format( + customer_id=customer_id, + asset_id=asset_id, + field_type=field_type, + ) + + @staticmethod + def parse_customer_asset_path(path: str) -> Dict[str, str]: + """Parses a customer_asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerAssets/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_asset_set_path( + customer_id: str, + asset_set_id: str, + ) -> str: + """Returns a fully-qualified customer_asset_set string.""" + return ( + "customers/{customer_id}/customerAssetSets/{asset_set_id}".format( + customer_id=customer_id, + asset_set_id=asset_set_id, + ) + ) + + @staticmethod + def parse_customer_asset_set_path(path: str) -> Dict[str, str]: + """Parses a customer_asset_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerAssetSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_client_path( + customer_id: str, + client_customer_id: str, + ) -> str: + """Returns a fully-qualified customer_client string.""" + return "customers/{customer_id}/customerClients/{client_customer_id}".format( + customer_id=customer_id, + client_customer_id=client_customer_id, + ) + + @staticmethod + def parse_customer_client_path(path: str) -> Dict[str, str]: + """Parses a customer_client path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerClients/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_client_link_path( + customer_id: str, + client_customer_id: str, + manager_link_id: str, + ) -> str: + """Returns a fully-qualified customer_client_link string.""" + return "customers/{customer_id}/customerClientLinks/{client_customer_id}~{manager_link_id}".format( + customer_id=customer_id, + client_customer_id=client_customer_id, + manager_link_id=manager_link_id, + ) + + @staticmethod + def parse_customer_client_link_path(path: str) -> Dict[str, str]: + """Parses a customer_client_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerClientLinks/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_conversion_goal_path( + customer_id: str, + category: str, + source: str, + ) -> str: + """Returns a fully-qualified customer_conversion_goal string.""" + return "customers/{customer_id}/customerConversionGoals/{category}~{source}".format( + customer_id=customer_id, + category=category, + source=source, + ) + + @staticmethod + def parse_customer_conversion_goal_path(path: str) -> Dict[str, str]: + """Parses a customer_conversion_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerConversionGoals/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_customizer_path( + customer_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customer_customizer string.""" + return "customers/{customer_id}/customerCustomizers/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customer_customizer_path(path: str) -> Dict[str, str]: + """Parses a customer_customizer path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerCustomizers/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_label_path( + customer_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified customer_label string.""" + return "customers/{customer_id}/customerLabels/{label_id}".format( + customer_id=customer_id, + label_id=label_id, + ) + + @staticmethod + def parse_customer_label_path(path: str) -> Dict[str, str]: + """Parses a customer_label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerLabels/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_lifecycle_goal_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer_lifecycle_goal string.""" + return "customers/{customer_id}/customerLifecycleGoals".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_lifecycle_goal_path(path: str) -> Dict[str, str]: + """Parses a customer_lifecycle_goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerLifecycleGoals$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_manager_link_path( + customer_id: str, + manager_customer_id: str, + manager_link_id: str, + ) -> str: + """Returns a fully-qualified customer_manager_link string.""" + return "customers/{customer_id}/customerManagerLinks/{manager_customer_id}~{manager_link_id}".format( + customer_id=customer_id, + manager_customer_id=manager_customer_id, + manager_link_id=manager_link_id, + ) + + @staticmethod + def parse_customer_manager_link_path(path: str) -> Dict[str, str]: + """Parses a customer_manager_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerManagerLinks/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_negative_criterion_path( + customer_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified customer_negative_criterion string.""" + return "customers/{customer_id}/customerNegativeCriteria/{criterion_id}".format( + customer_id=customer_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_customer_negative_criterion_path(path: str) -> Dict[str, str]: + """Parses a customer_negative_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerNegativeCriteria/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_search_term_insight_path( + customer_id: str, + cluster_id: str, + ) -> str: + """Returns a fully-qualified customer_search_term_insight string.""" + return "customers/{customer_id}/customerSearchTermInsights/{cluster_id}".format( + customer_id=customer_id, + cluster_id=cluster_id, + ) + + @staticmethod + def parse_customer_search_term_insight_path(path: str) -> Dict[str, str]: + """Parses a customer_search_term_insight path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerSearchTermInsights/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_user_access_path( + customer_id: str, + user_id: str, + ) -> str: + """Returns a fully-qualified customer_user_access string.""" + return "customers/{customer_id}/customerUserAccesses/{user_id}".format( + customer_id=customer_id, + user_id=user_id, + ) + + @staticmethod + def parse_customer_user_access_path(path: str) -> Dict[str, str]: + """Parses a customer_user_access path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerUserAccesses/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customer_user_access_invitation_path( + customer_id: str, + invitation_id: str, + ) -> str: + """Returns a fully-qualified customer_user_access_invitation string.""" + return "customers/{customer_id}/customerUserAccessInvitations/{invitation_id}".format( + customer_id=customer_id, + invitation_id=invitation_id, + ) + + @staticmethod + def parse_customer_user_access_invitation_path(path: str) -> Dict[str, str]: + """Parses a customer_user_access_invitation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customerUserAccessInvitations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def custom_interest_path( + customer_id: str, + custom_interest_id: str, + ) -> str: + """Returns a fully-qualified custom_interest string.""" + return "customers/{customer_id}/customInterests/{custom_interest_id}".format( + customer_id=customer_id, + custom_interest_id=custom_interest_id, + ) + + @staticmethod + def parse_custom_interest_path(path: str) -> Dict[str, str]: + """Parses a custom_interest path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customInterests/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def customizer_attribute_path( + customer_id: str, + customizer_attribute_id: str, + ) -> str: + """Returns a fully-qualified customizer_attribute string.""" + return "customers/{customer_id}/customizerAttributes/{customizer_attribute_id}".format( + customer_id=customer_id, + customizer_attribute_id=customizer_attribute_id, + ) + + @staticmethod + def parse_customizer_attribute_path(path: str) -> Dict[str, str]: + """Parses a customizer_attribute path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/customizerAttributes/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def data_link_path( + customer_id: str, + product_link_id: str, + data_link_id: str, + ) -> str: + """Returns a fully-qualified data_link string.""" + return "customers/{customer_id}/dataLinks/{product_link_id}~{data_link_id}".format( + customer_id=customer_id, + product_link_id=product_link_id, + data_link_id=data_link_id, + ) + + @staticmethod + def parse_data_link_path(path: str) -> Dict[str, str]: + """Parses a data_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/dataLinks/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def detail_content_suitability_placement_view_path( + customer_id: str, + placement_fingerprint: str, + ) -> str: + """Returns a fully-qualified detail_content_suitability_placement_view string.""" + return "customers/{customer_id}/detailContentSuitabilityPlacementViews/{placement_fingerprint}".format( + customer_id=customer_id, + placement_fingerprint=placement_fingerprint, + ) + + @staticmethod + def parse_detail_content_suitability_placement_view_path( + path: str, + ) -> Dict[str, str]: + """Parses a detail_content_suitability_placement_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/detailContentSuitabilityPlacementViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def detailed_demographic_path( + customer_id: str, + detailed_demographic_id: str, + ) -> str: + """Returns a fully-qualified detailed_demographic string.""" + return "customers/{customer_id}/detailedDemographics/{detailed_demographic_id}".format( + customer_id=customer_id, + detailed_demographic_id=detailed_demographic_id, + ) + + @staticmethod + def parse_detailed_demographic_path(path: str) -> Dict[str, str]: + """Parses a detailed_demographic path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/detailedDemographics/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def detail_placement_view_path( + customer_id: str, + ad_group_id: str, + base64_placement: str, + ) -> str: + """Returns a fully-qualified detail_placement_view string.""" + return "customers/{customer_id}/detailPlacementViews/{ad_group_id}~{base64_placement}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + base64_placement=base64_placement, + ) + + @staticmethod + def parse_detail_placement_view_path(path: str) -> Dict[str, str]: + """Parses a detail_placement_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/detailPlacementViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def display_keyword_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified display_keyword_view string.""" + return "customers/{customer_id}/displayKeywordViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_display_keyword_view_path(path: str) -> Dict[str, str]: + """Parses a display_keyword_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/displayKeywordViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def distance_view_path( + customer_id: str, + placeholder_chain_id: str, + distance_bucket: str, + ) -> str: + """Returns a fully-qualified distance_view string.""" + return "customers/{customer_id}/distanceViews/{placeholder_chain_id}~{distance_bucket}".format( + customer_id=customer_id, + placeholder_chain_id=placeholder_chain_id, + distance_bucket=distance_bucket, + ) + + @staticmethod + def parse_distance_view_path(path: str) -> Dict[str, str]: + """Parses a distance_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/distanceViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def domain_category_path( + customer_id: str, + campaign_id: str, + base64_category: str, + language_code: str, + ) -> str: + """Returns a fully-qualified domain_category string.""" + return "customers/{customer_id}/domainCategories/{campaign_id}~{base64_category}~{language_code}".format( + customer_id=customer_id, + campaign_id=campaign_id, + base64_category=base64_category, + language_code=language_code, + ) + + @staticmethod + def parse_domain_category_path(path: str) -> Dict[str, str]: + """Parses a domain_category path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/domainCategories/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def dynamic_search_ads_search_term_view_path( + customer_id: str, + ad_group_id: str, + search_term_fingerprint: str, + headline_fingerprint: str, + landing_page_fingerprint: str, + page_url_fingerprint: str, + ) -> str: + """Returns a fully-qualified dynamic_search_ads_search_term_view string.""" + return "customers/{customer_id}/dynamicSearchAdsSearchTermViews/{ad_group_id}~{search_term_fingerprint}~{headline_fingerprint}~{landing_page_fingerprint}~{page_url_fingerprint}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + search_term_fingerprint=search_term_fingerprint, + headline_fingerprint=headline_fingerprint, + landing_page_fingerprint=landing_page_fingerprint, + page_url_fingerprint=page_url_fingerprint, + ) + + @staticmethod + def parse_dynamic_search_ads_search_term_view_path( + path: str, + ) -> Dict[str, str]: + """Parses a dynamic_search_ads_search_term_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/dynamicSearchAdsSearchTermViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def expanded_landing_page_view_path( + customer_id: str, + expanded_final_url_fingerprint: str, + ) -> str: + """Returns a fully-qualified expanded_landing_page_view string.""" + return "customers/{customer_id}/expandedLandingPageViews/{expanded_final_url_fingerprint}".format( + customer_id=customer_id, + expanded_final_url_fingerprint=expanded_final_url_fingerprint, + ) + + @staticmethod + def parse_expanded_landing_page_view_path(path: str) -> Dict[str, str]: + """Parses a expanded_landing_page_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/expandedLandingPageViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_path( + customer_id: str, + trial_id: str, + ) -> str: + """Returns a fully-qualified experiment string.""" + return "customers/{customer_id}/experiments/{trial_id}".format( + customer_id=customer_id, + trial_id=trial_id, + ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str, str]: + """Parses a experiment path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experiments/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def experiment_arm_path( + customer_id: str, + trial_id: str, + trial_arm_id: str, + ) -> str: + """Returns a fully-qualified experiment_arm string.""" + return "customers/{customer_id}/experimentArms/{trial_id}~{trial_arm_id}".format( + customer_id=customer_id, + trial_id=trial_id, + trial_arm_id=trial_arm_id, + ) + + @staticmethod + def parse_experiment_arm_path(path: str) -> Dict[str, str]: + """Parses a experiment_arm path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/experimentArms/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def final_url_expansion_asset_view_path( + customer_id: str, + campaign_id: str, + asset_id: str, + field_type: str, + url_fp: str, + ) -> str: + """Returns a fully-qualified final_url_expansion_asset_view string.""" + return "customers/{customer_id}/finalUrlExpansionAssetViews/{campaign_id}~{asset_id}~{field_type}~{url_fp}".format( + customer_id=customer_id, + campaign_id=campaign_id, + asset_id=asset_id, + field_type=field_type, + url_fp=url_fp, + ) + + @staticmethod + def parse_final_url_expansion_asset_view_path(path: str) -> Dict[str, str]: + """Parses a final_url_expansion_asset_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/finalUrlExpansionAssetViews/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def gender_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified gender_view string.""" + return "customers/{customer_id}/genderViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_gender_view_path(path: str) -> Dict[str, str]: + """Parses a gender_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/genderViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def geographic_view_path( + customer_id: str, + country_criterion_id: str, + location_type: str, + ) -> str: + """Returns a fully-qualified geographic_view string.""" + return "customers/{customer_id}/geographicViews/{country_criterion_id}~{location_type}".format( + customer_id=customer_id, + country_criterion_id=country_criterion_id, + location_type=location_type, + ) + + @staticmethod + def parse_geographic_view_path(path: str) -> Dict[str, str]: + """Parses a geographic_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/geographicViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def geo_target_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def goal_path( + customer_id: str, + unified_goal_id: str, + ) -> str: + """Returns a fully-qualified goal string.""" + return "customers/{customer_id}/goals/{unified_goal_id}".format( + customer_id=customer_id, + unified_goal_id=unified_goal_id, + ) + + @staticmethod + def parse_goal_path(path: str) -> Dict[str, str]: + """Parses a goal path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/goals/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def group_content_suitability_placement_view_path( + customer_id: str, + placement_fingerprint: str, + ) -> str: + """Returns a fully-qualified group_content_suitability_placement_view string.""" + return "customers/{customer_id}/groupContentSuitabilityPlacementViews/{placement_fingerprint}".format( + customer_id=customer_id, + placement_fingerprint=placement_fingerprint, + ) + + @staticmethod + def parse_group_content_suitability_placement_view_path( + path: str, + ) -> Dict[str, str]: + """Parses a group_content_suitability_placement_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/groupContentSuitabilityPlacementViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def group_placement_view_path( + customer_id: str, + ad_group_id: str, + base64_placement: str, + ) -> str: + """Returns a fully-qualified group_placement_view string.""" + return "customers/{customer_id}/groupPlacementViews/{ad_group_id}~{base64_placement}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + base64_placement=base64_placement, + ) + + @staticmethod + def parse_group_placement_view_path(path: str) -> Dict[str, str]: + """Parses a group_placement_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/groupPlacementViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def hotel_group_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified hotel_group_view string.""" + return "customers/{customer_id}/hotelGroupViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_hotel_group_view_path(path: str) -> Dict[str, str]: + """Parses a hotel_group_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/hotelGroupViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def hotel_performance_view_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified hotel_performance_view string.""" + return "customers/{customer_id}/hotelPerformanceView".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_hotel_performance_view_path(path: str) -> Dict[str, str]: + """Parses a hotel_performance_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/hotelPerformanceView$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def hotel_reconciliation_path( + customer_id: str, + commission_id: str, + ) -> str: + """Returns a fully-qualified hotel_reconciliation string.""" + return "customers/{customer_id}/hotelReconciliations/{commission_id}".format( + customer_id=customer_id, + commission_id=commission_id, + ) + + @staticmethod + def parse_hotel_reconciliation_path(path: str) -> Dict[str, str]: + """Parses a hotel_reconciliation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/hotelReconciliations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def income_range_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified income_range_view string.""" + return "customers/{customer_id}/incomeRangeViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_income_range_view_path(path: str) -> Dict[str, str]: + """Parses a income_range_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/incomeRangeViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_path( + customer_id: str, + keyword_plan_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan string.""" + return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( + customer_id=customer_id, + keyword_plan_id=keyword_plan_id, + ) + + @staticmethod + def parse_keyword_plan_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_ad_group_path( + customer_id: str, + keyword_plan_ad_group_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group string.""" + return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_id=keyword_plan_ad_group_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_ad_group_keyword_path( + customer_id: str, + keyword_plan_ad_group_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group_keyword string.""" + return "customers/{customer_id}/keywordPlanAdGroupKeywords/{keyword_plan_ad_group_keyword_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_keyword_id=keyword_plan_ad_group_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroupKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_path( + customer_id: str, + keyword_plan_campaign_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign string.""" + return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( + customer_id=customer_id, + keyword_plan_campaign_id=keyword_plan_campaign_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_keyword_path( + customer_id: str, + keyword_plan_campaign_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign_keyword string.""" + return "customers/{customer_id}/keywordPlanCampaignKeywords/{keyword_plan_campaign_keyword_id}".format( + customer_id=customer_id, + keyword_plan_campaign_keyword_id=keyword_plan_campaign_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaignKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_theme_constant_path( + express_category_id: str, + express_sub_category_id: str, + ) -> str: + """Returns a fully-qualified keyword_theme_constant string.""" + return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( + express_category_id=express_category_id, + express_sub_category_id=express_sub_category_id, + ) + + @staticmethod + def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: + """Parses a keyword_theme_constant path into its component segments.""" + m = re.match( + r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified keyword_view string.""" + return "customers/{customer_id}/keywordViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_keyword_view_path(path: str) -> Dict[str, str]: + """Parses a keyword_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def label_path( + customer_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, + label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def landing_page_view_path( + customer_id: str, + unexpanded_final_url_fingerprint: str, + ) -> str: + """Returns a fully-qualified landing_page_view string.""" + return "customers/{customer_id}/landingPageViews/{unexpanded_final_url_fingerprint}".format( + customer_id=customer_id, + unexpanded_final_url_fingerprint=unexpanded_final_url_fingerprint, + ) + + @staticmethod + def parse_landing_page_view_path(path: str) -> Dict[str, str]: + """Parses a landing_page_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/landingPageViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def language_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified language_constant string.""" + return "languageConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_language_constant_path(path: str) -> Dict[str, str]: + """Parses a language_constant path into its component segments.""" + m = re.match(r"^languageConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def lead_form_submission_data_path( + customer_id: str, + lead_form_user_submission_id: str, + ) -> str: + """Returns a fully-qualified lead_form_submission_data string.""" + return "customers/{customer_id}/leadFormSubmissionData/{lead_form_user_submission_id}".format( + customer_id=customer_id, + lead_form_user_submission_id=lead_form_user_submission_id, + ) + + @staticmethod + def parse_lead_form_submission_data_path(path: str) -> Dict[str, str]: + """Parses a lead_form_submission_data path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/leadFormSubmissionData/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def life_event_path( + customer_id: str, + life_event_id: str, + ) -> str: + """Returns a fully-qualified life_event string.""" + return "customers/{customer_id}/lifeEvents/{life_event_id}".format( + customer_id=customer_id, + life_event_id=life_event_id, + ) + + @staticmethod + def parse_life_event_path(path: str) -> Dict[str, str]: + """Parses a life_event path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/lifeEvents/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def local_services_employee_path( + customer_id: str, + gls_employee_id: str, + ) -> str: + """Returns a fully-qualified local_services_employee string.""" + return "customers/{customer_id}/localServicesEmployees/{gls_employee_id}".format( + customer_id=customer_id, + gls_employee_id=gls_employee_id, + ) + + @staticmethod + def parse_local_services_employee_path(path: str) -> Dict[str, str]: + """Parses a local_services_employee path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/localServicesEmployees/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def local_services_lead_path( + customer_id: str, + local_services_lead_id: str, + ) -> str: + """Returns a fully-qualified local_services_lead string.""" + return "customers/{customer_id}/localServicesLeads/{local_services_lead_id}".format( + customer_id=customer_id, + local_services_lead_id=local_services_lead_id, + ) + + @staticmethod + def parse_local_services_lead_path(path: str) -> Dict[str, str]: + """Parses a local_services_lead path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/localServicesLeads/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def local_services_lead_conversation_path( + customer_id: str, + local_services_lead_conversation_id: str, + ) -> str: + """Returns a fully-qualified local_services_lead_conversation string.""" + return "customers/{customer_id}/localServicesLeadConversations/{local_services_lead_conversation_id}".format( + customer_id=customer_id, + local_services_lead_conversation_id=local_services_lead_conversation_id, + ) + + @staticmethod + def parse_local_services_lead_conversation_path( + path: str, + ) -> Dict[str, str]: + """Parses a local_services_lead_conversation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/localServicesLeadConversations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def local_services_verification_artifact_path( + customer_id: str, + gls_verification_artifact_id: str, + ) -> str: + """Returns a fully-qualified local_services_verification_artifact string.""" + return "customers/{customer_id}/localServicesVerificationArtifacts/{gls_verification_artifact_id}".format( + customer_id=customer_id, + gls_verification_artifact_id=gls_verification_artifact_id, + ) + + @staticmethod + def parse_local_services_verification_artifact_path( + path: str, + ) -> Dict[str, str]: + """Parses a local_services_verification_artifact path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/localServicesVerificationArtifacts/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def location_interest_view_path( + customer_id: str, + campaign_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified location_interest_view string.""" + return "customers/{customer_id}/locationInterestViews/{campaign_id}~{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_location_interest_view_path(path: str) -> Dict[str, str]: + """Parses a location_interest_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/locationInterestViews/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def location_view_path( + customer_id: str, + campaign_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified location_view string.""" + return "customers/{customer_id}/locationViews/{campaign_id}~{criterion_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_location_view_path(path: str) -> Dict[str, str]: + """Parses a location_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/locationViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def managed_placement_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified managed_placement_view string.""" + return "customers/{customer_id}/managedPlacementViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_managed_placement_view_path(path: str) -> Dict[str, str]: + """Parses a managed_placement_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/managedPlacementViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def matched_location_interest_view_path( + customer_id: str, + country_criterion_id: str, + ) -> str: + """Returns a fully-qualified matched_location_interest_view string.""" + return "customers/{customer_id}/matchedLocationInterestViews/{country_criterion_id}".format( + customer_id=customer_id, + country_criterion_id=country_criterion_id, + ) + + @staticmethod + def parse_matched_location_interest_view_path(path: str) -> Dict[str, str]: + """Parses a matched_location_interest_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/matchedLocationInterestViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def media_file_path( + customer_id: str, + media_file_id: str, + ) -> str: + """Returns a fully-qualified media_file string.""" + return "customers/{customer_id}/mediaFiles/{media_file_id}".format( + customer_id=customer_id, + media_file_id=media_file_id, + ) + + @staticmethod + def parse_media_file_path(path: str) -> Dict[str, str]: + """Parses a media_file path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/mediaFiles/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_app_category_constant_path( + mobile_app_category_id: str, + ) -> str: + """Returns a fully-qualified mobile_app_category_constant string.""" + return "mobileAppCategoryConstants/{mobile_app_category_id}".format( + mobile_app_category_id=mobile_app_category_id, + ) + + @staticmethod + def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: + """Parses a mobile_app_category_constant path into its component segments.""" + m = re.match( + r"^mobileAppCategoryConstants/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def mobile_device_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified mobile_device_constant string.""" + return "mobileDeviceConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_mobile_device_constant_path(path: str) -> Dict[str, str]: + """Parses a mobile_device_constant path into its component segments.""" + m = re.match(r"^mobileDeviceConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def offline_conversion_upload_client_summary_path( + customer_id: str, + client: str, + ) -> str: + """Returns a fully-qualified offline_conversion_upload_client_summary string.""" + return "customers/{customer_id}/offlineConversionUploadClientSummaries/{client}".format( + customer_id=customer_id, + client=client, + ) + + @staticmethod + def parse_offline_conversion_upload_client_summary_path( + path: str, + ) -> Dict[str, str]: + """Parses a offline_conversion_upload_client_summary path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/offlineConversionUploadClientSummaries/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def offline_conversion_upload_conversion_action_summary_path( + customer_id: str, + conversion_type_id: str, + client: str, + ) -> str: + """Returns a fully-qualified offline_conversion_upload_conversion_action_summary string.""" + return "customers/{customer_id}/offlineConversionUploadConversionActionSummaries/{conversion_type_id}~{client}".format( + customer_id=customer_id, + conversion_type_id=conversion_type_id, + client=client, + ) + + @staticmethod + def parse_offline_conversion_upload_conversion_action_summary_path( + path: str, + ) -> Dict[str, str]: + """Parses a offline_conversion_upload_conversion_action_summary path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/offlineConversionUploadConversionActionSummaries/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def offline_user_data_job_path( + customer_id: str, + offline_user_data_update_id: str, + ) -> str: + """Returns a fully-qualified offline_user_data_job string.""" + return "customers/{customer_id}/offlineUserDataJobs/{offline_user_data_update_id}".format( + customer_id=customer_id, + offline_user_data_update_id=offline_user_data_update_id, + ) + + @staticmethod + def parse_offline_user_data_job_path(path: str) -> Dict[str, str]: + """Parses a offline_user_data_job path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/offlineUserDataJobs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def operating_system_version_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified operating_system_version_constant string.""" + return "operatingSystemVersionConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_operating_system_version_constant_path( + path: str, + ) -> Dict[str, str]: + """Parses a operating_system_version_constant path into its component segments.""" + m = re.match( + r"^operatingSystemVersionConstants/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def paid_organic_search_term_view_path( + customer_id: str, + campaign_id: str, + ad_group_id: str, + base64_search_term: str, + ) -> str: + """Returns a fully-qualified paid_organic_search_term_view string.""" + return "customers/{customer_id}/paidOrganicSearchTermViews/{campaign_id}~{ad_group_id}~{base64_search_term}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ad_group_id=ad_group_id, + base64_search_term=base64_search_term, + ) + + @staticmethod + def parse_paid_organic_search_term_view_path(path: str) -> Dict[str, str]: + """Parses a paid_organic_search_term_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/paidOrganicSearchTermViews/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def parental_status_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified parental_status_view string.""" + return "customers/{customer_id}/parentalStatusViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_parental_status_view_path(path: str) -> Dict[str, str]: + """Parses a parental_status_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/parentalStatusViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def payments_account_path( + customer_id: str, + payments_account_id: str, + ) -> str: + """Returns a fully-qualified payments_account string.""" + return "customers/{customer_id}/paymentsAccounts/{payments_account_id}".format( + customer_id=customer_id, + payments_account_id=payments_account_id, + ) + + @staticmethod + def parse_payments_account_path(path: str) -> Dict[str, str]: + """Parses a payments_account path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/paymentsAccounts/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def performance_max_placement_view_path( + customer_id: str, + base_64_placement: str, + ) -> str: + """Returns a fully-qualified performance_max_placement_view string.""" + return "customers/{customer_id}/performanceMaxPlacementViews/{base_64_placement}".format( + customer_id=customer_id, + base_64_placement=base_64_placement, + ) + + @staticmethod + def parse_performance_max_placement_view_path(path: str) -> Dict[str, str]: + """Parses a performance_max_placement_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/performanceMaxPlacementViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def per_store_view_path( + customer_id: str, + place_id: str, + ) -> str: + """Returns a fully-qualified per_store_view string.""" + return "customers/{customer_id}/perStoreViews/{place_id}".format( + customer_id=customer_id, + place_id=place_id, + ) + + @staticmethod + def parse_per_store_view_path(path: str) -> Dict[str, str]: + """Parses a per_store_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/perStoreViews/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def product_category_constant_path( + level: str, + category_id: str, + ) -> str: + """Returns a fully-qualified product_category_constant string.""" + return "productCategoryConstants/{level}~{category_id}".format( + level=level, + category_id=category_id, + ) + + @staticmethod + def parse_product_category_constant_path(path: str) -> Dict[str, str]: + """Parses a product_category_constant path into its component segments.""" + m = re.match( + r"^productCategoryConstants/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def product_group_view_path( + customer_id: str, + adgroup_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified product_group_view string.""" + return "customers/{customer_id}/productGroupViews/{adgroup_id}~{criterion_id}".format( + customer_id=customer_id, + adgroup_id=adgroup_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_product_group_view_path(path: str) -> Dict[str, str]: + """Parses a product_group_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/productGroupViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def product_link_path( + customer_id: str, + product_link_id: str, + ) -> str: + """Returns a fully-qualified product_link string.""" + return "customers/{customer_id}/productLinks/{product_link_id}".format( + customer_id=customer_id, + product_link_id=product_link_id, + ) + + @staticmethod + def parse_product_link_path(path: str) -> Dict[str, str]: + """Parses a product_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/productLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def product_link_invitation_path( + customer_id: str, + customer_invitation_id: str, + ) -> str: + """Returns a fully-qualified product_link_invitation string.""" + return "customers/{customer_id}/productLinkInvitations/{customer_invitation_id}".format( + customer_id=customer_id, + customer_invitation_id=customer_invitation_id, + ) + + @staticmethod + def parse_product_link_invitation_path(path: str) -> Dict[str, str]: + """Parses a product_link_invitation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/productLinkInvitations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def qualifying_question_path( + qualifying_question_id: str, + ) -> str: + """Returns a fully-qualified qualifying_question string.""" + return "qualifyingQuestions/{qualifying_question_id}".format( + qualifying_question_id=qualifying_question_id, + ) + + @staticmethod + def parse_qualifying_question_path(path: str) -> Dict[str, str]: + """Parses a qualifying_question path into its component segments.""" + m = re.match( + r"^qualifyingQuestions/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def recommendation_path( + customer_id: str, + recommendation_id: str, + ) -> str: + """Returns a fully-qualified recommendation string.""" + return "customers/{customer_id}/recommendations/{recommendation_id}".format( + customer_id=customer_id, + recommendation_id=recommendation_id, + ) + + @staticmethod + def parse_recommendation_path(path: str) -> Dict[str, str]: + """Parses a recommendation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/recommendations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def recommendation_subscription_path( + customer_id: str, + recommendation_type: str, + ) -> str: + """Returns a fully-qualified recommendation_subscription string.""" + return "customers/{customer_id}/recommendationSubscriptions/{recommendation_type}".format( + customer_id=customer_id, + recommendation_type=recommendation_type, + ) + + @staticmethod + def parse_recommendation_subscription_path(path: str) -> Dict[str, str]: + """Parses a recommendation_subscription path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/recommendationSubscriptions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def remarketing_action_path( + customer_id: str, + remarketing_action_id: str, + ) -> str: + """Returns a fully-qualified remarketing_action string.""" + return "customers/{customer_id}/remarketingActions/{remarketing_action_id}".format( + customer_id=customer_id, + remarketing_action_id=remarketing_action_id, + ) + + @staticmethod + def parse_remarketing_action_path(path: str) -> Dict[str, str]: + """Parses a remarketing_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/remarketingActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def search_term_view_path( + customer_id: str, + campaign_id: str, + ad_group_id: str, + query: str, + ) -> str: + """Returns a fully-qualified search_term_view string.""" + return "customers/{customer_id}/searchTermViews/{campaign_id}~{ad_group_id}~{query}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ad_group_id=ad_group_id, + query=query, + ) + + @staticmethod + def parse_search_term_view_path(path: str) -> Dict[str, str]: + """Parses a search_term_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/searchTermViews/(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_criterion_path( + customer_id: str, + shared_set_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified shared_criterion string.""" + return "customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}".format( + customer_id=customer_id, + shared_set_id=shared_set_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_shared_criterion_path(path: str) -> Dict[str, str]: + """Parses a shared_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_set_path( + customer_id: str, + shared_set_id: str, + ) -> str: + """Returns a fully-qualified shared_set string.""" + return "customers/{customer_id}/sharedSets/{shared_set_id}".format( + customer_id=customer_id, + shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_shared_set_path(path: str) -> Dict[str, str]: + """Parses a shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shopping_performance_view_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified shopping_performance_view string.""" + return "customers/{customer_id}/shoppingPerformanceView".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_shopping_performance_view_path(path: str) -> Dict[str, str]: + """Parses a shopping_performance_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/shoppingPerformanceView$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def shopping_product_path( + customer_id: str, + merchant_center_id: str, + channel: str, + language_code: str, + feed_label: str, + item_id: str, + ) -> str: + """Returns a fully-qualified shopping_product string.""" + return "customers/{customer_id}/shoppingProducts/{merchant_center_id}~{channel}~{language_code}~{feed_label}~{item_id}".format( + customer_id=customer_id, + merchant_center_id=merchant_center_id, + channel=channel, + language_code=language_code, + feed_label=feed_label, + item_id=item_id, + ) + + @staticmethod + def parse_shopping_product_path(path: str) -> Dict[str, str]: + """Parses a shopping_product path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/shoppingProducts/(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def smart_campaign_search_term_view_path( + customer_id: str, + campaign_id: str, + query: str, + ) -> str: + """Returns a fully-qualified smart_campaign_search_term_view string.""" + return "customers/{customer_id}/smartCampaignSearchTermViews/{campaign_id}~{query}".format( + customer_id=customer_id, + campaign_id=campaign_id, + query=query, + ) + + @staticmethod + def parse_smart_campaign_search_term_view_path(path: str) -> Dict[str, str]: + """Parses a smart_campaign_search_term_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/smartCampaignSearchTermViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def smart_campaign_setting_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified smart_campaign_setting string.""" + return "customers/{customer_id}/smartCampaignSettings/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_smart_campaign_setting_path(path: str) -> Dict[str, str]: + """Parses a smart_campaign_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/smartCampaignSettings/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def targeting_expansion_view_path( + customer_id: str, + campaign_id: str, + targeting_expansion_type: str, + ) -> str: + """Returns a fully-qualified targeting_expansion_view string.""" + return "customers/{customer_id}/targetingExpansionViews/{campaign_id}~{targeting_expansion_type}".format( + customer_id=customer_id, + campaign_id=campaign_id, + targeting_expansion_type=targeting_expansion_type, + ) + + @staticmethod + def parse_targeting_expansion_view_path(path: str) -> Dict[str, str]: + """Parses a targeting_expansion_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/targetingExpansionViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def third_party_app_analytics_link_path( + customer_id: str, + customer_link_id: str, + ) -> str: + """Returns a fully-qualified third_party_app_analytics_link string.""" + return "customers/{customer_id}/thirdPartyAppAnalyticsLinks/{customer_link_id}".format( + customer_id=customer_id, + customer_link_id=customer_link_id, + ) + + @staticmethod + def parse_third_party_app_analytics_link_path(path: str) -> Dict[str, str]: + """Parses a third_party_app_analytics_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/thirdPartyAppAnalyticsLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def topic_constant_path( + topic_id: str, + ) -> str: + """Returns a fully-qualified topic_constant string.""" + return "topicConstants/{topic_id}".format( + topic_id=topic_id, + ) + + @staticmethod + def parse_topic_constant_path(path: str) -> Dict[str, str]: + """Parses a topic_constant path into its component segments.""" + m = re.match(r"^topicConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def topic_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified topic_view string.""" + return "customers/{customer_id}/topicViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_topic_view_path(path: str) -> Dict[str, str]: + """Parses a topic_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/topicViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def travel_activity_group_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified travel_activity_group_view string.""" + return "customers/{customer_id}/travelActivityGroupViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_travel_activity_group_view_path(path: str) -> Dict[str, str]: + """Parses a travel_activity_group_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/travelActivityGroupViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def travel_activity_performance_view_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified travel_activity_performance_view string.""" + return "customers/{customer_id}/travelActivityPerformanceViews".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_travel_activity_performance_view_path( + path: str, + ) -> Dict[str, str]: + """Parses a travel_activity_performance_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/travelActivityPerformanceViews$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_interest_path( + customer_id: str, + user_interest_id: str, + ) -> str: + """Returns a fully-qualified user_interest string.""" + return ( + "customers/{customer_id}/userInterests/{user_interest_id}".format( + customer_id=customer_id, + user_interest_id=user_interest_id, + ) + ) + + @staticmethod + def parse_user_interest_path(path: str) -> Dict[str, str]: + """Parses a user_interest path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userInterests/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_list_path( + customer_id: str, + user_list_id: str, + ) -> str: + """Returns a fully-qualified user_list string.""" + return "customers/{customer_id}/userLists/{user_list_id}".format( + customer_id=customer_id, + user_list_id=user_list_id, + ) + + @staticmethod + def parse_user_list_path(path: str) -> Dict[str, str]: + """Parses a user_list path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userLists/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_list_customer_type_path( + customer_id: str, + user_list_id: str, + semantic_label: str, + ) -> str: + """Returns a fully-qualified user_list_customer_type string.""" + return "customers/{customer_id}/userListCustomerTypes/{user_list_id}~{semantic_label}".format( + customer_id=customer_id, + user_list_id=user_list_id, + semantic_label=semantic_label, + ) + + @staticmethod + def parse_user_list_customer_type_path(path: str) -> Dict[str, str]: + """Parses a user_list_customer_type path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userListCustomerTypes/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_location_view_path( + customer_id: str, + country_criterion_id: str, + is_targeting_location: str, + ) -> str: + """Returns a fully-qualified user_location_view string.""" + return "customers/{customer_id}/userLocationViews/{country_criterion_id}~{is_targeting_location}".format( + customer_id=customer_id, + country_criterion_id=country_criterion_id, + is_targeting_location=is_targeting_location, + ) + + @staticmethod + def parse_user_location_view_path(path: str) -> Dict[str, str]: + """Parses a user_location_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userLocationViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def video_path( + customer_id: str, + video_id: str, + ) -> str: + """Returns a fully-qualified video string.""" + return "customers/{customer_id}/videos/{video_id}".format( + customer_id=customer_id, + video_id=video_id, + ) + + @staticmethod + def parse_video_path(path: str) -> Dict[str, str]: + """Parses a video path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/videos/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def webpage_view_path( + customer_id: str, + ad_group_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified webpage_view string.""" + return "customers/{customer_id}/webpageViews/{ad_group_id}~{criterion_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_webpage_view_path(path: str) -> Dict[str, str]: + """Parses a webpage_view path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/webpageViews/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = GoogleAdsServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = GoogleAdsServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = GoogleAdsServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = GoogleAdsServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + GoogleAdsServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = GoogleAdsServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + GoogleAdsServiceTransport, + Callable[..., GoogleAdsServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the google ads service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,GoogleAdsServiceTransport,Callable[..., GoogleAdsServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the GoogleAdsServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = GoogleAdsServiceClient._read_environment_variables() + self._client_cert_source = ( + GoogleAdsServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = GoogleAdsServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, GoogleAdsServiceTransport) + if transport_provided: + # transport is a GoogleAdsServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(GoogleAdsServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or GoogleAdsServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[GoogleAdsServiceTransport], + Callable[..., GoogleAdsServiceTransport], + ] = ( + GoogleAdsServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., GoogleAdsServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.GoogleAdsServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.GoogleAdsService", + "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.ads.googleads.v23.services.GoogleAdsService", + "credentialsType": None, + } + ), + ) + + def search( + self, + request: Optional[ + Union[google_ads_service.SearchGoogleAdsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + query: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.SearchPager: + r"""Returns all rows that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.SearchGoogleAdsRequest, dict]): + The request object. Request message for + [GoogleAdsService.Search][google.ads.googleads.v23.services.GoogleAdsService.Search]. + customer_id (str): + Required. The ID of the customer + being queried. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + query (str): + Required. The query string. + This corresponds to the ``query`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.google_ads_service.pagers.SearchPager: + Response message for + [GoogleAdsService.Search][google.ads.googleads.v23.services.GoogleAdsService.Search]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, query] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, google_ads_service.SearchGoogleAdsRequest): + request = google_ads_service.SearchGoogleAdsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if query is not None: + request.query = query + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.search] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.SearchPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def search_stream( + self, + request: Optional[ + Union[google_ads_service.SearchGoogleAdsStreamRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + query: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> Iterable[google_ads_service.SearchGoogleAdsStreamResponse]: + r"""Returns all rows that match the search stream query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.SearchGoogleAdsStreamRequest, dict]): + The request object. Request message for + [GoogleAdsService.SearchStream][google.ads.googleads.v23.services.GoogleAdsService.SearchStream]. + customer_id (str): + Required. The ID of the customer + being queried. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + query (str): + Required. The query string. + This corresponds to the ``query`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SearchGoogleAdsStreamResponse]: + Response message for + [GoogleAdsService.SearchStream][google.ads.googleads.v23.services.GoogleAdsService.SearchStream]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, query] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, google_ads_service.SearchGoogleAdsStreamRequest + ): + request = google_ads_service.SearchGoogleAdsStreamRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if query is not None: + request.query = query + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.search_stream] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def mutate( + self, + request: Optional[ + Union[google_ads_service.MutateGoogleAdsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + mutate_operations: Optional[ + MutableSequence[google_ads_service.MutateOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> google_ads_service.MutateGoogleAdsResponse: + r"""Creates, updates, or removes resources. This method supports + atomic transactions with multiple types of resources. For + example, you can atomically create a campaign and a campaign + budget, or perform up to thousands of mutates atomically. + + This method is essentially a wrapper around a series of mutate + methods. The only features it offers over calling those methods + directly are: + + - Atomic transactions + - Temp resource names (described below) + - Somewhat reduced latency over making a series of mutate calls + + Note: Only resources that support atomic transactions are + included, so this method can't replace all calls to individual + services. + + Atomic Transaction Benefits + --------------------------- + + Atomicity makes error handling much easier. If you're making a + series of changes and one fails, it can leave your account in an + inconsistent state. With atomicity, you either reach the chosen + state directly, or the request fails and you can retry. + + Temp Resource Names + ------------------- + + Temp resource names are a special type of resource name used to + create a resource and reference that resource in the same + request. For example, if a campaign budget is created with + ``resource_name`` equal to ``customers/123/campaignBudgets/-1``, + that resource name can be reused in the ``Campaign.budget`` + field in the same request. That way, the two resources are + created and linked atomically. + + To create a temp resource name, put a negative number in the + part of the name that the server would normally allocate. + + Note: + + - Resources must be created with a temp name before the name can + be reused. For example, the previous CampaignBudget+Campaign + example would fail if the mutate order was reversed. + - Temp names are not remembered across requests. + - There's no limit to the number of temp names in a request. + - Each temp name must use a unique negative number, even if the + resource types differ. + + Latency + ------- + + It's important to group mutates by resource type or the request + may time out and fail. Latency is roughly equal to a series of + calls to individual mutate methods, where each change in + resource type is a new call. For example, mutating 10 campaigns + then 10 ad groups is like 2 calls, while mutating 1 campaign, 1 + ad group, 1 campaign, 1 ad group is like 4 calls. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdGroupCriterionError <>`__ + `AdGroupError <>`__ `AssetError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `CampaignBudgetError <>`__ `CampaignCriterionError <>`__ + `CampaignError <>`__ `CampaignExperimentError <>`__ + `CampaignSharedSetError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `ConversionActionError <>`__ + `CriterionError <>`__ `CustomerFeedError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `DistinctError <>`__ `ExtensionFeedItemError <>`__ + `ExtensionSettingError <>`__ `FeedAttributeReferenceError <>`__ + `FeedError <>`__ `FeedItemError <>`__ `FeedItemSetError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `ImageError <>`__ + `InternalError <>`__ `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `LabelError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SharedSetError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `UserListError <>`__ + `YoutubeVideoRegistrationError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateGoogleAdsRequest, dict]): + The request object. Request message for + [GoogleAdsService.Mutate][google.ads.googleads.v23.services.GoogleAdsService.Mutate]. + customer_id (str): + Required. The ID of the customer + whose resources are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + mutate_operations (MutableSequence[google.ads.googleads.v23.services.types.MutateOperation]): + Required. The list of operations to + perform on individual resources. + + This corresponds to the ``mutate_operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateGoogleAdsResponse: + Response message for + [GoogleAdsService.Mutate][google.ads.googleads.v23.services.GoogleAdsService.Mutate]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, mutate_operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, google_ads_service.MutateGoogleAdsRequest): + request = google_ads_service.MutateGoogleAdsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if mutate_operations is not None: + request.mutate_operations = mutate_operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "GoogleAdsServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("GoogleAdsServiceClient",) diff --git a/google/ads/googleads/v23/services/services/google_ads_service/pagers.py b/google/ads/googleads/v23/services/services/google_ads_service/pagers.py new file mode 100644 index 000000000..2d114ee24 --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_service/pagers.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Sequence, + Tuple, + Iterator, + Union, +) + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import google_ads_service + + +class SearchPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.SearchGoogleAdsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``Search`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.SearchGoogleAdsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[..., google_ads_service.SearchGoogleAdsResponse], + request: google_ads_service.SearchGoogleAdsRequest, + response: google_ads_service.SearchGoogleAdsResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.SearchGoogleAdsRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.SearchGoogleAdsResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = google_ads_service.SearchGoogleAdsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[google_ads_service.SearchGoogleAdsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__(self) -> Iterator[google_ads_service.GoogleAdsRow]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class SearchAsyncPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.SearchGoogleAdsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``Search`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.SearchGoogleAdsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., Awaitable[google_ads_service.SearchGoogleAdsResponse] + ], + request: google_ads_service.SearchGoogleAdsRequest, + response: google_ads_service.SearchGoogleAdsResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.SearchGoogleAdsRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.SearchGoogleAdsResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = google_ads_service.SearchGoogleAdsRequest(request) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[google_ads_service.SearchGoogleAdsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__(self) -> AsyncIterator[google_ads_service.GoogleAdsRow]: + async def async_generator(): + async for page in self.pages: + for response in page.results: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/google_ads_service/transports/README.rst b/google/ads/googleads/v23/services/services/google_ads_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/google_ads_service/transports/README.rst rename to google/ads/googleads/v23/services/services/google_ads_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/google_ads_service/transports/__init__.py b/google/ads/googleads/v23/services/services/google_ads_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/google_ads_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/google_ads_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/google_ads_service/transports/base.py b/google/ads/googleads/v23/services/services/google_ads_service/transports/base.py new file mode 100644 index 000000000..92cdd500a --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_service/transports/base.py @@ -0,0 +1,207 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import google_ads_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class GoogleAdsServiceTransport(abc.ABC): + """Abstract transport class for GoogleAdsService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.search: gapic_v1.method.wrap_method( + self.search, + default_timeout=None, + client_info=client_info, + ), + self.search_stream: gapic_v1.method.wrap_method( + self.search_stream, + default_timeout=None, + client_info=client_info, + ), + self.mutate: gapic_v1.method.wrap_method( + self.mutate, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def search( + self, + ) -> Callable[ + [google_ads_service.SearchGoogleAdsRequest], + Union[ + google_ads_service.SearchGoogleAdsResponse, + Awaitable[google_ads_service.SearchGoogleAdsResponse], + ], + ]: + raise NotImplementedError() + + @property + def search_stream( + self, + ) -> Callable[ + [google_ads_service.SearchGoogleAdsStreamRequest], + Union[ + google_ads_service.SearchGoogleAdsStreamResponse, + Awaitable[google_ads_service.SearchGoogleAdsStreamResponse], + ], + ]: + raise NotImplementedError() + + @property + def mutate( + self, + ) -> Callable[ + [google_ads_service.MutateGoogleAdsRequest], + Union[ + google_ads_service.MutateGoogleAdsResponse, + Awaitable[google_ads_service.MutateGoogleAdsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("GoogleAdsServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/google_ads_service/transports/grpc.py b/google/ads/googleads/v23/services/services/google_ads_service/transports/grpc.py new file mode 100644 index 000000000..4ca2449f1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_service/transports/grpc.py @@ -0,0 +1,536 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import google_ads_service +from .base import GoogleAdsServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.GoogleAdsService", + "rpcName": str(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.ads.googleads.v23.services.GoogleAdsService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class GoogleAdsServiceGrpcTransport(GoogleAdsServiceTransport): + """gRPC backend transport for GoogleAdsService. + + Service to fetch data and metrics across resources. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def search( + self, + ) -> Callable[ + [google_ads_service.SearchGoogleAdsRequest], + google_ads_service.SearchGoogleAdsResponse, + ]: + r"""Return a callable for the search method over gRPC. + + Returns all rows that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SearchGoogleAdsRequest], + ~.SearchGoogleAdsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # 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._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GoogleAdsService/Search", + request_serializer=google_ads_service.SearchGoogleAdsRequest.serialize, + response_deserializer=google_ads_service.SearchGoogleAdsResponse.deserialize, + ) + return self._stubs["search"] + + @property + def search_stream( + self, + ) -> Callable[ + [google_ads_service.SearchGoogleAdsStreamRequest], + google_ads_service.SearchGoogleAdsStreamResponse, + ]: + r"""Return a callable for the search stream method over gRPC. + + Returns all rows that match the search stream query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SearchGoogleAdsStreamRequest], + ~.SearchGoogleAdsStreamResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "search_stream" not in self._stubs: + self._stubs["search_stream"] = self._logged_channel.unary_stream( + "/google.ads.googleads.v23.services.GoogleAdsService/SearchStream", + request_serializer=google_ads_service.SearchGoogleAdsStreamRequest.serialize, + response_deserializer=google_ads_service.SearchGoogleAdsStreamResponse.deserialize, + ) + return self._stubs["search_stream"] + + @property + def mutate( + self, + ) -> Callable[ + [google_ads_service.MutateGoogleAdsRequest], + google_ads_service.MutateGoogleAdsResponse, + ]: + r"""Return a callable for the mutate method over gRPC. + + Creates, updates, or removes resources. This method supports + atomic transactions with multiple types of resources. For + example, you can atomically create a campaign and a campaign + budget, or perform up to thousands of mutates atomically. + + This method is essentially a wrapper around a series of mutate + methods. The only features it offers over calling those methods + directly are: + + - Atomic transactions + - Temp resource names (described below) + - Somewhat reduced latency over making a series of mutate calls + + Note: Only resources that support atomic transactions are + included, so this method can't replace all calls to individual + services. + + Atomic Transaction Benefits + --------------------------- + + Atomicity makes error handling much easier. If you're making a + series of changes and one fails, it can leave your account in an + inconsistent state. With atomicity, you either reach the chosen + state directly, or the request fails and you can retry. + + Temp Resource Names + ------------------- + + Temp resource names are a special type of resource name used to + create a resource and reference that resource in the same + request. For example, if a campaign budget is created with + ``resource_name`` equal to ``customers/123/campaignBudgets/-1``, + that resource name can be reused in the ``Campaign.budget`` + field in the same request. That way, the two resources are + created and linked atomically. + + To create a temp resource name, put a negative number in the + part of the name that the server would normally allocate. + + Note: + + - Resources must be created with a temp name before the name can + be reused. For example, the previous CampaignBudget+Campaign + example would fail if the mutate order was reversed. + - Temp names are not remembered across requests. + - There's no limit to the number of temp names in a request. + - Each temp name must use a unique negative number, even if the + resource types differ. + + Latency + ------- + + It's important to group mutates by resource type or the request + may time out and fail. Latency is roughly equal to a series of + calls to individual mutate methods, where each change in + resource type is a new call. For example, mutating 10 campaigns + then 10 ad groups is like 2 calls, while mutating 1 campaign, 1 + ad group, 1 campaign, 1 ad group is like 4 calls. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdGroupCriterionError <>`__ + `AdGroupError <>`__ `AssetError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `CampaignBudgetError <>`__ `CampaignCriterionError <>`__ + `CampaignError <>`__ `CampaignExperimentError <>`__ + `CampaignSharedSetError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `ConversionActionError <>`__ + `CriterionError <>`__ `CustomerFeedError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `DistinctError <>`__ `ExtensionFeedItemError <>`__ + `ExtensionSettingError <>`__ `FeedAttributeReferenceError <>`__ + `FeedError <>`__ `FeedItemError <>`__ `FeedItemSetError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `ImageError <>`__ + `InternalError <>`__ `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `LabelError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SharedSetError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `UserListError <>`__ + `YoutubeVideoRegistrationError <>`__ + + Returns: + Callable[[~.MutateGoogleAdsRequest], + ~.MutateGoogleAdsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate" not in self._stubs: + self._stubs["mutate"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GoogleAdsService/Mutate", + request_serializer=google_ads_service.MutateGoogleAdsRequest.serialize, + response_deserializer=google_ads_service.MutateGoogleAdsResponse.deserialize, + ) + return self._stubs["mutate"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("GoogleAdsServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/google_ads_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/google_ads_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..4e44ef62d --- /dev/null +++ b/google/ads/googleads/v23/services/services/google_ads_service/transports/grpc_asyncio.py @@ -0,0 +1,567 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import google_ads_service +from .base import GoogleAdsServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.GoogleAdsService", + "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.ads.googleads.v23.services.GoogleAdsService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class GoogleAdsServiceGrpcAsyncIOTransport(GoogleAdsServiceTransport): + """gRPC AsyncIO backend transport for GoogleAdsService. + + Service to fetch data and metrics across resources. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def search( + self, + ) -> Callable[ + [google_ads_service.SearchGoogleAdsRequest], + Awaitable[google_ads_service.SearchGoogleAdsResponse], + ]: + r"""Return a callable for the search method over gRPC. + + Returns all rows that match the search query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SearchGoogleAdsRequest], + Awaitable[~.SearchGoogleAdsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # 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._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GoogleAdsService/Search", + request_serializer=google_ads_service.SearchGoogleAdsRequest.serialize, + response_deserializer=google_ads_service.SearchGoogleAdsResponse.deserialize, + ) + return self._stubs["search"] + + @property + def search_stream( + self, + ) -> Callable[ + [google_ads_service.SearchGoogleAdsStreamRequest], + Awaitable[google_ads_service.SearchGoogleAdsStreamResponse], + ]: + r"""Return a callable for the search stream method over gRPC. + + Returns all rows that match the search stream query. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ChangeEventError <>`__ + `ChangeStatusError <>`__ `ClickViewError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QueryError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SearchGoogleAdsStreamRequest], + Awaitable[~.SearchGoogleAdsStreamResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "search_stream" not in self._stubs: + self._stubs["search_stream"] = self._logged_channel.unary_stream( + "/google.ads.googleads.v23.services.GoogleAdsService/SearchStream", + request_serializer=google_ads_service.SearchGoogleAdsStreamRequest.serialize, + response_deserializer=google_ads_service.SearchGoogleAdsStreamResponse.deserialize, + ) + return self._stubs["search_stream"] + + @property + def mutate( + self, + ) -> Callable[ + [google_ads_service.MutateGoogleAdsRequest], + Awaitable[google_ads_service.MutateGoogleAdsResponse], + ]: + r"""Return a callable for the mutate method over gRPC. + + Creates, updates, or removes resources. This method supports + atomic transactions with multiple types of resources. For + example, you can atomically create a campaign and a campaign + budget, or perform up to thousands of mutates atomically. + + This method is essentially a wrapper around a series of mutate + methods. The only features it offers over calling those methods + directly are: + + - Atomic transactions + - Temp resource names (described below) + - Somewhat reduced latency over making a series of mutate calls + + Note: Only resources that support atomic transactions are + included, so this method can't replace all calls to individual + services. + + Atomic Transaction Benefits + --------------------------- + + Atomicity makes error handling much easier. If you're making a + series of changes and one fails, it can leave your account in an + inconsistent state. With atomicity, you either reach the chosen + state directly, or the request fails and you can retry. + + Temp Resource Names + ------------------- + + Temp resource names are a special type of resource name used to + create a resource and reference that resource in the same + request. For example, if a campaign budget is created with + ``resource_name`` equal to ``customers/123/campaignBudgets/-1``, + that resource name can be reused in the ``Campaign.budget`` + field in the same request. That way, the two resources are + created and linked atomically. + + To create a temp resource name, put a negative number in the + part of the name that the server would normally allocate. + + Note: + + - Resources must be created with a temp name before the name can + be reused. For example, the previous CampaignBudget+Campaign + example would fail if the mutate order was reversed. + - Temp names are not remembered across requests. + - There's no limit to the number of temp names in a request. + - Each temp name must use a unique negative number, even if the + resource types differ. + + Latency + ------- + + It's important to group mutates by resource type or the request + may time out and fail. Latency is roughly equal to a series of + calls to individual mutate methods, where each change in + resource type is a new call. For example, mutating 10 campaigns + then 10 ad groups is like 2 calls, while mutating 1 campaign, 1 + ad group, 1 campaign, 1 ad group is like 4 calls. + + List of thrown errors: `AdCustomizerError <>`__ `AdError <>`__ + `AdGroupAdError <>`__ `AdGroupCriterionError <>`__ + `AdGroupError <>`__ `AssetError <>`__ `AuthenticationError <>`__ + `AuthorizationError <>`__ `BiddingError <>`__ + `CampaignBudgetError <>`__ `CampaignCriterionError <>`__ + `CampaignError <>`__ `CampaignExperimentError <>`__ + `CampaignSharedSetError <>`__ `CollectionSizeError <>`__ + `ContextError <>`__ `ConversionActionError <>`__ + `CriterionError <>`__ `CustomerFeedError <>`__ + `DatabaseError <>`__ `DateError <>`__ `DateRangeError <>`__ + `DistinctError <>`__ `ExtensionFeedItemError <>`__ + `ExtensionSettingError <>`__ `FeedAttributeReferenceError <>`__ + `FeedError <>`__ `FeedItemError <>`__ `FeedItemSetError <>`__ + `FieldError <>`__ `FieldMaskError <>`__ + `FunctionParsingError <>`__ `HeaderError <>`__ `ImageError <>`__ + `InternalError <>`__ `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `LabelError <>`__ `ListOperationError <>`__ + `MediaUploadError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NullError <>`__ + `OperationAccessDeniedError <>`__ `PolicyFindingError <>`__ + `PolicyViolationError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SettingError <>`__ `SharedSetError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + `UrlFieldError <>`__ `UserListError <>`__ + `YoutubeVideoRegistrationError <>`__ + + Returns: + Callable[[~.MutateGoogleAdsRequest], + Awaitable[~.MutateGoogleAdsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate" not in self._stubs: + self._stubs["mutate"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.GoogleAdsService/Mutate", + request_serializer=google_ads_service.MutateGoogleAdsRequest.serialize, + response_deserializer=google_ads_service.MutateGoogleAdsResponse.deserialize, + ) + return self._stubs["mutate"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.search: self._wrap_method( + self.search, + default_timeout=None, + client_info=client_info, + ), + self.search_stream: self._wrap_method( + self.search_stream, + default_timeout=None, + client_info=client_info, + ), + self.mutate: self._wrap_method( + self.mutate, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("GoogleAdsServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/identity_verification_service/__init__.py b/google/ads/googleads/v23/services/services/identity_verification_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/identity_verification_service/__init__.py rename to google/ads/googleads/v23/services/services/identity_verification_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/identity_verification_service/async_client.py b/google/ads/googleads/v23/services/services/identity_verification_service/async_client.py new file mode 100644 index 000000000..8108b9b44 --- /dev/null +++ b/google/ads/googleads/v23/services/services/identity_verification_service/async_client.py @@ -0,0 +1,527 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.enums.types import identity_verification_program +from google.ads.googleads.v23.services.types import ( + identity_verification_service, +) +from .transports.base import ( + IdentityVerificationServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import IdentityVerificationServiceClient + +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 IdentityVerificationServiceAsyncClient: + """A service for managing Identity Verification Service.""" + + _client: IdentityVerificationServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = IdentityVerificationServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + IdentityVerificationServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + IdentityVerificationServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = IdentityVerificationServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod( + IdentityVerificationServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + IdentityVerificationServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + IdentityVerificationServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + IdentityVerificationServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + IdentityVerificationServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + IdentityVerificationServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + IdentityVerificationServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + IdentityVerificationServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + IdentityVerificationServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + IdentityVerificationServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + IdentityVerificationServiceAsyncClient: The constructed client. + """ + return IdentityVerificationServiceClient.from_service_account_info.__func__(IdentityVerificationServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + IdentityVerificationServiceAsyncClient: The constructed client. + """ + return IdentityVerificationServiceClient.from_service_account_file.__func__(IdentityVerificationServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return IdentityVerificationServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> IdentityVerificationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + IdentityVerificationServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = IdentityVerificationServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + IdentityVerificationServiceTransport, + Callable[..., IdentityVerificationServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the identity verification service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,IdentityVerificationServiceTransport,Callable[..., IdentityVerificationServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the IdentityVerificationServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = IdentityVerificationServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.IdentityVerificationServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.IdentityVerificationService", + "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.ads.googleads.v23.services.IdentityVerificationService", + "credentialsType": None, + } + ), + ) + + async def start_identity_verification( + self, + request: Optional[ + Union[ + identity_verification_service.StartIdentityVerificationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + verification_program: Optional[ + identity_verification_program.IdentityVerificationProgramEnum.IdentityVerificationProgram + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Starts Identity Verification for a given verification program + type. Statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.StartIdentityVerificationRequest, dict]]): + The request object. Request message for + [StartIdentityVerification][google.ads.googleads.v23.services.IdentityVerificationService.StartIdentityVerification]. + customer_id (:class:`str`): + Required. The Id of the customer for + whom we are creating this verification. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + verification_program (:class:`google.ads.googleads.v23.enums.types.IdentityVerificationProgramEnum.IdentityVerificationProgram`): + Required. The verification program + type for which we want to start the + verification. + + This corresponds to the ``verification_program`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, verification_program] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + identity_verification_service.StartIdentityVerificationRequest, + ): + request = ( + identity_verification_service.StartIdentityVerificationRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if verification_program is not None: + request.verification_program = verification_program + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.start_identity_verification + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def get_identity_verification( + self, + request: Optional[ + Union[ + identity_verification_service.GetIdentityVerificationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> identity_verification_service.GetIdentityVerificationResponse: + r"""Returns Identity Verification information. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GetIdentityVerificationRequest, dict]]): + The request object. Request message for + [GetIdentityVerification][google.ads.googleads.v23.services.IdentityVerificationService.GetIdentityVerification]. + customer_id (:class:`str`): + Required. The ID of the customer for + whom we are requesting verification + information. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GetIdentityVerificationResponse: + Response message for + [GetIdentityVerification][google.ads.googleads.v23.services.IdentityVerificationService.GetIdentityVerification]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + identity_verification_service.GetIdentityVerificationRequest, + ): + request = ( + identity_verification_service.GetIdentityVerificationRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.get_identity_verification + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "IdentityVerificationServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("IdentityVerificationServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/identity_verification_service/client.py b/google/ads/googleads/v23/services/services/identity_verification_service/client.py new file mode 100644 index 000000000..b1f730cc4 --- /dev/null +++ b/google/ads/googleads/v23/services/services/identity_verification_service/client.py @@ -0,0 +1,985 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.enums.types import identity_verification_program +from google.ads.googleads.v23.services.types import ( + identity_verification_service, +) +from .transports.base import ( + IdentityVerificationServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import IdentityVerificationServiceGrpcTransport +from .transports.grpc_asyncio import ( + IdentityVerificationServiceGrpcAsyncIOTransport, +) + + +class IdentityVerificationServiceClientMeta(type): + """Metaclass for the IdentityVerificationService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[IdentityVerificationServiceTransport]] + _transport_registry["grpc"] = IdentityVerificationServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + IdentityVerificationServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[IdentityVerificationServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class IdentityVerificationServiceClient( + metaclass=IdentityVerificationServiceClientMeta +): + """A service for managing Identity Verification Service.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + IdentityVerificationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + IdentityVerificationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> IdentityVerificationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + IdentityVerificationServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + IdentityVerificationServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + IdentityVerificationServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + IdentityVerificationServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + IdentityVerificationServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = IdentityVerificationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = IdentityVerificationServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + IdentityVerificationServiceTransport, + Callable[..., IdentityVerificationServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the identity verification service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,IdentityVerificationServiceTransport,Callable[..., IdentityVerificationServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the IdentityVerificationServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = IdentityVerificationServiceClient._read_environment_variables() + self._client_cert_source = ( + IdentityVerificationServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + IdentityVerificationServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, IdentityVerificationServiceTransport + ) + if transport_provided: + # transport is a IdentityVerificationServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + IdentityVerificationServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or IdentityVerificationServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[IdentityVerificationServiceTransport], + Callable[..., IdentityVerificationServiceTransport], + ] = ( + IdentityVerificationServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., IdentityVerificationServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.IdentityVerificationServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.IdentityVerificationService", + "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.ads.googleads.v23.services.IdentityVerificationService", + "credentialsType": None, + } + ), + ) + + def start_identity_verification( + self, + request: Optional[ + Union[ + identity_verification_service.StartIdentityVerificationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + verification_program: Optional[ + identity_verification_program.IdentityVerificationProgramEnum.IdentityVerificationProgram + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> None: + r"""Starts Identity Verification for a given verification program + type. Statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.StartIdentityVerificationRequest, dict]): + The request object. Request message for + [StartIdentityVerification][google.ads.googleads.v23.services.IdentityVerificationService.StartIdentityVerification]. + customer_id (str): + Required. The Id of the customer for + whom we are creating this verification. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + verification_program (google.ads.googleads.v23.enums.types.IdentityVerificationProgramEnum.IdentityVerificationProgram): + Required. The verification program + type for which we want to start the + verification. + + This corresponds to the ``verification_program`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, verification_program] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + identity_verification_service.StartIdentityVerificationRequest, + ): + request = ( + identity_verification_service.StartIdentityVerificationRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if verification_program is not None: + request.verification_program = verification_program + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.start_identity_verification + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def get_identity_verification( + self, + request: Optional[ + Union[ + identity_verification_service.GetIdentityVerificationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> identity_verification_service.GetIdentityVerificationResponse: + r"""Returns Identity Verification information. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GetIdentityVerificationRequest, dict]): + The request object. Request message for + [GetIdentityVerification][google.ads.googleads.v23.services.IdentityVerificationService.GetIdentityVerification]. + customer_id (str): + Required. The ID of the customer for + whom we are requesting verification + information. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GetIdentityVerificationResponse: + Response message for + [GetIdentityVerification][google.ads.googleads.v23.services.IdentityVerificationService.GetIdentityVerification]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + identity_verification_service.GetIdentityVerificationRequest, + ): + request = ( + identity_verification_service.GetIdentityVerificationRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.get_identity_verification + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "IdentityVerificationServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("IdentityVerificationServiceClient",) diff --git a/google/ads/googleads/v19/services/services/identity_verification_service/transports/README.rst b/google/ads/googleads/v23/services/services/identity_verification_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/identity_verification_service/transports/README.rst rename to google/ads/googleads/v23/services/services/identity_verification_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/identity_verification_service/transports/__init__.py b/google/ads/googleads/v23/services/services/identity_verification_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/identity_verification_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/identity_verification_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/identity_verification_service/transports/base.py b/google/ads/googleads/v23/services/services/identity_verification_service/transports/base.py new file mode 100644 index 000000000..a3df5b570 --- /dev/null +++ b/google/ads/googleads/v23/services/services/identity_verification_service/transports/base.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + identity_verification_service, +) +from google.protobuf import empty_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class IdentityVerificationServiceTransport(abc.ABC): + """Abstract transport class for IdentityVerificationService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.start_identity_verification: gapic_v1.method.wrap_method( + self.start_identity_verification, + default_timeout=None, + client_info=client_info, + ), + self.get_identity_verification: gapic_v1.method.wrap_method( + self.get_identity_verification, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def start_identity_verification( + self, + ) -> Callable[ + [identity_verification_service.StartIdentityVerificationRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def get_identity_verification( + self, + ) -> Callable[ + [identity_verification_service.GetIdentityVerificationRequest], + Union[ + identity_verification_service.GetIdentityVerificationResponse, + Awaitable[ + identity_verification_service.GetIdentityVerificationResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("IdentityVerificationServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/identity_verification_service/transports/grpc.py b/google/ads/googleads/v23/services/services/identity_verification_service/transports/grpc.py new file mode 100644 index 000000000..7949f26d6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/identity_verification_service/transports/grpc.py @@ -0,0 +1,428 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + identity_verification_service, +) +from google.protobuf import empty_pb2 # type: ignore +from .base import IdentityVerificationServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.IdentityVerificationService", + "rpcName": str(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.ads.googleads.v23.services.IdentityVerificationService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class IdentityVerificationServiceGrpcTransport( + IdentityVerificationServiceTransport +): + """gRPC backend transport for IdentityVerificationService. + + A service for managing Identity Verification Service. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def start_identity_verification( + self, + ) -> Callable[ + [identity_verification_service.StartIdentityVerificationRequest], + empty_pb2.Empty, + ]: + r"""Return a callable for the start identity verification method over gRPC. + + Starts Identity Verification for a given verification program + type. Statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.StartIdentityVerificationRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "start_identity_verification" not in self._stubs: + self._stubs["start_identity_verification"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.IdentityVerificationService/StartIdentityVerification", + request_serializer=identity_verification_service.StartIdentityVerificationRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + ) + return self._stubs["start_identity_verification"] + + @property + def get_identity_verification( + self, + ) -> Callable[ + [identity_verification_service.GetIdentityVerificationRequest], + identity_verification_service.GetIdentityVerificationResponse, + ]: + r"""Return a callable for the get identity verification method over gRPC. + + Returns Identity Verification information. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GetIdentityVerificationRequest], + ~.GetIdentityVerificationResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_identity_verification" not in self._stubs: + self._stubs["get_identity_verification"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.IdentityVerificationService/GetIdentityVerification", + request_serializer=identity_verification_service.GetIdentityVerificationRequest.serialize, + response_deserializer=identity_verification_service.GetIdentityVerificationResponse.deserialize, + ) + ) + return self._stubs["get_identity_verification"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("IdentityVerificationServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/identity_verification_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/identity_verification_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..001180124 --- /dev/null +++ b/google/ads/googleads/v23/services/services/identity_verification_service/transports/grpc_asyncio.py @@ -0,0 +1,456 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + identity_verification_service, +) +from google.protobuf import empty_pb2 # type: ignore +from .base import IdentityVerificationServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.IdentityVerificationService", + "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.ads.googleads.v23.services.IdentityVerificationService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class IdentityVerificationServiceGrpcAsyncIOTransport( + IdentityVerificationServiceTransport +): + """gRPC AsyncIO backend transport for IdentityVerificationService. + + A service for managing Identity Verification Service. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def start_identity_verification( + self, + ) -> Callable[ + [identity_verification_service.StartIdentityVerificationRequest], + Awaitable[empty_pb2.Empty], + ]: + r"""Return a callable for the start identity verification method over gRPC. + + Starts Identity Verification for a given verification program + type. Statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.StartIdentityVerificationRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "start_identity_verification" not in self._stubs: + self._stubs["start_identity_verification"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.IdentityVerificationService/StartIdentityVerification", + request_serializer=identity_verification_service.StartIdentityVerificationRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + ) + return self._stubs["start_identity_verification"] + + @property + def get_identity_verification( + self, + ) -> Callable[ + [identity_verification_service.GetIdentityVerificationRequest], + Awaitable[ + identity_verification_service.GetIdentityVerificationResponse + ], + ]: + r"""Return a callable for the get identity verification method over gRPC. + + Returns Identity Verification information. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GetIdentityVerificationRequest], + Awaitable[~.GetIdentityVerificationResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_identity_verification" not in self._stubs: + self._stubs["get_identity_verification"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.IdentityVerificationService/GetIdentityVerification", + request_serializer=identity_verification_service.GetIdentityVerificationRequest.serialize, + response_deserializer=identity_verification_service.GetIdentityVerificationResponse.deserialize, + ) + ) + return self._stubs["get_identity_verification"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.start_identity_verification: self._wrap_method( + self.start_identity_verification, + default_timeout=None, + client_info=client_info, + ), + self.get_identity_verification: self._wrap_method( + self.get_identity_verification, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("IdentityVerificationServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v23/services/services/incentive_service/__init__.py b/google/ads/googleads/v23/services/services/incentive_service/__init__.py new file mode 100644 index 000000000..e7bd10e9b --- /dev/null +++ b/google/ads/googleads/v23/services/services/incentive_service/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .client import IncentiveServiceClient +from .async_client import IncentiveServiceAsyncClient + +__all__ = ( + "IncentiveServiceClient", + "IncentiveServiceAsyncClient", +) diff --git a/google/ads/googleads/v23/services/services/incentive_service/async_client.py b/google/ads/googleads/v23/services/services/incentive_service/async_client.py new file mode 100644 index 000000000..2a96c1a39 --- /dev/null +++ b/google/ads/googleads/v23/services/services/incentive_service/async_client.py @@ -0,0 +1,457 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import incentive_service +from .transports.base import IncentiveServiceTransport, DEFAULT_CLIENT_INFO +from .client import IncentiveServiceClient + +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 IncentiveServiceAsyncClient: + """Service to support incentive related operations.""" + + _client: IncentiveServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = IncentiveServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = IncentiveServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + IncentiveServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = IncentiveServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod( + IncentiveServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + IncentiveServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(IncentiveServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + IncentiveServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + IncentiveServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + IncentiveServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + IncentiveServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + IncentiveServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + IncentiveServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + IncentiveServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + IncentiveServiceAsyncClient: The constructed client. + """ + return IncentiveServiceClient.from_service_account_info.__func__(IncentiveServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + IncentiveServiceAsyncClient: The constructed client. + """ + return IncentiveServiceClient.from_service_account_file.__func__(IncentiveServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return IncentiveServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> IncentiveServiceTransport: + """Returns the transport used by the client instance. + + Returns: + IncentiveServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = IncentiveServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + IncentiveServiceTransport, + Callable[..., IncentiveServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the incentive service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,IncentiveServiceTransport,Callable[..., IncentiveServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the IncentiveServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = IncentiveServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.IncentiveServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.IncentiveService", + "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.ads.googleads.v23.services.IncentiveService", + "credentialsType": None, + } + ), + ) + + async def fetch_incentive( + self, + request: Optional[ + Union[incentive_service.FetchIncentiveRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> incentive_service.FetchIncentiveResponse: + r"""Returns incentives for a given user. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.FetchIncentiveRequest, dict]]): + The request object. Request for getting the acquisition + incentive for a 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.FetchIncentiveResponse: + Response from getting the acquisition + incentive for a user when they visit a + specific marketing page. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, incentive_service.FetchIncentiveRequest): + request = incentive_service.FetchIncentiveRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.fetch_incentive + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def apply_incentive( + self, + request: Optional[ + Union[incentive_service.ApplyIncentiveRequest, dict] + ] = None, + *, + country_code: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> incentive_service.ApplyIncentiveResponse: + r"""Applies the incentive for the ads customer. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ApplyIncentiveRequest, dict]]): + The request object. Request message for applying an + incentive. + country_code (:class:`str`): + Required. User's country code. Required. This field must + be equal to the Google Ads account's billing country. + Incentive eligibility, terms of service, and reward + values are often country-specific. This country code is + used to ensure the selected incentive is applicable to + the user. Possible country codes: + https://developers.google.com/google-ads/api/data/codes-formats#country_codes + + This corresponds to the ``country_code`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ApplyIncentiveResponse: + Response for applying an incentive. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [country_code] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, incentive_service.ApplyIncentiveRequest): + request = incentive_service.ApplyIncentiveRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if country_code is not None: + request.country_code = country_code + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.apply_incentive + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ("customer_id", request.customer_id), + ("selected_incentive_id", request.selected_incentive_id), + ) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "IncentiveServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("IncentiveServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/incentive_service/client.py b/google/ads/googleads/v23/services/services/incentive_service/client.py new file mode 100644 index 000000000..475a851db --- /dev/null +++ b/google/ads/googleads/v23/services/services/incentive_service/client.py @@ -0,0 +1,895 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import incentive_service +from .transports.base import IncentiveServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import IncentiveServiceGrpcTransport +from .transports.grpc_asyncio import IncentiveServiceGrpcAsyncIOTransport + + +class IncentiveServiceClientMeta(type): + """Metaclass for the IncentiveService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[IncentiveServiceTransport]] + _transport_registry["grpc"] = IncentiveServiceGrpcTransport + _transport_registry["grpc_asyncio"] = IncentiveServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[IncentiveServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class IncentiveServiceClient(metaclass=IncentiveServiceClientMeta): + """Service to support incentive related operations.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + IncentiveServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + IncentiveServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> IncentiveServiceTransport: + """Returns the transport used by the client instance. + + Returns: + IncentiveServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = IncentiveServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = IncentiveServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = IncentiveServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = IncentiveServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + IncentiveServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = IncentiveServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + IncentiveServiceTransport, + Callable[..., IncentiveServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the incentive service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,IncentiveServiceTransport,Callable[..., IncentiveServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the IncentiveServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = IncentiveServiceClient._read_environment_variables() + self._client_cert_source = ( + IncentiveServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = IncentiveServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, IncentiveServiceTransport) + if transport_provided: + # transport is a IncentiveServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(IncentiveServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or IncentiveServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[IncentiveServiceTransport], + Callable[..., IncentiveServiceTransport], + ] = ( + IncentiveServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., IncentiveServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.IncentiveServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.IncentiveService", + "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.ads.googleads.v23.services.IncentiveService", + "credentialsType": None, + } + ), + ) + + def fetch_incentive( + self, + request: Optional[ + Union[incentive_service.FetchIncentiveRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> incentive_service.FetchIncentiveResponse: + r"""Returns incentives for a given user. + + Args: + request (Union[google.ads.googleads.v23.services.types.FetchIncentiveRequest, dict]): + The request object. Request for getting the acquisition + incentive for a 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.FetchIncentiveResponse: + Response from getting the acquisition + incentive for a user when they visit a + specific marketing page. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, incentive_service.FetchIncentiveRequest): + request = incentive_service.FetchIncentiveRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.fetch_incentive] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def apply_incentive( + self, + request: Optional[ + Union[incentive_service.ApplyIncentiveRequest, dict] + ] = None, + *, + country_code: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> incentive_service.ApplyIncentiveResponse: + r"""Applies the incentive for the ads customer. + + Args: + request (Union[google.ads.googleads.v23.services.types.ApplyIncentiveRequest, dict]): + The request object. Request message for applying an + incentive. + country_code (str): + Required. User's country code. Required. This field must + be equal to the Google Ads account's billing country. + Incentive eligibility, terms of service, and reward + values are often country-specific. This country code is + used to ensure the selected incentive is applicable to + the user. Possible country codes: + https://developers.google.com/google-ads/api/data/codes-formats#country_codes + + This corresponds to the ``country_code`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ApplyIncentiveResponse: + Response for applying an incentive. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [country_code] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, incentive_service.ApplyIncentiveRequest): + request = incentive_service.ApplyIncentiveRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if country_code is not None: + request.country_code = country_code + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.apply_incentive] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + ( + ("customer_id", request.customer_id), + ("selected_incentive_id", request.selected_incentive_id), + ) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "IncentiveServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("IncentiveServiceClient",) diff --git a/google/ads/googleads/v23/services/services/incentive_service/transports/README.rst b/google/ads/googleads/v23/services/services/incentive_service/transports/README.rst new file mode 100644 index 000000000..59e39e8df --- /dev/null +++ b/google/ads/googleads/v23/services/services/incentive_service/transports/README.rst @@ -0,0 +1,9 @@ + +transport inheritance structure +_______________________________ + +`IncentiveServiceTransport` is the ABC for all transports. +- public child `IncentiveServiceGrpcTransport` for sync gRPC transport (defined in `grpc.py`). +- public child `IncentiveServiceGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). +- private child `_BaseIncentiveServiceRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). +- public child `IncentiveServiceRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). diff --git a/google/ads/googleads/v23/services/services/incentive_service/transports/__init__.py b/google/ads/googleads/v23/services/services/incentive_service/transports/__init__.py new file mode 100644 index 000000000..0855ce0e6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/incentive_service/transports/__init__.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict + +from .base import IncentiveServiceTransport +from .grpc import IncentiveServiceGrpcTransport +from .grpc_asyncio import IncentiveServiceGrpcAsyncIOTransport + + +# Compile a registry of transports. +_transport_registry = ( + OrderedDict() +) # type: Dict[str, Type[IncentiveServiceTransport]] +_transport_registry["grpc"] = IncentiveServiceGrpcTransport +_transport_registry["grpc_asyncio"] = IncentiveServiceGrpcAsyncIOTransport + +__all__ = ( + "IncentiveServiceTransport", + "IncentiveServiceGrpcTransport", + "IncentiveServiceGrpcAsyncIOTransport", +) diff --git a/google/ads/googleads/v23/services/services/incentive_service/transports/base.py b/google/ads/googleads/v23/services/services/incentive_service/transports/base.py new file mode 100644 index 000000000..5f68b11be --- /dev/null +++ b/google/ads/googleads/v23/services/services/incentive_service/transports/base.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import incentive_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class IncentiveServiceTransport(abc.ABC): + """Abstract transport class for IncentiveService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.fetch_incentive: gapic_v1.method.wrap_method( + self.fetch_incentive, + default_timeout=None, + client_info=client_info, + ), + self.apply_incentive: gapic_v1.method.wrap_method( + self.apply_incentive, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def fetch_incentive( + self, + ) -> Callable[ + [incentive_service.FetchIncentiveRequest], + Union[ + incentive_service.FetchIncentiveResponse, + Awaitable[incentive_service.FetchIncentiveResponse], + ], + ]: + raise NotImplementedError() + + @property + def apply_incentive( + self, + ) -> Callable[ + [incentive_service.ApplyIncentiveRequest], + Union[ + incentive_service.ApplyIncentiveResponse, + Awaitable[incentive_service.ApplyIncentiveResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("IncentiveServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/incentive_service/transports/grpc.py b/google/ads/googleads/v23/services/services/incentive_service/transports/grpc.py new file mode 100644 index 000000000..ab6ea30a4 --- /dev/null +++ b/google/ads/googleads/v23/services/services/incentive_service/transports/grpc.py @@ -0,0 +1,410 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import incentive_service +from .base import IncentiveServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.IncentiveService", + "rpcName": str(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.ads.googleads.v23.services.IncentiveService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class IncentiveServiceGrpcTransport(IncentiveServiceTransport): + """gRPC backend transport for IncentiveService. + + Service to support incentive related operations. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def fetch_incentive( + self, + ) -> Callable[ + [incentive_service.FetchIncentiveRequest], + incentive_service.FetchIncentiveResponse, + ]: + r"""Return a callable for the fetch incentive method over gRPC. + + Returns incentives for a given user. + + Returns: + Callable[[~.FetchIncentiveRequest], + ~.FetchIncentiveResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "fetch_incentive" not in self._stubs: + self._stubs["fetch_incentive"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.IncentiveService/FetchIncentive", + request_serializer=incentive_service.FetchIncentiveRequest.serialize, + response_deserializer=incentive_service.FetchIncentiveResponse.deserialize, + ) + return self._stubs["fetch_incentive"] + + @property + def apply_incentive( + self, + ) -> Callable[ + [incentive_service.ApplyIncentiveRequest], + incentive_service.ApplyIncentiveResponse, + ]: + r"""Return a callable for the apply incentive method over gRPC. + + Applies the incentive for the ads customer. + + Returns: + Callable[[~.ApplyIncentiveRequest], + ~.ApplyIncentiveResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "apply_incentive" not in self._stubs: + self._stubs["apply_incentive"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.IncentiveService/ApplyIncentive", + request_serializer=incentive_service.ApplyIncentiveRequest.serialize, + response_deserializer=incentive_service.ApplyIncentiveResponse.deserialize, + ) + return self._stubs["apply_incentive"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("IncentiveServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/incentive_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/incentive_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..d3c9e1eba --- /dev/null +++ b/google/ads/googleads/v23/services/services/incentive_service/transports/grpc_asyncio.py @@ -0,0 +1,436 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import incentive_service +from .base import IncentiveServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.IncentiveService", + "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.ads.googleads.v23.services.IncentiveService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class IncentiveServiceGrpcAsyncIOTransport(IncentiveServiceTransport): + """gRPC AsyncIO backend transport for IncentiveService. + + Service to support incentive related operations. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def fetch_incentive( + self, + ) -> Callable[ + [incentive_service.FetchIncentiveRequest], + Awaitable[incentive_service.FetchIncentiveResponse], + ]: + r"""Return a callable for the fetch incentive method over gRPC. + + Returns incentives for a given user. + + Returns: + Callable[[~.FetchIncentiveRequest], + Awaitable[~.FetchIncentiveResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "fetch_incentive" not in self._stubs: + self._stubs["fetch_incentive"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.IncentiveService/FetchIncentive", + request_serializer=incentive_service.FetchIncentiveRequest.serialize, + response_deserializer=incentive_service.FetchIncentiveResponse.deserialize, + ) + return self._stubs["fetch_incentive"] + + @property + def apply_incentive( + self, + ) -> Callable[ + [incentive_service.ApplyIncentiveRequest], + Awaitable[incentive_service.ApplyIncentiveResponse], + ]: + r"""Return a callable for the apply incentive method over gRPC. + + Applies the incentive for the ads customer. + + Returns: + Callable[[~.ApplyIncentiveRequest], + Awaitable[~.ApplyIncentiveResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "apply_incentive" not in self._stubs: + self._stubs["apply_incentive"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.IncentiveService/ApplyIncentive", + request_serializer=incentive_service.ApplyIncentiveRequest.serialize, + response_deserializer=incentive_service.ApplyIncentiveResponse.deserialize, + ) + return self._stubs["apply_incentive"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.fetch_incentive: self._wrap_method( + self.fetch_incentive, + default_timeout=None, + client_info=client_info, + ), + self.apply_incentive: self._wrap_method( + self.apply_incentive, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("IncentiveServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/invoice_service/__init__.py b/google/ads/googleads/v23/services/services/invoice_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/invoice_service/__init__.py rename to google/ads/googleads/v23/services/services/invoice_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/invoice_service/async_client.py b/google/ads/googleads/v23/services/services/invoice_service/async_client.py new file mode 100644 index 000000000..29446ed6a --- /dev/null +++ b/google/ads/googleads/v23/services/services/invoice_service/async_client.py @@ -0,0 +1,436 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.enums.types import month_of_year +from google.ads.googleads.v23.services.types import invoice_service +from .transports.base import InvoiceServiceTransport, DEFAULT_CLIENT_INFO +from .client import InvoiceServiceClient + +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 InvoiceServiceAsyncClient: + """A service to fetch invoices issued for a billing setup during + a given month. + """ + + _client: InvoiceServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = InvoiceServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = InvoiceServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = InvoiceServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = InvoiceServiceClient._DEFAULT_UNIVERSE + + invoice_path = staticmethod(InvoiceServiceClient.invoice_path) + parse_invoice_path = staticmethod(InvoiceServiceClient.parse_invoice_path) + common_billing_account_path = staticmethod( + InvoiceServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + InvoiceServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(InvoiceServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + InvoiceServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + InvoiceServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + InvoiceServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(InvoiceServiceClient.common_project_path) + parse_common_project_path = staticmethod( + InvoiceServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + InvoiceServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + InvoiceServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + InvoiceServiceAsyncClient: The constructed client. + """ + return InvoiceServiceClient.from_service_account_info.__func__(InvoiceServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + InvoiceServiceAsyncClient: The constructed client. + """ + return InvoiceServiceClient.from_service_account_file.__func__(InvoiceServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return InvoiceServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> InvoiceServiceTransport: + """Returns the transport used by the client instance. + + Returns: + InvoiceServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = InvoiceServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + InvoiceServiceTransport, + Callable[..., InvoiceServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the invoice service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,InvoiceServiceTransport,Callable[..., InvoiceServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the InvoiceServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = InvoiceServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.InvoiceServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.InvoiceService", + "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.ads.googleads.v23.services.InvoiceService", + "credentialsType": None, + } + ), + ) + + async def list_invoices( + self, + request: Optional[ + Union[invoice_service.ListInvoicesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + billing_setup: Optional[str] = None, + issue_year: Optional[str] = None, + issue_month: Optional[month_of_year.MonthOfYearEnum.MonthOfYear] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> invoice_service.ListInvoicesResponse: + r"""Returns all invoices associated with a billing setup, for a + given month. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `InvoiceError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListInvoicesRequest, dict]]): + The request object. Request message for fetching the + invoices of a given billing setup that + were issued during a given month. + customer_id (:class:`str`): + Required. The ID of the customer to + fetch invoices for. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + billing_setup (:class:`str`): + Required. The billing setup resource name of the + requested invoices. + + ``customers/{customer_id}/billingSetups/{billing_setup_id}`` + + This corresponds to the ``billing_setup`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + issue_year (:class:`str`): + Required. The issue year to retrieve + invoices, in yyyy format. Only invoices + issued in 2019 or later can be + retrieved. + + This corresponds to the ``issue_year`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + issue_month (:class:`google.ads.googleads.v23.enums.types.MonthOfYearEnum.MonthOfYear`): + Required. The issue month to retrieve + invoices. + + This corresponds to the ``issue_month`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListInvoicesResponse: + Response message for + [InvoiceService.ListInvoices][google.ads.googleads.v23.services.InvoiceService.ListInvoices]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, billing_setup, issue_year, issue_month] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, invoice_service.ListInvoicesRequest): + request = invoice_service.ListInvoicesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if billing_setup is not None: + request.billing_setup = billing_setup + if issue_year is not None: + request.issue_year = issue_year + if issue_month is not None: + request.issue_month = issue_month + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_invoices + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "InvoiceServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("InvoiceServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/invoice_service/client.py b/google/ads/googleads/v23/services/services/invoice_service/client.py new file mode 100644 index 000000000..b9132f997 --- /dev/null +++ b/google/ads/googleads/v23/services/services/invoice_service/client.py @@ -0,0 +1,896 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.enums.types import month_of_year +from google.ads.googleads.v23.services.types import invoice_service +from .transports.base import InvoiceServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import InvoiceServiceGrpcTransport +from .transports.grpc_asyncio import InvoiceServiceGrpcAsyncIOTransport + + +class InvoiceServiceClientMeta(type): + """Metaclass for the InvoiceService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[InvoiceServiceTransport]] + _transport_registry["grpc"] = InvoiceServiceGrpcTransport + _transport_registry["grpc_asyncio"] = InvoiceServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[InvoiceServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class InvoiceServiceClient(metaclass=InvoiceServiceClientMeta): + """A service to fetch invoices issued for a billing setup during + a given month. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + InvoiceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + InvoiceServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> InvoiceServiceTransport: + """Returns the transport used by the client instance. + + Returns: + InvoiceServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def invoice_path( + customer_id: str, + invoice_id: str, + ) -> str: + """Returns a fully-qualified invoice string.""" + return "customers/{customer_id}/invoices/{invoice_id}".format( + customer_id=customer_id, + invoice_id=invoice_id, + ) + + @staticmethod + def parse_invoice_path(path: str) -> Dict[str, str]: + """Parses a invoice path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/invoices/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = InvoiceServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = InvoiceServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = InvoiceServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = InvoiceServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + InvoiceServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = InvoiceServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + InvoiceServiceTransport, + Callable[..., InvoiceServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the invoice service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,InvoiceServiceTransport,Callable[..., InvoiceServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the InvoiceServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = InvoiceServiceClient._read_environment_variables() + self._client_cert_source = InvoiceServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = InvoiceServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, InvoiceServiceTransport) + if transport_provided: + # transport is a InvoiceServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(InvoiceServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or InvoiceServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[InvoiceServiceTransport], + Callable[..., InvoiceServiceTransport], + ] = ( + InvoiceServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., InvoiceServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.InvoiceServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.InvoiceService", + "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.ads.googleads.v23.services.InvoiceService", + "credentialsType": None, + } + ), + ) + + def list_invoices( + self, + request: Optional[ + Union[invoice_service.ListInvoicesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + billing_setup: Optional[str] = None, + issue_year: Optional[str] = None, + issue_month: Optional[month_of_year.MonthOfYearEnum.MonthOfYear] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> invoice_service.ListInvoicesResponse: + r"""Returns all invoices associated with a billing setup, for a + given month. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `InvoiceError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListInvoicesRequest, dict]): + The request object. Request message for fetching the + invoices of a given billing setup that + were issued during a given month. + customer_id (str): + Required. The ID of the customer to + fetch invoices for. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + billing_setup (str): + Required. The billing setup resource name of the + requested invoices. + + ``customers/{customer_id}/billingSetups/{billing_setup_id}`` + + This corresponds to the ``billing_setup`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + issue_year (str): + Required. The issue year to retrieve + invoices, in yyyy format. Only invoices + issued in 2019 or later can be + retrieved. + + This corresponds to the ``issue_year`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + issue_month (google.ads.googleads.v23.enums.types.MonthOfYearEnum.MonthOfYear): + Required. The issue month to retrieve + invoices. + + This corresponds to the ``issue_month`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListInvoicesResponse: + Response message for + [InvoiceService.ListInvoices][google.ads.googleads.v23.services.InvoiceService.ListInvoices]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, billing_setup, issue_year, issue_month] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, invoice_service.ListInvoicesRequest): + request = invoice_service.ListInvoicesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if billing_setup is not None: + request.billing_setup = billing_setup + if issue_year is not None: + request.issue_year = issue_year + if issue_month is not None: + request.issue_month = issue_month + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_invoices] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "InvoiceServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("InvoiceServiceClient",) diff --git a/google/ads/googleads/v19/services/services/invoice_service/transports/README.rst b/google/ads/googleads/v23/services/services/invoice_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/invoice_service/transports/README.rst rename to google/ads/googleads/v23/services/services/invoice_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/invoice_service/transports/__init__.py b/google/ads/googleads/v23/services/services/invoice_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/invoice_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/invoice_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/invoice_service/transports/base.py b/google/ads/googleads/v23/services/services/invoice_service/transports/base.py new file mode 100644 index 000000000..80e3d91be --- /dev/null +++ b/google/ads/googleads/v23/services/services/invoice_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import invoice_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class InvoiceServiceTransport(abc.ABC): + """Abstract transport class for InvoiceService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_invoices: gapic_v1.method.wrap_method( + self.list_invoices, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def list_invoices( + self, + ) -> Callable[ + [invoice_service.ListInvoicesRequest], + Union[ + invoice_service.ListInvoicesResponse, + Awaitable[invoice_service.ListInvoicesResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("InvoiceServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/invoice_service/transports/grpc.py b/google/ads/googleads/v23/services/services/invoice_service/transports/grpc.py new file mode 100644 index 000000000..b2b007cbe --- /dev/null +++ b/google/ads/googleads/v23/services/services/invoice_service/transports/grpc.py @@ -0,0 +1,388 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import invoice_service +from .base import InvoiceServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.InvoiceService", + "rpcName": str(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.ads.googleads.v23.services.InvoiceService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class InvoiceServiceGrpcTransport(InvoiceServiceTransport): + """gRPC backend transport for InvoiceService. + + A service to fetch invoices issued for a billing setup during + a given month. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def list_invoices( + self, + ) -> Callable[ + [invoice_service.ListInvoicesRequest], + invoice_service.ListInvoicesResponse, + ]: + r"""Return a callable for the list invoices method over gRPC. + + Returns all invoices associated with a billing setup, for a + given month. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `InvoiceError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListInvoicesRequest], + ~.ListInvoicesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_invoices" not in self._stubs: + self._stubs["list_invoices"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.InvoiceService/ListInvoices", + request_serializer=invoice_service.ListInvoicesRequest.serialize, + response_deserializer=invoice_service.ListInvoicesResponse.deserialize, + ) + return self._stubs["list_invoices"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("InvoiceServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/invoice_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/invoice_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..ca3ba96ac --- /dev/null +++ b/google/ads/googleads/v23/services/services/invoice_service/transports/grpc_asyncio.py @@ -0,0 +1,409 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import invoice_service +from .base import InvoiceServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.InvoiceService", + "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.ads.googleads.v23.services.InvoiceService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class InvoiceServiceGrpcAsyncIOTransport(InvoiceServiceTransport): + """gRPC AsyncIO backend transport for InvoiceService. + + A service to fetch invoices issued for a billing setup during + a given month. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def list_invoices( + self, + ) -> Callable[ + [invoice_service.ListInvoicesRequest], + Awaitable[invoice_service.ListInvoicesResponse], + ]: + r"""Return a callable for the list invoices method over gRPC. + + Returns all invoices associated with a billing setup, for a + given month. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `InvoiceError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.ListInvoicesRequest], + Awaitable[~.ListInvoicesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_invoices" not in self._stubs: + self._stubs["list_invoices"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.InvoiceService/ListInvoices", + request_serializer=invoice_service.ListInvoicesRequest.serialize, + response_deserializer=invoice_service.ListInvoicesResponse.deserialize, + ) + return self._stubs["list_invoices"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.list_invoices: self._wrap_method( + self.list_invoices, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("InvoiceServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/async_client.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/async_client.py new file mode 100644 index 000000000..c69121c42 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/async_client.py @@ -0,0 +1,459 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + keyword_plan_ad_group_keyword_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanAdGroupKeywordServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import KeywordPlanAdGroupKeywordServiceClient + +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 KeywordPlanAdGroupKeywordServiceAsyncClient: + """Service to manage Keyword Plan ad group keywords. + KeywordPlanAdGroup is required to add ad group keywords. + Positive and negative keywords are supported. A maximum of + 10,000 positive keywords are allowed per keyword plan. A maximum + of 1,000 negative keywords are allower per keyword plan. This + includes campaign negative keywords and ad group negative + keywords. + """ + + _client: KeywordPlanAdGroupKeywordServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = KeywordPlanAdGroupKeywordServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + KeywordPlanAdGroupKeywordServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + KeywordPlanAdGroupKeywordServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = KeywordPlanAdGroupKeywordServiceClient._DEFAULT_UNIVERSE + + keyword_plan_ad_group_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.keyword_plan_ad_group_path + ) + parse_keyword_plan_ad_group_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.parse_keyword_plan_ad_group_path + ) + keyword_plan_ad_group_keyword_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.keyword_plan_ad_group_keyword_path + ) + parse_keyword_plan_ad_group_keyword_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.parse_keyword_plan_ad_group_keyword_path + ) + common_billing_account_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + KeywordPlanAdGroupKeywordServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupKeywordServiceAsyncClient: The constructed client. + """ + return KeywordPlanAdGroupKeywordServiceClient.from_service_account_info.__func__(KeywordPlanAdGroupKeywordServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupKeywordServiceAsyncClient: The constructed client. + """ + return KeywordPlanAdGroupKeywordServiceClient.from_service_account_file.__func__(KeywordPlanAdGroupKeywordServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return KeywordPlanAdGroupKeywordServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> KeywordPlanAdGroupKeywordServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanAdGroupKeywordServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + KeywordPlanAdGroupKeywordServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanAdGroupKeywordServiceTransport, + Callable[..., KeywordPlanAdGroupKeywordServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan ad group keyword service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanAdGroupKeywordServiceTransport,Callable[..., KeywordPlanAdGroupKeywordServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanAdGroupKeywordServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = KeywordPlanAdGroupKeywordServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.KeywordPlanAdGroupKeywordServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService", + "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.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService", + "credentialsType": None, + } + ), + ) + + async def mutate_keyword_plan_ad_group_keywords( + self, + request: Optional[ + Union[ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + keyword_plan_ad_group_keyword_service.KeywordPlanAdGroupKeywordOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse + ): + r"""Creates, updates, or removes Keyword Plan ad group keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupKeywordsRequest, dict]]): + The request object. Request message for + [KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords][google.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords]. + customer_id (:class:`str`): + Required. The ID of the customer + whose Keyword Plan ad group keywords are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanAdGroupKeywordOperation]`): + Required. The list of operations to + perform on individual Keyword Plan ad + group keywords. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupKeywordsResponse: + Response message for a Keyword Plan + ad group keyword mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest, + ): + request = keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_keyword_plan_ad_group_keywords + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "KeywordPlanAdGroupKeywordServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("KeywordPlanAdGroupKeywordServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/client.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/client.py new file mode 100644 index 000000000..35778d01a --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/client.py @@ -0,0 +1,958 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + keyword_plan_ad_group_keyword_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanAdGroupKeywordServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordPlanAdGroupKeywordServiceGrpcTransport +from .transports.grpc_asyncio import ( + KeywordPlanAdGroupKeywordServiceGrpcAsyncIOTransport, +) + + +class KeywordPlanAdGroupKeywordServiceClientMeta(type): + """Metaclass for the KeywordPlanAdGroupKeywordService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanAdGroupKeywordServiceTransport]] + _transport_registry["grpc"] = KeywordPlanAdGroupKeywordServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + KeywordPlanAdGroupKeywordServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[KeywordPlanAdGroupKeywordServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanAdGroupKeywordServiceClient( + metaclass=KeywordPlanAdGroupKeywordServiceClientMeta +): + """Service to manage Keyword Plan ad group keywords. + KeywordPlanAdGroup is required to add ad group keywords. + Positive and negative keywords are supported. A maximum of + 10,000 positive keywords are allowed per keyword plan. A maximum + of 1,000 negative keywords are allower per keyword plan. This + includes campaign negative keywords and ad group negative + keywords. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupKeywordServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupKeywordServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanAdGroupKeywordServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanAdGroupKeywordServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def keyword_plan_ad_group_path( + customer_id: str, + keyword_plan_ad_group_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group string.""" + return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_id=keyword_plan_ad_group_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_ad_group_keyword_path( + customer_id: str, + keyword_plan_ad_group_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group_keyword string.""" + return "customers/{customer_id}/keywordPlanAdGroupKeywords/{keyword_plan_ad_group_keyword_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_keyword_id=keyword_plan_ad_group_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroupKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + KeywordPlanAdGroupKeywordServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + KeywordPlanAdGroupKeywordServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + KeywordPlanAdGroupKeywordServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + KeywordPlanAdGroupKeywordServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = KeywordPlanAdGroupKeywordServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + KeywordPlanAdGroupKeywordServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanAdGroupKeywordServiceTransport, + Callable[..., KeywordPlanAdGroupKeywordServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan ad group keyword service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanAdGroupKeywordServiceTransport,Callable[..., KeywordPlanAdGroupKeywordServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanAdGroupKeywordServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = KeywordPlanAdGroupKeywordServiceClient._read_environment_variables() + self._client_cert_source = ( + KeywordPlanAdGroupKeywordServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + KeywordPlanAdGroupKeywordServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, KeywordPlanAdGroupKeywordServiceTransport + ) + if transport_provided: + # transport is a KeywordPlanAdGroupKeywordServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + KeywordPlanAdGroupKeywordServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or KeywordPlanAdGroupKeywordServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[KeywordPlanAdGroupKeywordServiceTransport], + Callable[..., KeywordPlanAdGroupKeywordServiceTransport], + ] = ( + KeywordPlanAdGroupKeywordServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., KeywordPlanAdGroupKeywordServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.KeywordPlanAdGroupKeywordServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService", + "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.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService", + "credentialsType": None, + } + ), + ) + + def mutate_keyword_plan_ad_group_keywords( + self, + request: Optional[ + Union[ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + keyword_plan_ad_group_keyword_service.KeywordPlanAdGroupKeywordOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse + ): + r"""Creates, updates, or removes Keyword Plan ad group keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupKeywordsRequest, dict]): + The request object. Request message for + [KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords][google.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords]. + customer_id (str): + Required. The ID of the customer + whose Keyword Plan ad group keywords are + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanAdGroupKeywordOperation]): + Required. The list of operations to + perform on individual Keyword Plan ad + group keywords. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupKeywordsResponse: + Response message for a Keyword Plan + ad group keyword mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest, + ): + request = keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_keyword_plan_ad_group_keywords + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "KeywordPlanAdGroupKeywordServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("KeywordPlanAdGroupKeywordServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/README.rst b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/README.rst rename to google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_ad_group_keyword_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/base.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/base.py new file mode 100644 index 000000000..d6bcd73ba --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + keyword_plan_ad_group_keyword_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class KeywordPlanAdGroupKeywordServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanAdGroupKeywordService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_keyword_plan_ad_group_keywords: gapic_v1.method.wrap_method( + self.mutate_keyword_plan_ad_group_keywords, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_keyword_plan_ad_group_keywords( + self, + ) -> Callable[ + [ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest + ], + Union[ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse, + Awaitable[ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("KeywordPlanAdGroupKeywordServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/grpc.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/grpc.py new file mode 100644 index 000000000..bd766b763 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/grpc.py @@ -0,0 +1,404 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + keyword_plan_ad_group_keyword_service, +) +from .base import KeywordPlanAdGroupKeywordServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService", + "rpcName": str(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.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanAdGroupKeywordServiceGrpcTransport( + KeywordPlanAdGroupKeywordServiceTransport +): + """gRPC backend transport for KeywordPlanAdGroupKeywordService. + + Service to manage Keyword Plan ad group keywords. + KeywordPlanAdGroup is required to add ad group keywords. + Positive and negative keywords are supported. A maximum of + 10,000 positive keywords are allowed per keyword plan. A maximum + of 1,000 negative keywords are allower per keyword plan. This + includes campaign negative keywords and ad group negative + keywords. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_keyword_plan_ad_group_keywords( + self, + ) -> Callable[ + [ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest + ], + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse, + ]: + r"""Return a callable for the mutate keyword plan ad group + keywords method over gRPC. + + Creates, updates, or removes Keyword Plan ad group keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanAdGroupKeywordsRequest], + ~.MutateKeywordPlanAdGroupKeywordsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_ad_group_keywords" not in self._stubs: + self._stubs["mutate_keyword_plan_ad_group_keywords"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService/MutateKeywordPlanAdGroupKeywords", + request_serializer=keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest.serialize, + response_deserializer=keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse.deserialize, + ) + ) + return self._stubs["mutate_keyword_plan_ad_group_keywords"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("KeywordPlanAdGroupKeywordServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..c4ffe6586 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_keyword_service/transports/grpc_asyncio.py @@ -0,0 +1,427 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + keyword_plan_ad_group_keyword_service, +) +from .base import KeywordPlanAdGroupKeywordServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService", + "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.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanAdGroupKeywordServiceGrpcAsyncIOTransport( + KeywordPlanAdGroupKeywordServiceTransport +): + """gRPC AsyncIO backend transport for KeywordPlanAdGroupKeywordService. + + Service to manage Keyword Plan ad group keywords. + KeywordPlanAdGroup is required to add ad group keywords. + Positive and negative keywords are supported. A maximum of + 10,000 positive keywords are allowed per keyword plan. A maximum + of 1,000 negative keywords are allower per keyword plan. This + includes campaign negative keywords and ad group negative + keywords. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_keyword_plan_ad_group_keywords( + self, + ) -> Callable[ + [ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest + ], + Awaitable[ + keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse + ], + ]: + r"""Return a callable for the mutate keyword plan ad group + keywords method over gRPC. + + Creates, updates, or removes Keyword Plan ad group keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanAdGroupKeywordsRequest], + Awaitable[~.MutateKeywordPlanAdGroupKeywordsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_ad_group_keywords" not in self._stubs: + self._stubs["mutate_keyword_plan_ad_group_keywords"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService/MutateKeywordPlanAdGroupKeywords", + request_serializer=keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsRequest.serialize, + response_deserializer=keyword_plan_ad_group_keyword_service.MutateKeywordPlanAdGroupKeywordsResponse.deserialize, + ) + ) + return self._stubs["mutate_keyword_plan_ad_group_keywords"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_keyword_plan_ad_group_keywords: self._wrap_method( + self.mutate_keyword_plan_ad_group_keywords, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("KeywordPlanAdGroupKeywordServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/async_client.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/async_client.py new file mode 100644 index 000000000..eb9b7d3db --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/async_client.py @@ -0,0 +1,451 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + keyword_plan_ad_group_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanAdGroupServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import KeywordPlanAdGroupServiceClient + +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 KeywordPlanAdGroupServiceAsyncClient: + """Service to manage Keyword Plan ad groups.""" + + _client: KeywordPlanAdGroupServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = KeywordPlanAdGroupServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + KeywordPlanAdGroupServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + KeywordPlanAdGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = KeywordPlanAdGroupServiceClient._DEFAULT_UNIVERSE + + keyword_plan_ad_group_path = staticmethod( + KeywordPlanAdGroupServiceClient.keyword_plan_ad_group_path + ) + parse_keyword_plan_ad_group_path = staticmethod( + KeywordPlanAdGroupServiceClient.parse_keyword_plan_ad_group_path + ) + keyword_plan_campaign_path = staticmethod( + KeywordPlanAdGroupServiceClient.keyword_plan_campaign_path + ) + parse_keyword_plan_campaign_path = staticmethod( + KeywordPlanAdGroupServiceClient.parse_keyword_plan_campaign_path + ) + common_billing_account_path = staticmethod( + KeywordPlanAdGroupServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + KeywordPlanAdGroupServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + KeywordPlanAdGroupServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + KeywordPlanAdGroupServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + KeywordPlanAdGroupServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + KeywordPlanAdGroupServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + KeywordPlanAdGroupServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + KeywordPlanAdGroupServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + KeywordPlanAdGroupServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + KeywordPlanAdGroupServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupServiceAsyncClient: The constructed client. + """ + return KeywordPlanAdGroupServiceClient.from_service_account_info.__func__(KeywordPlanAdGroupServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupServiceAsyncClient: The constructed client. + """ + return KeywordPlanAdGroupServiceClient.from_service_account_file.__func__(KeywordPlanAdGroupServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return KeywordPlanAdGroupServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> KeywordPlanAdGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanAdGroupServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = KeywordPlanAdGroupServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanAdGroupServiceTransport, + Callable[..., KeywordPlanAdGroupServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan ad group service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanAdGroupServiceTransport,Callable[..., KeywordPlanAdGroupServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanAdGroupServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = KeywordPlanAdGroupServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.KeywordPlanAdGroupServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanAdGroupService", + "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.ads.googleads.v23.services.KeywordPlanAdGroupService", + "credentialsType": None, + } + ), + ) + + async def mutate_keyword_plan_ad_groups( + self, + request: Optional[ + Union[ + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + keyword_plan_ad_group_service.KeywordPlanAdGroupOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse: + r"""Creates, updates, or removes Keyword Plan ad groups. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupsRequest, dict]]): + The request object. Request message for + [KeywordPlanAdGroupService.MutateKeywordPlanAdGroups][google.ads.googleads.v23.services.KeywordPlanAdGroupService.MutateKeywordPlanAdGroups]. + customer_id (:class:`str`): + Required. The ID of the customer + whose Keyword Plan ad groups are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanAdGroupOperation]`): + Required. The list of operations to + perform on individual Keyword Plan ad + groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupsResponse: + Response message for a Keyword Plan + ad group mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest, + ): + request = ( + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_keyword_plan_ad_groups + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "KeywordPlanAdGroupServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("KeywordPlanAdGroupServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/client.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/client.py new file mode 100644 index 000000000..438329739 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/client.py @@ -0,0 +1,945 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + keyword_plan_ad_group_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanAdGroupServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordPlanAdGroupServiceGrpcTransport +from .transports.grpc_asyncio import ( + KeywordPlanAdGroupServiceGrpcAsyncIOTransport, +) + + +class KeywordPlanAdGroupServiceClientMeta(type): + """Metaclass for the KeywordPlanAdGroupService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanAdGroupServiceTransport]] + _transport_registry["grpc"] = KeywordPlanAdGroupServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + KeywordPlanAdGroupServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[KeywordPlanAdGroupServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanAdGroupServiceClient( + metaclass=KeywordPlanAdGroupServiceClientMeta +): + """Service to manage Keyword Plan ad groups.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanAdGroupServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanAdGroupServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanAdGroupServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def keyword_plan_ad_group_path( + customer_id: str, + keyword_plan_ad_group_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_ad_group string.""" + return "customers/{customer_id}/keywordPlanAdGroups/{keyword_plan_ad_group_id}".format( + customer_id=customer_id, + keyword_plan_ad_group_id=keyword_plan_ad_group_id, + ) + + @staticmethod + def parse_keyword_plan_ad_group_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanAdGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_path( + customer_id: str, + keyword_plan_campaign_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign string.""" + return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( + customer_id=customer_id, + keyword_plan_campaign_id=keyword_plan_campaign_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + KeywordPlanAdGroupServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + KeywordPlanAdGroupServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + KeywordPlanAdGroupServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = KeywordPlanAdGroupServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = KeywordPlanAdGroupServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = KeywordPlanAdGroupServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanAdGroupServiceTransport, + Callable[..., KeywordPlanAdGroupServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan ad group service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanAdGroupServiceTransport,Callable[..., KeywordPlanAdGroupServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanAdGroupServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = KeywordPlanAdGroupServiceClient._read_environment_variables() + self._client_cert_source = ( + KeywordPlanAdGroupServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + KeywordPlanAdGroupServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, KeywordPlanAdGroupServiceTransport + ) + if transport_provided: + # transport is a KeywordPlanAdGroupServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + KeywordPlanAdGroupServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or KeywordPlanAdGroupServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[KeywordPlanAdGroupServiceTransport], + Callable[..., KeywordPlanAdGroupServiceTransport], + ] = ( + KeywordPlanAdGroupServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., KeywordPlanAdGroupServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.KeywordPlanAdGroupServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanAdGroupService", + "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.ads.googleads.v23.services.KeywordPlanAdGroupService", + "credentialsType": None, + } + ), + ) + + def mutate_keyword_plan_ad_groups( + self, + request: Optional[ + Union[ + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + keyword_plan_ad_group_service.KeywordPlanAdGroupOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse: + r"""Creates, updates, or removes Keyword Plan ad groups. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupsRequest, dict]): + The request object. Request message for + [KeywordPlanAdGroupService.MutateKeywordPlanAdGroups][google.ads.googleads.v23.services.KeywordPlanAdGroupService.MutateKeywordPlanAdGroups]. + customer_id (str): + Required. The ID of the customer + whose Keyword Plan ad groups are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanAdGroupOperation]): + Required. The list of operations to + perform on individual Keyword Plan ad + groups. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupsResponse: + Response message for a Keyword Plan + ad group mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest, + ): + request = ( + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_keyword_plan_ad_groups + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "KeywordPlanAdGroupServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("KeywordPlanAdGroupServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/README.rst b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/README.rst rename to google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_ad_group_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/base.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/base.py new file mode 100644 index 000000000..b532681ea --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + keyword_plan_ad_group_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class KeywordPlanAdGroupServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanAdGroupService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_keyword_plan_ad_groups: gapic_v1.method.wrap_method( + self.mutate_keyword_plan_ad_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_keyword_plan_ad_groups( + self, + ) -> Callable[ + [keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest], + Union[ + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse, + Awaitable[ + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("KeywordPlanAdGroupServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/grpc.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/grpc.py new file mode 100644 index 000000000..95d58f522 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/grpc.py @@ -0,0 +1,396 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + keyword_plan_ad_group_service, +) +from .base import KeywordPlanAdGroupServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.KeywordPlanAdGroupService", + "rpcName": str(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.ads.googleads.v23.services.KeywordPlanAdGroupService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanAdGroupServiceGrpcTransport( + KeywordPlanAdGroupServiceTransport +): + """gRPC backend transport for KeywordPlanAdGroupService. + + Service to manage Keyword Plan ad groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_keyword_plan_ad_groups( + self, + ) -> Callable[ + [keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest], + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse, + ]: + r"""Return a callable for the mutate keyword plan ad groups method over gRPC. + + Creates, updates, or removes Keyword Plan ad groups. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanAdGroupsRequest], + ~.MutateKeywordPlanAdGroupsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_ad_groups" not in self._stubs: + self._stubs["mutate_keyword_plan_ad_groups"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanAdGroupService/MutateKeywordPlanAdGroups", + request_serializer=keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest.serialize, + response_deserializer=keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse.deserialize, + ) + ) + return self._stubs["mutate_keyword_plan_ad_groups"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("KeywordPlanAdGroupServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..60dbf5f84 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_ad_group_service/transports/grpc_asyncio.py @@ -0,0 +1,419 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + keyword_plan_ad_group_service, +) +from .base import KeywordPlanAdGroupServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.KeywordPlanAdGroupService", + "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.ads.googleads.v23.services.KeywordPlanAdGroupService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanAdGroupServiceGrpcAsyncIOTransport( + KeywordPlanAdGroupServiceTransport +): + """gRPC AsyncIO backend transport for KeywordPlanAdGroupService. + + Service to manage Keyword Plan ad groups. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_keyword_plan_ad_groups( + self, + ) -> Callable[ + [keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest], + Awaitable[ + keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse + ], + ]: + r"""Return a callable for the mutate keyword plan ad groups method over gRPC. + + Creates, updates, or removes Keyword Plan ad groups. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanAdGroupsRequest], + Awaitable[~.MutateKeywordPlanAdGroupsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_ad_groups" not in self._stubs: + self._stubs["mutate_keyword_plan_ad_groups"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanAdGroupService/MutateKeywordPlanAdGroups", + request_serializer=keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsRequest.serialize, + response_deserializer=keyword_plan_ad_group_service.MutateKeywordPlanAdGroupsResponse.deserialize, + ) + ) + return self._stubs["mutate_keyword_plan_ad_groups"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_keyword_plan_ad_groups: self._wrap_method( + self.mutate_keyword_plan_ad_groups, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("KeywordPlanAdGroupServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/async_client.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/async_client.py new file mode 100644 index 000000000..9b05b8b7d --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/async_client.py @@ -0,0 +1,461 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + keyword_plan_campaign_keyword_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanCampaignKeywordServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import KeywordPlanCampaignKeywordServiceClient + +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 KeywordPlanCampaignKeywordServiceAsyncClient: + """Service to manage Keyword Plan campaign keywords. + KeywordPlanCampaign is required to add the campaign keywords. + Only negative keywords are supported. A maximum of 1000 negative + keywords are allowed per plan. This includes both campaign + negative keywords and ad group negative keywords. + """ + + _client: KeywordPlanCampaignKeywordServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = KeywordPlanCampaignKeywordServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + KeywordPlanCampaignKeywordServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + KeywordPlanCampaignKeywordServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ( + KeywordPlanCampaignKeywordServiceClient._DEFAULT_UNIVERSE + ) + + keyword_plan_campaign_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.keyword_plan_campaign_path + ) + parse_keyword_plan_campaign_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.parse_keyword_plan_campaign_path + ) + keyword_plan_campaign_keyword_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.keyword_plan_campaign_keyword_path + ) + parse_keyword_plan_campaign_keyword_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.parse_keyword_plan_campaign_keyword_path + ) + common_billing_account_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + KeywordPlanCampaignKeywordServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignKeywordServiceAsyncClient: The constructed client. + """ + return KeywordPlanCampaignKeywordServiceClient.from_service_account_info.__func__(KeywordPlanCampaignKeywordServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignKeywordServiceAsyncClient: The constructed client. + """ + return KeywordPlanCampaignKeywordServiceClient.from_service_account_file.__func__(KeywordPlanCampaignKeywordServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return KeywordPlanCampaignKeywordServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> KeywordPlanCampaignKeywordServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanCampaignKeywordServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + KeywordPlanCampaignKeywordServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanCampaignKeywordServiceTransport, + Callable[..., KeywordPlanCampaignKeywordServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan campaign keyword service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanCampaignKeywordServiceTransport,Callable[..., KeywordPlanCampaignKeywordServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanCampaignKeywordServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = KeywordPlanCampaignKeywordServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.KeywordPlanCampaignKeywordServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanCampaignKeywordService", + "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.ads.googleads.v23.services.KeywordPlanCampaignKeywordService", + "credentialsType": None, + } + ), + ) + + async def mutate_keyword_plan_campaign_keywords( + self, + request: Optional[ + Union[ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + keyword_plan_campaign_keyword_service.KeywordPlanCampaignKeywordOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse + ): + r"""Creates, updates, or removes Keyword Plan campaign keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignKeywordError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateKeywordPlanCampaignKeywordsRequest, dict]]): + The request object. Request message for + [KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords][google.ads.googleads.v23.services.KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords]. + customer_id (:class:`str`): + Required. The ID of the customer + whose campaign keywords are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanCampaignKeywordOperation]`): + Required. The list of operations to + perform on individual Keyword Plan + campaign keywords. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateKeywordPlanCampaignKeywordsResponse: + Response message for a Keyword Plan + campaign keyword mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest, + ): + request = keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_keyword_plan_campaign_keywords + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__( + self, + ) -> "KeywordPlanCampaignKeywordServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("KeywordPlanCampaignKeywordServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/client.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/client.py new file mode 100644 index 000000000..9628ecec6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/client.py @@ -0,0 +1,958 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + keyword_plan_campaign_keyword_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanCampaignKeywordServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordPlanCampaignKeywordServiceGrpcTransport +from .transports.grpc_asyncio import ( + KeywordPlanCampaignKeywordServiceGrpcAsyncIOTransport, +) + + +class KeywordPlanCampaignKeywordServiceClientMeta(type): + """Metaclass for the KeywordPlanCampaignKeywordService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanCampaignKeywordServiceTransport]] + _transport_registry["grpc"] = KeywordPlanCampaignKeywordServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + KeywordPlanCampaignKeywordServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[KeywordPlanCampaignKeywordServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanCampaignKeywordServiceClient( + metaclass=KeywordPlanCampaignKeywordServiceClientMeta +): + """Service to manage Keyword Plan campaign keywords. + KeywordPlanCampaign is required to add the campaign keywords. + Only negative keywords are supported. A maximum of 1000 negative + keywords are allowed per plan. This includes both campaign + negative keywords and ad group negative keywords. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignKeywordServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignKeywordServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanCampaignKeywordServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanCampaignKeywordServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def keyword_plan_campaign_path( + customer_id: str, + keyword_plan_campaign_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign string.""" + return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( + customer_id=customer_id, + keyword_plan_campaign_id=keyword_plan_campaign_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_keyword_path( + customer_id: str, + keyword_plan_campaign_keyword_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign_keyword string.""" + return "customers/{customer_id}/keywordPlanCampaignKeywords/{keyword_plan_campaign_keyword_id}".format( + customer_id=customer_id, + keyword_plan_campaign_keyword_id=keyword_plan_campaign_keyword_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_keyword_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign_keyword path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaignKeywords/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + KeywordPlanCampaignKeywordServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + KeywordPlanCampaignKeywordServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + KeywordPlanCampaignKeywordServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + KeywordPlanCampaignKeywordServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = KeywordPlanCampaignKeywordServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + KeywordPlanCampaignKeywordServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanCampaignKeywordServiceTransport, + Callable[..., KeywordPlanCampaignKeywordServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan campaign keyword service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanCampaignKeywordServiceTransport,Callable[..., KeywordPlanCampaignKeywordServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanCampaignKeywordServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ( + KeywordPlanCampaignKeywordServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + KeywordPlanCampaignKeywordServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + KeywordPlanCampaignKeywordServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, KeywordPlanCampaignKeywordServiceTransport + ) + if transport_provided: + # transport is a KeywordPlanCampaignKeywordServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + KeywordPlanCampaignKeywordServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or KeywordPlanCampaignKeywordServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[KeywordPlanCampaignKeywordServiceTransport], + Callable[..., KeywordPlanCampaignKeywordServiceTransport], + ] = ( + KeywordPlanCampaignKeywordServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., KeywordPlanCampaignKeywordServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.KeywordPlanCampaignKeywordServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanCampaignKeywordService", + "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.ads.googleads.v23.services.KeywordPlanCampaignKeywordService", + "credentialsType": None, + } + ), + ) + + def mutate_keyword_plan_campaign_keywords( + self, + request: Optional[ + Union[ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + keyword_plan_campaign_keyword_service.KeywordPlanCampaignKeywordOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse + ): + r"""Creates, updates, or removes Keyword Plan campaign keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignKeywordError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateKeywordPlanCampaignKeywordsRequest, dict]): + The request object. Request message for + [KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords][google.ads.googleads.v23.services.KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords]. + customer_id (str): + Required. The ID of the customer + whose campaign keywords are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanCampaignKeywordOperation]): + Required. The list of operations to + perform on individual Keyword Plan + campaign keywords. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateKeywordPlanCampaignKeywordsResponse: + Response message for a Keyword Plan + campaign keyword mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest, + ): + request = keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_keyword_plan_campaign_keywords + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "KeywordPlanCampaignKeywordServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("KeywordPlanCampaignKeywordServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/README.rst b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/README.rst rename to google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_campaign_keyword_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/base.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/base.py new file mode 100644 index 000000000..b5bf31625 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + keyword_plan_campaign_keyword_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class KeywordPlanCampaignKeywordServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanCampaignKeywordService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_keyword_plan_campaign_keywords: gapic_v1.method.wrap_method( + self.mutate_keyword_plan_campaign_keywords, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_keyword_plan_campaign_keywords( + self, + ) -> Callable[ + [ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest + ], + Union[ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse, + Awaitable[ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("KeywordPlanCampaignKeywordServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/grpc.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/grpc.py new file mode 100644 index 000000000..3f7d5f87b --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/grpc.py @@ -0,0 +1,405 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + keyword_plan_campaign_keyword_service, +) +from .base import ( + KeywordPlanCampaignKeywordServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.KeywordPlanCampaignKeywordService", + "rpcName": str(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.ads.googleads.v23.services.KeywordPlanCampaignKeywordService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanCampaignKeywordServiceGrpcTransport( + KeywordPlanCampaignKeywordServiceTransport +): + """gRPC backend transport for KeywordPlanCampaignKeywordService. + + Service to manage Keyword Plan campaign keywords. + KeywordPlanCampaign is required to add the campaign keywords. + Only negative keywords are supported. A maximum of 1000 negative + keywords are allowed per plan. This includes both campaign + negative keywords and ad group negative keywords. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_keyword_plan_campaign_keywords( + self, + ) -> Callable[ + [ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest + ], + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse, + ]: + r"""Return a callable for the mutate keyword plan campaign + keywords method over gRPC. + + Creates, updates, or removes Keyword Plan campaign keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignKeywordError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanCampaignKeywordsRequest], + ~.MutateKeywordPlanCampaignKeywordsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_campaign_keywords" not in self._stubs: + self._stubs["mutate_keyword_plan_campaign_keywords"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanCampaignKeywordService/MutateKeywordPlanCampaignKeywords", + request_serializer=keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest.serialize, + response_deserializer=keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse.deserialize, + ) + ) + return self._stubs["mutate_keyword_plan_campaign_keywords"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("KeywordPlanCampaignKeywordServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..64a6c5141 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_campaign_keyword_service/transports/grpc_asyncio.py @@ -0,0 +1,428 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + keyword_plan_campaign_keyword_service, +) +from .base import ( + KeywordPlanCampaignKeywordServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.KeywordPlanCampaignKeywordService", + "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.ads.googleads.v23.services.KeywordPlanCampaignKeywordService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanCampaignKeywordServiceGrpcAsyncIOTransport( + KeywordPlanCampaignKeywordServiceTransport +): + """gRPC AsyncIO backend transport for KeywordPlanCampaignKeywordService. + + Service to manage Keyword Plan campaign keywords. + KeywordPlanCampaign is required to add the campaign keywords. + Only negative keywords are supported. A maximum of 1000 negative + keywords are allowed per plan. This includes both campaign + negative keywords and ad group negative keywords. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_keyword_plan_campaign_keywords( + self, + ) -> Callable[ + [ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest + ], + Awaitable[ + keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse + ], + ]: + r"""Return a callable for the mutate keyword plan campaign + keywords method over gRPC. + + Creates, updates, or removes Keyword Plan campaign keywords. + Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanAdGroupKeywordError <>`__ + `KeywordPlanCampaignKeywordError <>`__ `QuotaError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanCampaignKeywordsRequest], + Awaitable[~.MutateKeywordPlanCampaignKeywordsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_campaign_keywords" not in self._stubs: + self._stubs["mutate_keyword_plan_campaign_keywords"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanCampaignKeywordService/MutateKeywordPlanCampaignKeywords", + request_serializer=keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsRequest.serialize, + response_deserializer=keyword_plan_campaign_keyword_service.MutateKeywordPlanCampaignKeywordsResponse.deserialize, + ) + ) + return self._stubs["mutate_keyword_plan_campaign_keywords"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_keyword_plan_campaign_keywords: self._wrap_method( + self.mutate_keyword_plan_campaign_keywords, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("KeywordPlanCampaignKeywordServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_campaign_service/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_campaign_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/async_client.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/async_client.py new file mode 100644 index 000000000..d6eabd93e --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/async_client.py @@ -0,0 +1,463 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + keyword_plan_campaign_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanCampaignServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import KeywordPlanCampaignServiceClient + +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 KeywordPlanCampaignServiceAsyncClient: + """Service to manage Keyword Plan campaigns.""" + + _client: KeywordPlanCampaignServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = KeywordPlanCampaignServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + KeywordPlanCampaignServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + KeywordPlanCampaignServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = KeywordPlanCampaignServiceClient._DEFAULT_UNIVERSE + + geo_target_constant_path = staticmethod( + KeywordPlanCampaignServiceClient.geo_target_constant_path + ) + parse_geo_target_constant_path = staticmethod( + KeywordPlanCampaignServiceClient.parse_geo_target_constant_path + ) + keyword_plan_path = staticmethod( + KeywordPlanCampaignServiceClient.keyword_plan_path + ) + parse_keyword_plan_path = staticmethod( + KeywordPlanCampaignServiceClient.parse_keyword_plan_path + ) + keyword_plan_campaign_path = staticmethod( + KeywordPlanCampaignServiceClient.keyword_plan_campaign_path + ) + parse_keyword_plan_campaign_path = staticmethod( + KeywordPlanCampaignServiceClient.parse_keyword_plan_campaign_path + ) + language_constant_path = staticmethod( + KeywordPlanCampaignServiceClient.language_constant_path + ) + parse_language_constant_path = staticmethod( + KeywordPlanCampaignServiceClient.parse_language_constant_path + ) + common_billing_account_path = staticmethod( + KeywordPlanCampaignServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + KeywordPlanCampaignServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + KeywordPlanCampaignServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + KeywordPlanCampaignServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + KeywordPlanCampaignServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + KeywordPlanCampaignServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + KeywordPlanCampaignServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + KeywordPlanCampaignServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + KeywordPlanCampaignServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + KeywordPlanCampaignServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignServiceAsyncClient: The constructed client. + """ + return KeywordPlanCampaignServiceClient.from_service_account_info.__func__(KeywordPlanCampaignServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignServiceAsyncClient: The constructed client. + """ + return KeywordPlanCampaignServiceClient.from_service_account_file.__func__(KeywordPlanCampaignServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return KeywordPlanCampaignServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> KeywordPlanCampaignServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanCampaignServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = KeywordPlanCampaignServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanCampaignServiceTransport, + Callable[..., KeywordPlanCampaignServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan campaign service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanCampaignServiceTransport,Callable[..., KeywordPlanCampaignServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanCampaignServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = KeywordPlanCampaignServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.KeywordPlanCampaignServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanCampaignService", + "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.ads.googleads.v23.services.KeywordPlanCampaignService", + "credentialsType": None, + } + ), + ) + + async def mutate_keyword_plan_campaigns( + self, + request: Optional[ + Union[ + keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + keyword_plan_campaign_service.KeywordPlanCampaignOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse: + r"""Creates, updates, or removes Keyword Plan campaigns. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `ListOperationError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateKeywordPlanCampaignsRequest, dict]]): + The request object. Request message for + [KeywordPlanCampaignService.MutateKeywordPlanCampaigns][google.ads.googleads.v23.services.KeywordPlanCampaignService.MutateKeywordPlanCampaigns]. + customer_id (:class:`str`): + Required. The ID of the customer + whose Keyword Plan campaigns are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanCampaignOperation]`): + Required. The list of operations to + perform on individual Keyword Plan + campaigns. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateKeywordPlanCampaignsResponse: + Response message for a Keyword Plan + campaign mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest, + ): + request = ( + keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_keyword_plan_campaigns + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "KeywordPlanCampaignServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("KeywordPlanCampaignServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/client.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/client.py new file mode 100644 index 000000000..0e342a65f --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/client.py @@ -0,0 +1,978 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + keyword_plan_campaign_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + KeywordPlanCampaignServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordPlanCampaignServiceGrpcTransport +from .transports.grpc_asyncio import ( + KeywordPlanCampaignServiceGrpcAsyncIOTransport, +) + + +class KeywordPlanCampaignServiceClientMeta(type): + """Metaclass for the KeywordPlanCampaignService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanCampaignServiceTransport]] + _transport_registry["grpc"] = KeywordPlanCampaignServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + KeywordPlanCampaignServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[KeywordPlanCampaignServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanCampaignServiceClient( + metaclass=KeywordPlanCampaignServiceClientMeta +): + """Service to manage Keyword Plan campaigns.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanCampaignServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanCampaignServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanCampaignServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def geo_target_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified geo_target_constant string.""" + return "geoTargetConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_geo_target_constant_path(path: str) -> Dict[str, str]: + """Parses a geo_target_constant path into its component segments.""" + m = re.match(r"^geoTargetConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_path( + customer_id: str, + keyword_plan_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan string.""" + return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( + customer_id=customer_id, + keyword_plan_id=keyword_plan_id, + ) + + @staticmethod + def parse_keyword_plan_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_plan_campaign_path( + customer_id: str, + keyword_plan_campaign_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan_campaign string.""" + return "customers/{customer_id}/keywordPlanCampaigns/{keyword_plan_campaign_id}".format( + customer_id=customer_id, + keyword_plan_campaign_id=keyword_plan_campaign_id, + ) + + @staticmethod + def parse_keyword_plan_campaign_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan_campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlanCampaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def language_constant_path( + criterion_id: str, + ) -> str: + """Returns a fully-qualified language_constant string.""" + return "languageConstants/{criterion_id}".format( + criterion_id=criterion_id, + ) + + @staticmethod + def parse_language_constant_path(path: str) -> Dict[str, str]: + """Parses a language_constant path into its component segments.""" + m = re.match(r"^languageConstants/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + KeywordPlanCampaignServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + KeywordPlanCampaignServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + KeywordPlanCampaignServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + KeywordPlanCampaignServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = KeywordPlanCampaignServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = KeywordPlanCampaignServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanCampaignServiceTransport, + Callable[..., KeywordPlanCampaignServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan campaign service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanCampaignServiceTransport,Callable[..., KeywordPlanCampaignServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanCampaignServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = KeywordPlanCampaignServiceClient._read_environment_variables() + self._client_cert_source = ( + KeywordPlanCampaignServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + KeywordPlanCampaignServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, KeywordPlanCampaignServiceTransport + ) + if transport_provided: + # transport is a KeywordPlanCampaignServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + KeywordPlanCampaignServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or KeywordPlanCampaignServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[KeywordPlanCampaignServiceTransport], + Callable[..., KeywordPlanCampaignServiceTransport], + ] = ( + KeywordPlanCampaignServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., KeywordPlanCampaignServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.KeywordPlanCampaignServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanCampaignService", + "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.ads.googleads.v23.services.KeywordPlanCampaignService", + "credentialsType": None, + } + ), + ) + + def mutate_keyword_plan_campaigns( + self, + request: Optional[ + Union[ + keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + keyword_plan_campaign_service.KeywordPlanCampaignOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse: + r"""Creates, updates, or removes Keyword Plan campaigns. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `ListOperationError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateKeywordPlanCampaignsRequest, dict]): + The request object. Request message for + [KeywordPlanCampaignService.MutateKeywordPlanCampaigns][google.ads.googleads.v23.services.KeywordPlanCampaignService.MutateKeywordPlanCampaigns]. + customer_id (str): + Required. The ID of the customer + whose Keyword Plan campaigns are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanCampaignOperation]): + Required. The list of operations to + perform on individual Keyword Plan + campaigns. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateKeywordPlanCampaignsResponse: + Response message for a Keyword Plan + campaign mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest, + ): + request = ( + keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_keyword_plan_campaigns + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "KeywordPlanCampaignServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("KeywordPlanCampaignServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/README.rst b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/README.rst rename to google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_campaign_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/base.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/base.py new file mode 100644 index 000000000..c56608713 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + keyword_plan_campaign_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class KeywordPlanCampaignServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanCampaignService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_keyword_plan_campaigns: gapic_v1.method.wrap_method( + self.mutate_keyword_plan_campaigns, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_keyword_plan_campaigns( + self, + ) -> Callable[ + [keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest], + Union[ + keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse, + Awaitable[ + keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("KeywordPlanCampaignServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/grpc.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/grpc.py new file mode 100644 index 000000000..f022f51bc --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/grpc.py @@ -0,0 +1,396 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + keyword_plan_campaign_service, +) +from .base import KeywordPlanCampaignServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.KeywordPlanCampaignService", + "rpcName": str(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.ads.googleads.v23.services.KeywordPlanCampaignService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanCampaignServiceGrpcTransport( + KeywordPlanCampaignServiceTransport +): + """gRPC backend transport for KeywordPlanCampaignService. + + Service to manage Keyword Plan campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_keyword_plan_campaigns( + self, + ) -> Callable[ + [keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest], + keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse, + ]: + r"""Return a callable for the mutate keyword plan campaigns method over gRPC. + + Creates, updates, or removes Keyword Plan campaigns. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `ListOperationError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanCampaignsRequest], + ~.MutateKeywordPlanCampaignsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_campaigns" not in self._stubs: + self._stubs["mutate_keyword_plan_campaigns"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanCampaignService/MutateKeywordPlanCampaigns", + request_serializer=keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest.serialize, + response_deserializer=keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse.deserialize, + ) + ) + return self._stubs["mutate_keyword_plan_campaigns"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("KeywordPlanCampaignServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..3a1516fe1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_campaign_service/transports/grpc_asyncio.py @@ -0,0 +1,419 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + keyword_plan_campaign_service, +) +from .base import KeywordPlanCampaignServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.KeywordPlanCampaignService", + "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.ads.googleads.v23.services.KeywordPlanCampaignService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanCampaignServiceGrpcAsyncIOTransport( + KeywordPlanCampaignServiceTransport +): + """gRPC AsyncIO backend transport for KeywordPlanCampaignService. + + Service to manage Keyword Plan campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_keyword_plan_campaigns( + self, + ) -> Callable[ + [keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest], + Awaitable[ + keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse + ], + ]: + r"""Return a callable for the mutate keyword plan campaigns method over gRPC. + + Creates, updates, or removes Keyword Plan campaigns. Operation + statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanCampaignError <>`__ `KeywordPlanError <>`__ + `ListOperationError <>`__ `MutateError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ + + Returns: + Callable[[~.MutateKeywordPlanCampaignsRequest], + Awaitable[~.MutateKeywordPlanCampaignsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plan_campaigns" not in self._stubs: + self._stubs["mutate_keyword_plan_campaigns"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanCampaignService/MutateKeywordPlanCampaigns", + request_serializer=keyword_plan_campaign_service.MutateKeywordPlanCampaignsRequest.serialize, + response_deserializer=keyword_plan_campaign_service.MutateKeywordPlanCampaignsResponse.deserialize, + ) + ) + return self._stubs["mutate_keyword_plan_campaigns"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_keyword_plan_campaigns: self._wrap_method( + self.mutate_keyword_plan_campaigns, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("KeywordPlanCampaignServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_idea_service/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_idea_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_idea_service/async_client.py b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/async_client.py new file mode 100644 index 000000000..402e9f70e --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/async_client.py @@ -0,0 +1,701 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.services.keyword_plan_idea_service import ( + pagers, +) +from google.ads.googleads.v23.services.types import keyword_plan_idea_service +from .transports.base import ( + KeywordPlanIdeaServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import KeywordPlanIdeaServiceClient + +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 KeywordPlanIdeaServiceAsyncClient: + """Service to generate keyword ideas.""" + + _client: KeywordPlanIdeaServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = KeywordPlanIdeaServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = KeywordPlanIdeaServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + KeywordPlanIdeaServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = KeywordPlanIdeaServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod( + KeywordPlanIdeaServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + KeywordPlanIdeaServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + KeywordPlanIdeaServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + KeywordPlanIdeaServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + KeywordPlanIdeaServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + KeywordPlanIdeaServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + KeywordPlanIdeaServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + KeywordPlanIdeaServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + KeywordPlanIdeaServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + KeywordPlanIdeaServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanIdeaServiceAsyncClient: The constructed client. + """ + return KeywordPlanIdeaServiceClient.from_service_account_info.__func__(KeywordPlanIdeaServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanIdeaServiceAsyncClient: The constructed client. + """ + return KeywordPlanIdeaServiceClient.from_service_account_file.__func__(KeywordPlanIdeaServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return KeywordPlanIdeaServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> KeywordPlanIdeaServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanIdeaServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = KeywordPlanIdeaServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanIdeaServiceTransport, + Callable[..., KeywordPlanIdeaServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan idea service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanIdeaServiceTransport,Callable[..., KeywordPlanIdeaServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanIdeaServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = KeywordPlanIdeaServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.KeywordPlanIdeaServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanIdeaService", + "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.ads.googleads.v23.services.KeywordPlanIdeaService", + "credentialsType": None, + } + ), + ) + + async def generate_keyword_ideas( + self, + request: Optional[ + Union[keyword_plan_idea_service.GenerateKeywordIdeasRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.GenerateKeywordIdeasAsyncPager: + r"""Returns a list of keyword ideas. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanIdeaError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateKeywordIdeasRequest, dict]]): + The request object. Request message for + [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.keyword_plan_idea_service.pagers.GenerateKeywordIdeasAsyncPager: + Response message for + [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, keyword_plan_idea_service.GenerateKeywordIdeasRequest + ): + request = keyword_plan_idea_service.GenerateKeywordIdeasRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_keyword_ideas + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.GenerateKeywordIdeasAsyncPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_keyword_historical_metrics( + self, + request: Optional[ + Union[ + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse: + r"""Returns a list of keyword historical metrics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateKeywordHistoricalMetricsRequest, dict]]): + The request object. Request message for + [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateKeywordHistoricalMetricsResponse: + Response message for + [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest, + ): + request = keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_keyword_historical_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_ad_group_themes( + self, + request: Optional[ + Union[keyword_plan_idea_service.GenerateAdGroupThemesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + keywords: Optional[MutableSequence[str]] = None, + ad_groups: Optional[MutableSequence[str]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_idea_service.GenerateAdGroupThemesResponse: + r"""Returns a list of suggested AdGroups and suggested modifications + (text, match type) for the given keywords. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateAdGroupThemesRequest, dict]]): + The request object. Request message for + [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + keywords (:class:`MutableSequence[str]`): + Required. A list of keywords to group + into the provided AdGroups. + + This corresponds to the ``keywords`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + ad_groups (:class:`MutableSequence[str]`): + Required. A list of resource names of AdGroups to group + keywords into. Resource name format: + ``customers/{customer_id}/adGroups/{ad_group_id}`` + + This corresponds to the ``ad_groups`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateAdGroupThemesResponse: + Response message for + [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, keywords, ad_groups] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, keyword_plan_idea_service.GenerateAdGroupThemesRequest + ): + request = keyword_plan_idea_service.GenerateAdGroupThemesRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if keywords: + request.keywords.extend(keywords) + if ad_groups: + request.ad_groups.extend(ad_groups) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_ad_group_themes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_keyword_forecast_metrics( + self, + request: Optional[ + Union[ + keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest, + dict, + ] + ] = None, + *, + campaign: Optional[keyword_plan_idea_service.CampaignToForecast] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse: + r"""Returns metrics (such as impressions, clicks, total cost) of a + keyword forecast for the given campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateKeywordForecastMetricsRequest, dict]]): + The request object. Request message for + [KeywordPlanIdeaService.GenerateKeywordForecastMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. + campaign (:class:`google.ads.googleads.v23.services.types.CampaignToForecast`): + Required. The campaign used in the + forecast. + + This corresponds to the ``campaign`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateKeywordForecastMetricsResponse: + Response message for + [KeywordPlanIdeaService.GenerateKeywordForecastMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [campaign] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest, + ): + request = ( + keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if campaign is not None: + request.campaign = campaign + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_keyword_forecast_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "KeywordPlanIdeaServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("KeywordPlanIdeaServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_idea_service/client.py b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/client.py new file mode 100644 index 000000000..b620f60e5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/client.py @@ -0,0 +1,1162 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.services.keyword_plan_idea_service import ( + pagers, +) +from google.ads.googleads.v23.services.types import keyword_plan_idea_service +from .transports.base import ( + KeywordPlanIdeaServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordPlanIdeaServiceGrpcTransport +from .transports.grpc_asyncio import KeywordPlanIdeaServiceGrpcAsyncIOTransport + + +class KeywordPlanIdeaServiceClientMeta(type): + """Metaclass for the KeywordPlanIdeaService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanIdeaServiceTransport]] + _transport_registry["grpc"] = KeywordPlanIdeaServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + KeywordPlanIdeaServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[KeywordPlanIdeaServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanIdeaServiceClient(metaclass=KeywordPlanIdeaServiceClientMeta): + """Service to generate keyword ideas.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanIdeaServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanIdeaServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanIdeaServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanIdeaServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + KeywordPlanIdeaServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + KeywordPlanIdeaServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = KeywordPlanIdeaServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = KeywordPlanIdeaServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + KeywordPlanIdeaServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = KeywordPlanIdeaServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanIdeaServiceTransport, + Callable[..., KeywordPlanIdeaServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan idea service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanIdeaServiceTransport,Callable[..., KeywordPlanIdeaServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanIdeaServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = KeywordPlanIdeaServiceClient._read_environment_variables() + self._client_cert_source = ( + KeywordPlanIdeaServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + KeywordPlanIdeaServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, KeywordPlanIdeaServiceTransport + ) + if transport_provided: + # transport is a KeywordPlanIdeaServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(KeywordPlanIdeaServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or KeywordPlanIdeaServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[KeywordPlanIdeaServiceTransport], + Callable[..., KeywordPlanIdeaServiceTransport], + ] = ( + KeywordPlanIdeaServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., KeywordPlanIdeaServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.KeywordPlanIdeaServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanIdeaService", + "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.ads.googleads.v23.services.KeywordPlanIdeaService", + "credentialsType": None, + } + ), + ) + + def generate_keyword_ideas( + self, + request: Optional[ + Union[keyword_plan_idea_service.GenerateKeywordIdeasRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> pagers.GenerateKeywordIdeasPager: + r"""Returns a list of keyword ideas. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanIdeaError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateKeywordIdeasRequest, dict]): + The request object. Request message for + [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.services.keyword_plan_idea_service.pagers.GenerateKeywordIdeasPager: + Response message for + [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, keyword_plan_idea_service.GenerateKeywordIdeasRequest + ): + request = keyword_plan_idea_service.GenerateKeywordIdeasRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_keyword_ideas + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__iter__` convenience method. + response = pagers.GenerateKeywordIdeasPager( + method=rpc, + request=request, + response=response, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_keyword_historical_metrics( + self, + request: Optional[ + Union[ + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse: + r"""Returns a list of keyword historical metrics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateKeywordHistoricalMetricsRequest, dict]): + The request object. Request message for + [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateKeywordHistoricalMetricsResponse: + Response message for + [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest, + ): + request = keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_keyword_historical_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_ad_group_themes( + self, + request: Optional[ + Union[keyword_plan_idea_service.GenerateAdGroupThemesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + keywords: Optional[MutableSequence[str]] = None, + ad_groups: Optional[MutableSequence[str]] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_idea_service.GenerateAdGroupThemesResponse: + r"""Returns a list of suggested AdGroups and suggested modifications + (text, match type) for the given keywords. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateAdGroupThemesRequest, dict]): + The request object. Request message for + [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + keywords (MutableSequence[str]): + Required. A list of keywords to group + into the provided AdGroups. + + This corresponds to the ``keywords`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + ad_groups (MutableSequence[str]): + Required. A list of resource names of AdGroups to group + keywords into. Resource name format: + ``customers/{customer_id}/adGroups/{ad_group_id}`` + + This corresponds to the ``ad_groups`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateAdGroupThemesResponse: + Response message for + [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, keywords, ad_groups] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, keyword_plan_idea_service.GenerateAdGroupThemesRequest + ): + request = keyword_plan_idea_service.GenerateAdGroupThemesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if keywords is not None: + request.keywords = keywords + if ad_groups is not None: + request.ad_groups = ad_groups + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_ad_group_themes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_keyword_forecast_metrics( + self, + request: Optional[ + Union[ + keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest, + dict, + ] + ] = None, + *, + campaign: Optional[keyword_plan_idea_service.CampaignToForecast] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse: + r"""Returns metrics (such as impressions, clicks, total cost) of a + keyword forecast for the given campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateKeywordForecastMetricsRequest, dict]): + The request object. Request message for + [KeywordPlanIdeaService.GenerateKeywordForecastMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. + campaign (google.ads.googleads.v23.services.types.CampaignToForecast): + Required. The campaign used in the + forecast. + + This corresponds to the ``campaign`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateKeywordForecastMetricsResponse: + Response message for + [KeywordPlanIdeaService.GenerateKeywordForecastMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [campaign] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest, + ): + request = ( + keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if campaign is not None: + request.campaign = campaign + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_keyword_forecast_metrics + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "KeywordPlanIdeaServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("KeywordPlanIdeaServiceClient",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_idea_service/pagers.py b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/pagers.py new file mode 100644 index 000000000..3eb82824b --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/pagers.py @@ -0,0 +1,212 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.api_core import retry_async as retries_async +from typing import ( + Any, + AsyncIterator, + Awaitable, + Callable, + Sequence, + Tuple, + Iterator, + Union, +) + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] + OptionalAsyncRetry = Union[ + retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.Retry, object, None] # type: ignore + OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import keyword_plan_idea_service + + +class GenerateKeywordIdeasPager: + """A pager for iterating through ``generate_keyword_ideas`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.GenerateKeywordIdeaResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``GenerateKeywordIdeas`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.GenerateKeywordIdeaResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., keyword_plan_idea_service.GenerateKeywordIdeaResponse + ], + request: keyword_plan_idea_service.GenerateKeywordIdeasRequest, + response: keyword_plan_idea_service.GenerateKeywordIdeaResponse, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.GenerateKeywordIdeasRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.GenerateKeywordIdeaResponse): + The initial response object. + retry (google.api_core.retry.Retry): Designation of what errors, + if any, should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = keyword_plan_idea_service.GenerateKeywordIdeasRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages( + self, + ) -> Iterator[keyword_plan_idea_service.GenerateKeywordIdeaResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __iter__( + self, + ) -> Iterator[keyword_plan_idea_service.GenerateKeywordIdeaResult]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class GenerateKeywordIdeasAsyncPager: + """A pager for iterating through ``generate_keyword_ideas`` requests. + + This class thinly wraps an initial + :class:`google.ads.googleads.v23.services.types.GenerateKeywordIdeaResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``GenerateKeywordIdeas`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.ads.googleads.v23.services.types.GenerateKeywordIdeaResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + ..., + Awaitable[keyword_plan_idea_service.GenerateKeywordIdeaResponse], + ], + request: keyword_plan_idea_service.GenerateKeywordIdeasRequest, + response: keyword_plan_idea_service.GenerateKeywordIdeaResponse, + *, + retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ): + """Instantiates the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (google.ads.googleads.v23.services.types.GenerateKeywordIdeasRequest): + The initial request object. + response (google.ads.googleads.v23.services.types.GenerateKeywordIdeaResponse): + The initial response object. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, 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 = keyword_plan_idea_service.GenerateKeywordIdeasRequest( + request + ) + self._response = response + self._retry = retry + self._timeout = timeout + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self, + ) -> AsyncIterator[keyword_plan_idea_service.GenerateKeywordIdeaResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method( + self._request, + retry=self._retry, + timeout=self._timeout, + metadata=self._metadata, + ) + yield self._response + + def __aiter__( + self, + ) -> AsyncIterator[keyword_plan_idea_service.GenerateKeywordIdeaResult]: + async def async_generator(): + async for page in self.pages: + for response in page.results: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/README.rst b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/README.rst rename to google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_idea_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/base.py b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/base.py new file mode 100644 index 000000000..041faf646 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/base.py @@ -0,0 +1,228 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import keyword_plan_idea_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class KeywordPlanIdeaServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanIdeaService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.generate_keyword_ideas: gapic_v1.method.wrap_method( + self.generate_keyword_ideas, + default_timeout=None, + client_info=client_info, + ), + self.generate_keyword_historical_metrics: gapic_v1.method.wrap_method( + self.generate_keyword_historical_metrics, + default_timeout=None, + client_info=client_info, + ), + self.generate_ad_group_themes: gapic_v1.method.wrap_method( + self.generate_ad_group_themes, + default_timeout=None, + client_info=client_info, + ), + self.generate_keyword_forecast_metrics: gapic_v1.method.wrap_method( + self.generate_keyword_forecast_metrics, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def generate_keyword_ideas( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordIdeasRequest], + Union[ + keyword_plan_idea_service.GenerateKeywordIdeaResponse, + Awaitable[keyword_plan_idea_service.GenerateKeywordIdeaResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_keyword_historical_metrics( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest], + Union[ + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse, + Awaitable[ + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def generate_ad_group_themes( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateAdGroupThemesRequest], + Union[ + keyword_plan_idea_service.GenerateAdGroupThemesResponse, + Awaitable[keyword_plan_idea_service.GenerateAdGroupThemesResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_keyword_forecast_metrics( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest], + Union[ + keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse, + Awaitable[ + keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("KeywordPlanIdeaServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/grpc.py b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/grpc.py new file mode 100644 index 000000000..92dc2ab05 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/grpc.py @@ -0,0 +1,501 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import keyword_plan_idea_service +from .base import KeywordPlanIdeaServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.KeywordPlanIdeaService", + "rpcName": str(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.ads.googleads.v23.services.KeywordPlanIdeaService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanIdeaServiceGrpcTransport(KeywordPlanIdeaServiceTransport): + """gRPC backend transport for KeywordPlanIdeaService. + + Service to generate keyword ideas. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def generate_keyword_ideas( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordIdeasRequest], + keyword_plan_idea_service.GenerateKeywordIdeaResponse, + ]: + r"""Return a callable for the generate keyword ideas method over gRPC. + + Returns a list of keyword ideas. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanIdeaError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateKeywordIdeasRequest], + ~.GenerateKeywordIdeaResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_keyword_ideas" not in self._stubs: + self._stubs["generate_keyword_ideas"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanIdeaService/GenerateKeywordIdeas", + request_serializer=keyword_plan_idea_service.GenerateKeywordIdeasRequest.serialize, + response_deserializer=keyword_plan_idea_service.GenerateKeywordIdeaResponse.deserialize, + ) + ) + return self._stubs["generate_keyword_ideas"] + + @property + def generate_keyword_historical_metrics( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest], + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse, + ]: + r"""Return a callable for the generate keyword historical + metrics method over gRPC. + + Returns a list of keyword historical metrics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateKeywordHistoricalMetricsRequest], + ~.GenerateKeywordHistoricalMetricsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_keyword_historical_metrics" not in self._stubs: + self._stubs["generate_keyword_historical_metrics"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanIdeaService/GenerateKeywordHistoricalMetrics", + request_serializer=keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest.serialize, + response_deserializer=keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse.deserialize, + ) + ) + return self._stubs["generate_keyword_historical_metrics"] + + @property + def generate_ad_group_themes( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateAdGroupThemesRequest], + keyword_plan_idea_service.GenerateAdGroupThemesResponse, + ]: + r"""Return a callable for the generate ad group themes method over gRPC. + + Returns a list of suggested AdGroups and suggested modifications + (text, match type) for the given keywords. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateAdGroupThemesRequest], + ~.GenerateAdGroupThemesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_ad_group_themes" not in self._stubs: + self._stubs["generate_ad_group_themes"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanIdeaService/GenerateAdGroupThemes", + request_serializer=keyword_plan_idea_service.GenerateAdGroupThemesRequest.serialize, + response_deserializer=keyword_plan_idea_service.GenerateAdGroupThemesResponse.deserialize, + ) + ) + return self._stubs["generate_ad_group_themes"] + + @property + def generate_keyword_forecast_metrics( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest], + keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse, + ]: + r"""Return a callable for the generate keyword forecast + metrics method over gRPC. + + Returns metrics (such as impressions, clicks, total cost) of a + keyword forecast for the given campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateKeywordForecastMetricsRequest], + ~.GenerateKeywordForecastMetricsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_keyword_forecast_metrics" not in self._stubs: + self._stubs["generate_keyword_forecast_metrics"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanIdeaService/GenerateKeywordForecastMetrics", + request_serializer=keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest.serialize, + response_deserializer=keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse.deserialize, + ) + ) + return self._stubs["generate_keyword_forecast_metrics"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("KeywordPlanIdeaServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..676e49857 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_idea_service/transports/grpc_asyncio.py @@ -0,0 +1,543 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import keyword_plan_idea_service +from .base import KeywordPlanIdeaServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.KeywordPlanIdeaService", + "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.ads.googleads.v23.services.KeywordPlanIdeaService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanIdeaServiceGrpcAsyncIOTransport( + KeywordPlanIdeaServiceTransport +): + """gRPC AsyncIO backend transport for KeywordPlanIdeaService. + + Service to generate keyword ideas. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def generate_keyword_ideas( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordIdeasRequest], + Awaitable[keyword_plan_idea_service.GenerateKeywordIdeaResponse], + ]: + r"""Return a callable for the generate keyword ideas method over gRPC. + + Returns a list of keyword ideas. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `KeywordPlanIdeaError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateKeywordIdeasRequest], + Awaitable[~.GenerateKeywordIdeaResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_keyword_ideas" not in self._stubs: + self._stubs["generate_keyword_ideas"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanIdeaService/GenerateKeywordIdeas", + request_serializer=keyword_plan_idea_service.GenerateKeywordIdeasRequest.serialize, + response_deserializer=keyword_plan_idea_service.GenerateKeywordIdeaResponse.deserialize, + ) + ) + return self._stubs["generate_keyword_ideas"] + + @property + def generate_keyword_historical_metrics( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest], + Awaitable[ + keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse + ], + ]: + r"""Return a callable for the generate keyword historical + metrics method over gRPC. + + Returns a list of keyword historical metrics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateKeywordHistoricalMetricsRequest], + Awaitable[~.GenerateKeywordHistoricalMetricsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_keyword_historical_metrics" not in self._stubs: + self._stubs["generate_keyword_historical_metrics"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanIdeaService/GenerateKeywordHistoricalMetrics", + request_serializer=keyword_plan_idea_service.GenerateKeywordHistoricalMetricsRequest.serialize, + response_deserializer=keyword_plan_idea_service.GenerateKeywordHistoricalMetricsResponse.deserialize, + ) + ) + return self._stubs["generate_keyword_historical_metrics"] + + @property + def generate_ad_group_themes( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateAdGroupThemesRequest], + Awaitable[keyword_plan_idea_service.GenerateAdGroupThemesResponse], + ]: + r"""Return a callable for the generate ad group themes method over gRPC. + + Returns a list of suggested AdGroups and suggested modifications + (text, match type) for the given keywords. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateAdGroupThemesRequest], + Awaitable[~.GenerateAdGroupThemesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_ad_group_themes" not in self._stubs: + self._stubs["generate_ad_group_themes"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanIdeaService/GenerateAdGroupThemes", + request_serializer=keyword_plan_idea_service.GenerateAdGroupThemesRequest.serialize, + response_deserializer=keyword_plan_idea_service.GenerateAdGroupThemesResponse.deserialize, + ) + ) + return self._stubs["generate_ad_group_themes"] + + @property + def generate_keyword_forecast_metrics( + self, + ) -> Callable[ + [keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest], + Awaitable[ + keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse + ], + ]: + r"""Return a callable for the generate keyword forecast + metrics method over gRPC. + + Returns metrics (such as impressions, clicks, total cost) of a + keyword forecast for the given campaign. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.GenerateKeywordForecastMetricsRequest], + Awaitable[~.GenerateKeywordForecastMetricsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_keyword_forecast_metrics" not in self._stubs: + self._stubs["generate_keyword_forecast_metrics"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanIdeaService/GenerateKeywordForecastMetrics", + request_serializer=keyword_plan_idea_service.GenerateKeywordForecastMetricsRequest.serialize, + response_deserializer=keyword_plan_idea_service.GenerateKeywordForecastMetricsResponse.deserialize, + ) + ) + return self._stubs["generate_keyword_forecast_metrics"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.generate_keyword_ideas: self._wrap_method( + self.generate_keyword_ideas, + default_timeout=None, + client_info=client_info, + ), + self.generate_keyword_historical_metrics: self._wrap_method( + self.generate_keyword_historical_metrics, + default_timeout=None, + client_info=client_info, + ), + self.generate_ad_group_themes: self._wrap_method( + self.generate_ad_group_themes, + default_timeout=None, + client_info=client_info, + ), + self.generate_keyword_forecast_metrics: self._wrap_method( + self.generate_keyword_forecast_metrics, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("KeywordPlanIdeaServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_service/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_service/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_service/async_client.py b/google/ads/googleads/v23/services/services/keyword_plan_service/async_client.py new file mode 100644 index 000000000..fdadf7ec9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_service/async_client.py @@ -0,0 +1,423 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import keyword_plan_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import KeywordPlanServiceTransport, DEFAULT_CLIENT_INFO +from .client import KeywordPlanServiceClient + +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 KeywordPlanServiceAsyncClient: + """Service to manage keyword plans.""" + + _client: KeywordPlanServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = KeywordPlanServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = KeywordPlanServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + KeywordPlanServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = KeywordPlanServiceClient._DEFAULT_UNIVERSE + + keyword_plan_path = staticmethod(KeywordPlanServiceClient.keyword_plan_path) + parse_keyword_plan_path = staticmethod( + KeywordPlanServiceClient.parse_keyword_plan_path + ) + common_billing_account_path = staticmethod( + KeywordPlanServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + KeywordPlanServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + KeywordPlanServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + KeywordPlanServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + KeywordPlanServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + KeywordPlanServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + KeywordPlanServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + KeywordPlanServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + KeywordPlanServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + KeywordPlanServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanServiceAsyncClient: The constructed client. + """ + return KeywordPlanServiceClient.from_service_account_info.__func__(KeywordPlanServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanServiceAsyncClient: The constructed client. + """ + return KeywordPlanServiceClient.from_service_account_file.__func__(KeywordPlanServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return KeywordPlanServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> KeywordPlanServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = KeywordPlanServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanServiceTransport, + Callable[..., KeywordPlanServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanServiceTransport,Callable[..., KeywordPlanServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = KeywordPlanServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.KeywordPlanServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanService", + "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.ads.googleads.v23.services.KeywordPlanService", + "credentialsType": None, + } + ), + ) + + async def mutate_keyword_plans( + self, + request: Optional[ + Union[keyword_plan_service.MutateKeywordPlansRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[keyword_plan_service.KeywordPlanOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_service.MutateKeywordPlansResponse: + r"""Creates, updates, or removes keyword plans. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateKeywordPlansRequest, dict]]): + The request object. Request message for + [KeywordPlanService.MutateKeywordPlans][google.ads.googleads.v23.services.KeywordPlanService.MutateKeywordPlans]. + customer_id (:class:`str`): + Required. The ID of the customer + whose keyword plans are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanOperation]`): + Required. The list of operations to + perform on individual keyword plans. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateKeywordPlansResponse: + Response message for a keyword plan + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, keyword_plan_service.MutateKeywordPlansRequest + ): + request = keyword_plan_service.MutateKeywordPlansRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_keyword_plans + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "KeywordPlanServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("KeywordPlanServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_service/client.py b/google/ads/googleads/v23/services/services/keyword_plan_service/client.py new file mode 100644 index 000000000..09be53215 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_service/client.py @@ -0,0 +1,889 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import keyword_plan_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import KeywordPlanServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import KeywordPlanServiceGrpcTransport +from .transports.grpc_asyncio import KeywordPlanServiceGrpcAsyncIOTransport + + +class KeywordPlanServiceClientMeta(type): + """Metaclass for the KeywordPlanService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordPlanServiceTransport]] + _transport_registry["grpc"] = KeywordPlanServiceGrpcTransport + _transport_registry["grpc_asyncio"] = KeywordPlanServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[KeywordPlanServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordPlanServiceClient(metaclass=KeywordPlanServiceClientMeta): + """Service to manage keyword plans.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordPlanServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordPlanServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordPlanServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def keyword_plan_path( + customer_id: str, + keyword_plan_id: str, + ) -> str: + """Returns a fully-qualified keyword_plan string.""" + return "customers/{customer_id}/keywordPlans/{keyword_plan_id}".format( + customer_id=customer_id, + keyword_plan_id=keyword_plan_id, + ) + + @staticmethod + def parse_keyword_plan_path(path: str) -> Dict[str, str]: + """Parses a keyword_plan path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/keywordPlans/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = KeywordPlanServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = KeywordPlanServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = KeywordPlanServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = KeywordPlanServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + KeywordPlanServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = KeywordPlanServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordPlanServiceTransport, + Callable[..., KeywordPlanServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword plan service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordPlanServiceTransport,Callable[..., KeywordPlanServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordPlanServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = KeywordPlanServiceClient._read_environment_variables() + self._client_cert_source = ( + KeywordPlanServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = KeywordPlanServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, KeywordPlanServiceTransport) + if transport_provided: + # transport is a KeywordPlanServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(KeywordPlanServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or KeywordPlanServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[KeywordPlanServiceTransport], + Callable[..., KeywordPlanServiceTransport], + ] = ( + KeywordPlanServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., KeywordPlanServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.KeywordPlanServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordPlanService", + "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.ads.googleads.v23.services.KeywordPlanService", + "credentialsType": None, + } + ), + ) + + def mutate_keyword_plans( + self, + request: Optional[ + Union[keyword_plan_service.MutateKeywordPlansRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[keyword_plan_service.KeywordPlanOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_plan_service.MutateKeywordPlansResponse: + r"""Creates, updates, or removes keyword plans. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateKeywordPlansRequest, dict]): + The request object. Request message for + [KeywordPlanService.MutateKeywordPlans][google.ads.googleads.v23.services.KeywordPlanService.MutateKeywordPlans]. + customer_id (str): + Required. The ID of the customer + whose keyword plans are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanOperation]): + Required. The list of operations to + perform on individual keyword plans. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateKeywordPlansResponse: + Response message for a keyword plan + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, keyword_plan_service.MutateKeywordPlansRequest + ): + request = keyword_plan_service.MutateKeywordPlansRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_keyword_plans + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "KeywordPlanServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("KeywordPlanServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_plan_service/transports/README.rst b/google/ads/googleads/v23/services/services/keyword_plan_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_service/transports/README.rst rename to google/ads/googleads/v23/services/services/keyword_plan_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/keyword_plan_service/transports/__init__.py b/google/ads/googleads/v23/services/services/keyword_plan_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_plan_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/keyword_plan_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_plan_service/transports/base.py b/google/ads/googleads/v23/services/services/keyword_plan_service/transports/base.py new file mode 100644 index 000000000..a4a096843 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import keyword_plan_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class KeywordPlanServiceTransport(abc.ABC): + """Abstract transport class for KeywordPlanService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_keyword_plans: gapic_v1.method.wrap_method( + self.mutate_keyword_plans, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_keyword_plans( + self, + ) -> Callable[ + [keyword_plan_service.MutateKeywordPlansRequest], + Union[ + keyword_plan_service.MutateKeywordPlansResponse, + Awaitable[keyword_plan_service.MutateKeywordPlansResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("KeywordPlanServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_service/transports/grpc.py b/google/ads/googleads/v23/services/services/keyword_plan_service/transports/grpc.py new file mode 100644 index 000000000..2e5a0bea5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_service/transports/grpc.py @@ -0,0 +1,391 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import keyword_plan_service +from .base import KeywordPlanServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.KeywordPlanService", + "rpcName": str(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.ads.googleads.v23.services.KeywordPlanService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanServiceGrpcTransport(KeywordPlanServiceTransport): + """gRPC backend transport for KeywordPlanService. + + Service to manage keyword plans. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_keyword_plans( + self, + ) -> Callable[ + [keyword_plan_service.MutateKeywordPlansRequest], + keyword_plan_service.MutateKeywordPlansResponse, + ]: + r"""Return a callable for the mutate keyword plans method over gRPC. + + Creates, updates, or removes keyword plans. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateKeywordPlansRequest], + ~.MutateKeywordPlansResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plans" not in self._stubs: + self._stubs["mutate_keyword_plans"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanService/MutateKeywordPlans", + request_serializer=keyword_plan_service.MutateKeywordPlansRequest.serialize, + response_deserializer=keyword_plan_service.MutateKeywordPlansResponse.deserialize, + ) + ) + return self._stubs["mutate_keyword_plans"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("KeywordPlanServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_plan_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/keyword_plan_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..1f219bb2d --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_plan_service/transports/grpc_asyncio.py @@ -0,0 +1,412 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import keyword_plan_service +from .base import KeywordPlanServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.KeywordPlanService", + "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.ads.googleads.v23.services.KeywordPlanService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordPlanServiceGrpcAsyncIOTransport(KeywordPlanServiceTransport): + """gRPC AsyncIO backend transport for KeywordPlanService. + + Service to manage keyword plans. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_keyword_plans( + self, + ) -> Callable[ + [keyword_plan_service.MutateKeywordPlansRequest], + Awaitable[keyword_plan_service.MutateKeywordPlansResponse], + ]: + r"""Return a callable for the mutate keyword plans method over gRPC. + + Creates, updates, or removes keyword plans. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `KeywordPlanError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `QuotaError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateKeywordPlansRequest], + Awaitable[~.MutateKeywordPlansResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_keyword_plans" not in self._stubs: + self._stubs["mutate_keyword_plans"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordPlanService/MutateKeywordPlans", + request_serializer=keyword_plan_service.MutateKeywordPlansRequest.serialize, + response_deserializer=keyword_plan_service.MutateKeywordPlansResponse.deserialize, + ) + ) + return self._stubs["mutate_keyword_plans"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_keyword_plans: self._wrap_method( + self.mutate_keyword_plans, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("KeywordPlanServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/__init__.py b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_theme_constant_service/__init__.py rename to google/ads/googleads/v23/services/services/keyword_theme_constant_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_theme_constant_service/async_client.py b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/async_client.py new file mode 100644 index 000000000..1ee6a403a --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/async_client.py @@ -0,0 +1,388 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + keyword_theme_constant_service, +) +from .transports.base import ( + KeywordThemeConstantServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import KeywordThemeConstantServiceClient + +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 KeywordThemeConstantServiceAsyncClient: + """Service to fetch Smart Campaign keyword themes.""" + + _client: KeywordThemeConstantServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = KeywordThemeConstantServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + KeywordThemeConstantServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + KeywordThemeConstantServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = KeywordThemeConstantServiceClient._DEFAULT_UNIVERSE + + keyword_theme_constant_path = staticmethod( + KeywordThemeConstantServiceClient.keyword_theme_constant_path + ) + parse_keyword_theme_constant_path = staticmethod( + KeywordThemeConstantServiceClient.parse_keyword_theme_constant_path + ) + common_billing_account_path = staticmethod( + KeywordThemeConstantServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + KeywordThemeConstantServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + KeywordThemeConstantServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + KeywordThemeConstantServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + KeywordThemeConstantServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + KeywordThemeConstantServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + KeywordThemeConstantServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + KeywordThemeConstantServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + KeywordThemeConstantServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + KeywordThemeConstantServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordThemeConstantServiceAsyncClient: The constructed client. + """ + return KeywordThemeConstantServiceClient.from_service_account_info.__func__(KeywordThemeConstantServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordThemeConstantServiceAsyncClient: The constructed client. + """ + return KeywordThemeConstantServiceClient.from_service_account_file.__func__(KeywordThemeConstantServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return KeywordThemeConstantServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> KeywordThemeConstantServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordThemeConstantServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = KeywordThemeConstantServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordThemeConstantServiceTransport, + Callable[..., KeywordThemeConstantServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword theme constant service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordThemeConstantServiceTransport,Callable[..., KeywordThemeConstantServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordThemeConstantServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = KeywordThemeConstantServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.KeywordThemeConstantServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordThemeConstantService", + "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.ads.googleads.v23.services.KeywordThemeConstantService", + "credentialsType": None, + } + ), + ) + + async def suggest_keyword_theme_constants( + self, + request: Optional[ + Union[ + keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse: + r"""Returns KeywordThemeConstant suggestions by keyword themes. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.SuggestKeywordThemeConstantsRequest, dict]]): + The request object. Request message for + [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v23.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestKeywordThemeConstantsResponse: + Response message for + [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v23.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest, + ): + request = keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.suggest_keyword_theme_constants + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "KeywordThemeConstantServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("KeywordThemeConstantServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/keyword_theme_constant_service/client.py b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/client.py new file mode 100644 index 000000000..f0858c5cf --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/client.py @@ -0,0 +1,862 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + keyword_theme_constant_service, +) +from .transports.base import ( + KeywordThemeConstantServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import KeywordThemeConstantServiceGrpcTransport +from .transports.grpc_asyncio import ( + KeywordThemeConstantServiceGrpcAsyncIOTransport, +) + + +class KeywordThemeConstantServiceClientMeta(type): + """Metaclass for the KeywordThemeConstantService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[KeywordThemeConstantServiceTransport]] + _transport_registry["grpc"] = KeywordThemeConstantServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + KeywordThemeConstantServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[KeywordThemeConstantServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class KeywordThemeConstantServiceClient( + metaclass=KeywordThemeConstantServiceClientMeta +): + """Service to fetch Smart Campaign keyword themes.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordThemeConstantServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + KeywordThemeConstantServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> KeywordThemeConstantServiceTransport: + """Returns the transport used by the client instance. + + Returns: + KeywordThemeConstantServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def keyword_theme_constant_path( + express_category_id: str, + express_sub_category_id: str, + ) -> str: + """Returns a fully-qualified keyword_theme_constant string.""" + return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( + express_category_id=express_category_id, + express_sub_category_id=express_sub_category_id, + ) + + @staticmethod + def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: + """Parses a keyword_theme_constant path into its component segments.""" + m = re.match( + r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + KeywordThemeConstantServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + KeywordThemeConstantServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + KeywordThemeConstantServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + KeywordThemeConstantServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = KeywordThemeConstantServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = KeywordThemeConstantServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + KeywordThemeConstantServiceTransport, + Callable[..., KeywordThemeConstantServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the keyword theme constant service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,KeywordThemeConstantServiceTransport,Callable[..., KeywordThemeConstantServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the KeywordThemeConstantServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = KeywordThemeConstantServiceClient._read_environment_variables() + self._client_cert_source = ( + KeywordThemeConstantServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + KeywordThemeConstantServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, KeywordThemeConstantServiceTransport + ) + if transport_provided: + # transport is a KeywordThemeConstantServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + KeywordThemeConstantServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or KeywordThemeConstantServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[KeywordThemeConstantServiceTransport], + Callable[..., KeywordThemeConstantServiceTransport], + ] = ( + KeywordThemeConstantServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., KeywordThemeConstantServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.KeywordThemeConstantServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.KeywordThemeConstantService", + "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.ads.googleads.v23.services.KeywordThemeConstantService", + "credentialsType": None, + } + ), + ) + + def suggest_keyword_theme_constants( + self, + request: Optional[ + Union[ + keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse: + r"""Returns KeywordThemeConstant suggestions by keyword themes. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.SuggestKeywordThemeConstantsRequest, dict]): + The request object. Request message for + [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v23.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestKeywordThemeConstantsResponse: + Response message for + [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v23.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest, + ): + request = keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.suggest_keyword_theme_constants + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "KeywordThemeConstantServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("KeywordThemeConstantServiceClient",) diff --git a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/README.rst b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/README.rst rename to google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/__init__.py b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/keyword_theme_constant_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/base.py b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/base.py new file mode 100644 index 000000000..92f7327e3 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + keyword_theme_constant_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class KeywordThemeConstantServiceTransport(abc.ABC): + """Abstract transport class for KeywordThemeConstantService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.suggest_keyword_theme_constants: gapic_v1.method.wrap_method( + self.suggest_keyword_theme_constants, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def suggest_keyword_theme_constants( + self, + ) -> Callable[ + [keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest], + Union[ + keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse, + Awaitable[ + keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("KeywordThemeConstantServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/grpc.py b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/grpc.py new file mode 100644 index 000000000..87bdb2a61 --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/grpc.py @@ -0,0 +1,392 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + keyword_theme_constant_service, +) +from .base import KeywordThemeConstantServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.KeywordThemeConstantService", + "rpcName": str(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.ads.googleads.v23.services.KeywordThemeConstantService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordThemeConstantServiceGrpcTransport( + KeywordThemeConstantServiceTransport +): + """gRPC backend transport for KeywordThemeConstantService. + + Service to fetch Smart Campaign keyword themes. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def suggest_keyword_theme_constants( + self, + ) -> Callable[ + [keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest], + keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse, + ]: + r"""Return a callable for the suggest keyword theme + constants method over gRPC. + + Returns KeywordThemeConstant suggestions by keyword themes. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SuggestKeywordThemeConstantsRequest], + ~.SuggestKeywordThemeConstantsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_keyword_theme_constants" not in self._stubs: + self._stubs["suggest_keyword_theme_constants"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordThemeConstantService/SuggestKeywordThemeConstants", + request_serializer=keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest.serialize, + response_deserializer=keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse.deserialize, + ) + ) + return self._stubs["suggest_keyword_theme_constants"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("KeywordThemeConstantServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..b0d13670c --- /dev/null +++ b/google/ads/googleads/v23/services/services/keyword_theme_constant_service/transports/grpc_asyncio.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + keyword_theme_constant_service, +) +from .base import KeywordThemeConstantServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.KeywordThemeConstantService", + "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.ads.googleads.v23.services.KeywordThemeConstantService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class KeywordThemeConstantServiceGrpcAsyncIOTransport( + KeywordThemeConstantServiceTransport +): + """gRPC AsyncIO backend transport for KeywordThemeConstantService. + + Service to fetch Smart Campaign keyword themes. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def suggest_keyword_theme_constants( + self, + ) -> Callable[ + [keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest], + Awaitable[ + keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse + ], + ]: + r"""Return a callable for the suggest keyword theme + constants method over gRPC. + + Returns KeywordThemeConstant suggestions by keyword themes. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.SuggestKeywordThemeConstantsRequest], + Awaitable[~.SuggestKeywordThemeConstantsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_keyword_theme_constants" not in self._stubs: + self._stubs["suggest_keyword_theme_constants"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.KeywordThemeConstantService/SuggestKeywordThemeConstants", + request_serializer=keyword_theme_constant_service.SuggestKeywordThemeConstantsRequest.serialize, + response_deserializer=keyword_theme_constant_service.SuggestKeywordThemeConstantsResponse.deserialize, + ) + ) + return self._stubs["suggest_keyword_theme_constants"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.suggest_keyword_theme_constants: self._wrap_method( + self.suggest_keyword_theme_constants, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("KeywordThemeConstantServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/label_service/__init__.py b/google/ads/googleads/v23/services/services/label_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/label_service/__init__.py rename to google/ads/googleads/v23/services/services/label_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/label_service/async_client.py b/google/ads/googleads/v23/services/services/label_service/async_client.py new file mode 100644 index 000000000..e4a08f550 --- /dev/null +++ b/google/ads/googleads/v23/services/services/label_service/async_client.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import LabelServiceTransport, DEFAULT_CLIENT_INFO +from .client import LabelServiceClient + +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 LabelServiceAsyncClient: + """Service to manage labels.""" + + _client: LabelServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = LabelServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = LabelServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = LabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE + _DEFAULT_UNIVERSE = LabelServiceClient._DEFAULT_UNIVERSE + + label_path = staticmethod(LabelServiceClient.label_path) + parse_label_path = staticmethod(LabelServiceClient.parse_label_path) + common_billing_account_path = staticmethod( + LabelServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + LabelServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(LabelServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + LabelServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + LabelServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + LabelServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod(LabelServiceClient.common_project_path) + parse_common_project_path = staticmethod( + LabelServiceClient.parse_common_project_path + ) + common_location_path = staticmethod(LabelServiceClient.common_location_path) + parse_common_location_path = staticmethod( + LabelServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LabelServiceAsyncClient: The constructed client. + """ + return LabelServiceClient.from_service_account_info.__func__(LabelServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LabelServiceAsyncClient: The constructed client. + """ + return LabelServiceClient.from_service_account_file.__func__(LabelServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return LabelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> LabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + LabelServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = LabelServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, LabelServiceTransport, Callable[..., LabelServiceTransport] + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the label service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,LabelServiceTransport,Callable[..., LabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the LabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = LabelServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.LabelServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.LabelService", + "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.ads.googleads.v23.services.LabelService", + "credentialsType": None, + } + ), + ) + + async def mutate_labels( + self, + request: Optional[ + Union[label_service.MutateLabelsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[label_service.LabelOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> label_service.MutateLabelsResponse: + r"""Creates, updates, or removes labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `LabelError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateLabelsRequest, dict]]): + The request object. Request message for + [LabelService.MutateLabels][google.ads.googleads.v23.services.LabelService.MutateLabels]. + customer_id (:class:`str`): + Required. ID of the customer whose + labels are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.LabelOperation]`): + Required. The list of operations to + perform on labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateLabelsResponse: + Response message for a labels mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, label_service.MutateLabelsRequest): + request = label_service.MutateLabelsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_labels + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "LabelServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("LabelServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/label_service/client.py b/google/ads/googleads/v23/services/services/label_service/client.py new file mode 100644 index 000000000..dc1891fc6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/label_service/client.py @@ -0,0 +1,880 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import label_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import LabelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import LabelServiceGrpcTransport +from .transports.grpc_asyncio import LabelServiceGrpcAsyncIOTransport + + +class LabelServiceClientMeta(type): + """Metaclass for the LabelService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[LabelServiceTransport]] + _transport_registry["grpc"] = LabelServiceGrpcTransport + _transport_registry["grpc_asyncio"] = LabelServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[LabelServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class LabelServiceClient(metaclass=LabelServiceClientMeta): + """Service to manage labels.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LabelServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> LabelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + LabelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def label_path( + customer_id: str, + label_id: str, + ) -> str: + """Returns a fully-qualified label string.""" + return "customers/{customer_id}/labels/{label_id}".format( + customer_id=customer_id, + label_id=label_id, + ) + + @staticmethod + def parse_label_path(path: str) -> Dict[str, str]: + """Parses a label path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/labels/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = LabelServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = LabelServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = LabelServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = LabelServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = LabelServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = LabelServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, LabelServiceTransport, Callable[..., LabelServiceTransport] + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the label service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,LabelServiceTransport,Callable[..., LabelServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the LabelServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = LabelServiceClient._read_environment_variables() + self._client_cert_source = LabelServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + self._universe_domain = LabelServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, LabelServiceTransport) + if transport_provided: + # transport is a LabelServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(LabelServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or LabelServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[LabelServiceTransport], + Callable[..., LabelServiceTransport], + ] = ( + LabelServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., LabelServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.LabelServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.LabelService", + "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.ads.googleads.v23.services.LabelService", + "credentialsType": None, + } + ), + ) + + def mutate_labels( + self, + request: Optional[ + Union[label_service.MutateLabelsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[label_service.LabelOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> label_service.MutateLabelsResponse: + r"""Creates, updates, or removes labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `LabelError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateLabelsRequest, dict]): + The request object. Request message for + [LabelService.MutateLabels][google.ads.googleads.v23.services.LabelService.MutateLabels]. + customer_id (str): + Required. ID of the customer whose + labels are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.LabelOperation]): + Required. The list of operations to + perform on labels. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateLabelsResponse: + Response message for a labels mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, label_service.MutateLabelsRequest): + request = label_service.MutateLabelsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.mutate_labels] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "LabelServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("LabelServiceClient",) diff --git a/google/ads/googleads/v19/services/services/label_service/transports/README.rst b/google/ads/googleads/v23/services/services/label_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/label_service/transports/README.rst rename to google/ads/googleads/v23/services/services/label_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/label_service/transports/__init__.py b/google/ads/googleads/v23/services/services/label_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/label_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/label_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/label_service/transports/base.py b/google/ads/googleads/v23/services/services/label_service/transports/base.py new file mode 100644 index 000000000..fcfad390f --- /dev/null +++ b/google/ads/googleads/v23/services/services/label_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import label_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class LabelServiceTransport(abc.ABC): + """Abstract transport class for LabelService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_labels: gapic_v1.method.wrap_method( + self.mutate_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_labels( + self, + ) -> Callable[ + [label_service.MutateLabelsRequest], + Union[ + label_service.MutateLabelsResponse, + Awaitable[label_service.MutateLabelsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("LabelServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/label_service/transports/grpc.py b/google/ads/googleads/v23/services/services/label_service/transports/grpc.py new file mode 100644 index 000000000..bdb21a0d5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/label_service/transports/grpc.py @@ -0,0 +1,392 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import label_service +from .base import LabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.LabelService", + "rpcName": str(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.ads.googleads.v23.services.LabelService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class LabelServiceGrpcTransport(LabelServiceTransport): + """gRPC backend transport for LabelService. + + Service to manage labels. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_labels( + self, + ) -> Callable[ + [label_service.MutateLabelsRequest], label_service.MutateLabelsResponse + ]: + r"""Return a callable for the mutate labels method over gRPC. + + Creates, updates, or removes labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `LabelError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateLabelsRequest], + ~.MutateLabelsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_labels" not in self._stubs: + self._stubs["mutate_labels"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.LabelService/MutateLabels", + request_serializer=label_service.MutateLabelsRequest.serialize, + response_deserializer=label_service.MutateLabelsResponse.deserialize, + ) + return self._stubs["mutate_labels"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("LabelServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/label_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/label_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..0b51b8583 --- /dev/null +++ b/google/ads/googleads/v23/services/services/label_service/transports/grpc_asyncio.py @@ -0,0 +1,414 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import label_service +from .base import LabelServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.LabelService", + "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.ads.googleads.v23.services.LabelService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class LabelServiceGrpcAsyncIOTransport(LabelServiceTransport): + """gRPC AsyncIO backend transport for LabelService. + + Service to manage labels. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_labels( + self, + ) -> Callable[ + [label_service.MutateLabelsRequest], + Awaitable[label_service.MutateLabelsResponse], + ]: + r"""Return a callable for the mutate labels method over gRPC. + + Creates, updates, or removes labels. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `LabelError <>`__ `MutateError <>`__ + `NewResourceCreationError <>`__ `NotEmptyError <>`__ + `NullError <>`__ `OperatorError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SizeLimitError <>`__ + `StringFormatError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.MutateLabelsRequest], + Awaitable[~.MutateLabelsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_labels" not in self._stubs: + self._stubs["mutate_labels"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.LabelService/MutateLabels", + request_serializer=label_service.MutateLabelsRequest.serialize, + response_deserializer=label_service.MutateLabelsResponse.deserialize, + ) + return self._stubs["mutate_labels"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_labels: self._wrap_method( + self.mutate_labels, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("LabelServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/local_services_lead_service/__init__.py b/google/ads/googleads/v23/services/services/local_services_lead_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/local_services_lead_service/__init__.py rename to google/ads/googleads/v23/services/services/local_services_lead_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/local_services_lead_service/async_client.py b/google/ads/googleads/v23/services/services/local_services_lead_service/async_client.py new file mode 100644 index 000000000..7c828fca6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/local_services_lead_service/async_client.py @@ -0,0 +1,496 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import local_services_lead_service +from .transports.base import ( + LocalServicesLeadServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import LocalServicesLeadServiceClient + +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 LocalServicesLeadServiceAsyncClient: + """This service allows management of LocalServicesLead + resources. + """ + + _client: LocalServicesLeadServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = LocalServicesLeadServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = LocalServicesLeadServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + LocalServicesLeadServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = LocalServicesLeadServiceClient._DEFAULT_UNIVERSE + + local_services_lead_path = staticmethod( + LocalServicesLeadServiceClient.local_services_lead_path + ) + parse_local_services_lead_path = staticmethod( + LocalServicesLeadServiceClient.parse_local_services_lead_path + ) + common_billing_account_path = staticmethod( + LocalServicesLeadServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + LocalServicesLeadServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + LocalServicesLeadServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + LocalServicesLeadServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + LocalServicesLeadServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + LocalServicesLeadServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + LocalServicesLeadServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + LocalServicesLeadServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + LocalServicesLeadServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + LocalServicesLeadServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LocalServicesLeadServiceAsyncClient: The constructed client. + """ + return LocalServicesLeadServiceClient.from_service_account_info.__func__(LocalServicesLeadServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LocalServicesLeadServiceAsyncClient: The constructed client. + """ + return LocalServicesLeadServiceClient.from_service_account_file.__func__(LocalServicesLeadServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return LocalServicesLeadServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> LocalServicesLeadServiceTransport: + """Returns the transport used by the client instance. + + Returns: + LocalServicesLeadServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = LocalServicesLeadServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + LocalServicesLeadServiceTransport, + Callable[..., LocalServicesLeadServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the local services lead service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,LocalServicesLeadServiceTransport,Callable[..., LocalServicesLeadServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the LocalServicesLeadServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = LocalServicesLeadServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.LocalServicesLeadServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.LocalServicesLeadService", + "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.ads.googleads.v23.services.LocalServicesLeadService", + "credentialsType": None, + } + ), + ) + + async def append_lead_conversation( + self, + request: Optional[ + Union[ + local_services_lead_service.AppendLeadConversationRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + conversations: Optional[ + MutableSequence[local_services_lead_service.Conversation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> local_services_lead_service.AppendLeadConversationResponse: + r"""RPC to append Local Services Lead Conversation + resources to Local Services Lead resources. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.AppendLeadConversationRequest, dict]]): + The request object. Request message for + [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v23.services.LocalServicesLeadService.AppendLeadConversation]. + customer_id (:class:`str`): + Required. The Id of the customer + which owns the leads onto which the + conversations will be appended. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + conversations (:class:`MutableSequence[google.ads.googleads.v23.services.types.Conversation]`): + Required. Conversations that are + being appended. + + This corresponds to the ``conversations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.AppendLeadConversationResponse: + Response message for + [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v23.services.LocalServicesLeadService.AppendLeadConversation]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, conversations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, local_services_lead_service.AppendLeadConversationRequest + ): + request = local_services_lead_service.AppendLeadConversationRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if conversations: + request.conversations.extend(conversations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.append_lead_conversation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def provide_lead_feedback( + self, + request: Optional[ + Union[local_services_lead_service.ProvideLeadFeedbackRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> local_services_lead_service.ProvideLeadFeedbackResponse: + r"""RPC to provide feedback on Local Services Lead + resources. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ProvideLeadFeedbackRequest, dict]]): + The request object. Request message for + [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v23.services.LocalServicesLeadService.ProvideLeadFeedback]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ProvideLeadFeedbackResponse: + Response message for + [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v23.services.LocalServicesLeadService.ProvideLeadFeedback]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, local_services_lead_service.ProvideLeadFeedbackRequest + ): + request = local_services_lead_service.ProvideLeadFeedbackRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.provide_lead_feedback + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "LocalServicesLeadServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("LocalServicesLeadServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/local_services_lead_service/client.py b/google/ads/googleads/v23/services/services/local_services_lead_service/client.py new file mode 100644 index 000000000..1ce56a758 --- /dev/null +++ b/google/ads/googleads/v23/services/services/local_services_lead_service/client.py @@ -0,0 +1,974 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import local_services_lead_service +from .transports.base import ( + LocalServicesLeadServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import LocalServicesLeadServiceGrpcTransport +from .transports.grpc_asyncio import ( + LocalServicesLeadServiceGrpcAsyncIOTransport, +) + + +class LocalServicesLeadServiceClientMeta(type): + """Metaclass for the LocalServicesLeadService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[LocalServicesLeadServiceTransport]] + _transport_registry["grpc"] = LocalServicesLeadServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + LocalServicesLeadServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[LocalServicesLeadServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class LocalServicesLeadServiceClient( + metaclass=LocalServicesLeadServiceClientMeta +): + """This service allows management of LocalServicesLead + resources. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LocalServicesLeadServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + LocalServicesLeadServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> LocalServicesLeadServiceTransport: + """Returns the transport used by the client instance. + + Returns: + LocalServicesLeadServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def local_services_lead_path( + customer_id: str, + local_services_lead_id: str, + ) -> str: + """Returns a fully-qualified local_services_lead string.""" + return "customers/{customer_id}/localServicesLeads/{local_services_lead_id}".format( + customer_id=customer_id, + local_services_lead_id=local_services_lead_id, + ) + + @staticmethod + def parse_local_services_lead_path(path: str) -> Dict[str, str]: + """Parses a local_services_lead path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/localServicesLeads/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + LocalServicesLeadServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + LocalServicesLeadServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = LocalServicesLeadServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = LocalServicesLeadServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = LocalServicesLeadServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = LocalServicesLeadServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + LocalServicesLeadServiceTransport, + Callable[..., LocalServicesLeadServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the local services lead service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,LocalServicesLeadServiceTransport,Callable[..., LocalServicesLeadServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the LocalServicesLeadServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = LocalServicesLeadServiceClient._read_environment_variables() + self._client_cert_source = ( + LocalServicesLeadServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + LocalServicesLeadServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, LocalServicesLeadServiceTransport + ) + if transport_provided: + # transport is a LocalServicesLeadServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(LocalServicesLeadServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or LocalServicesLeadServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[LocalServicesLeadServiceTransport], + Callable[..., LocalServicesLeadServiceTransport], + ] = ( + LocalServicesLeadServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., LocalServicesLeadServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.LocalServicesLeadServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.LocalServicesLeadService", + "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.ads.googleads.v23.services.LocalServicesLeadService", + "credentialsType": None, + } + ), + ) + + def append_lead_conversation( + self, + request: Optional[ + Union[ + local_services_lead_service.AppendLeadConversationRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + conversations: Optional[ + MutableSequence[local_services_lead_service.Conversation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> local_services_lead_service.AppendLeadConversationResponse: + r"""RPC to append Local Services Lead Conversation + resources to Local Services Lead resources. + + Args: + request (Union[google.ads.googleads.v23.services.types.AppendLeadConversationRequest, dict]): + The request object. Request message for + [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v23.services.LocalServicesLeadService.AppendLeadConversation]. + customer_id (str): + Required. The Id of the customer + which owns the leads onto which the + conversations will be appended. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + conversations (MutableSequence[google.ads.googleads.v23.services.types.Conversation]): + Required. Conversations that are + being appended. + + This corresponds to the ``conversations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.AppendLeadConversationResponse: + Response message for + [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v23.services.LocalServicesLeadService.AppendLeadConversation]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, conversations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, local_services_lead_service.AppendLeadConversationRequest + ): + request = local_services_lead_service.AppendLeadConversationRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if conversations is not None: + request.conversations = conversations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.append_lead_conversation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def provide_lead_feedback( + self, + request: Optional[ + Union[local_services_lead_service.ProvideLeadFeedbackRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> local_services_lead_service.ProvideLeadFeedbackResponse: + r"""RPC to provide feedback on Local Services Lead + resources. + + Args: + request (Union[google.ads.googleads.v23.services.types.ProvideLeadFeedbackRequest, dict]): + The request object. Request message for + [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v23.services.LocalServicesLeadService.ProvideLeadFeedback]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ProvideLeadFeedbackResponse: + Response message for + [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v23.services.LocalServicesLeadService.ProvideLeadFeedback]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, local_services_lead_service.ProvideLeadFeedbackRequest + ): + request = local_services_lead_service.ProvideLeadFeedbackRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.provide_lead_feedback + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "LocalServicesLeadServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("LocalServicesLeadServiceClient",) diff --git a/google/ads/googleads/v19/services/services/local_services_lead_service/transports/README.rst b/google/ads/googleads/v23/services/services/local_services_lead_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/local_services_lead_service/transports/README.rst rename to google/ads/googleads/v23/services/services/local_services_lead_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/local_services_lead_service/transports/__init__.py b/google/ads/googleads/v23/services/services/local_services_lead_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/local_services_lead_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/local_services_lead_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/local_services_lead_service/transports/base.py b/google/ads/googleads/v23/services/services/local_services_lead_service/transports/base.py new file mode 100644 index 000000000..f65c61844 --- /dev/null +++ b/google/ads/googleads/v23/services/services/local_services_lead_service/transports/base.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import local_services_lead_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class LocalServicesLeadServiceTransport(abc.ABC): + """Abstract transport class for LocalServicesLeadService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.append_lead_conversation: gapic_v1.method.wrap_method( + self.append_lead_conversation, + default_timeout=None, + client_info=client_info, + ), + self.provide_lead_feedback: gapic_v1.method.wrap_method( + self.provide_lead_feedback, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def append_lead_conversation( + self, + ) -> Callable[ + [local_services_lead_service.AppendLeadConversationRequest], + Union[ + local_services_lead_service.AppendLeadConversationResponse, + Awaitable[ + local_services_lead_service.AppendLeadConversationResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def provide_lead_feedback( + self, + ) -> Callable[ + [local_services_lead_service.ProvideLeadFeedbackRequest], + Union[ + local_services_lead_service.ProvideLeadFeedbackResponse, + Awaitable[local_services_lead_service.ProvideLeadFeedbackResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("LocalServicesLeadServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/local_services_lead_service/transports/grpc.py b/google/ads/googleads/v23/services/services/local_services_lead_service/transports/grpc.py new file mode 100644 index 000000000..78488c6a8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/local_services_lead_service/transports/grpc.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import local_services_lead_service +from .base import LocalServicesLeadServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.LocalServicesLeadService", + "rpcName": str(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.ads.googleads.v23.services.LocalServicesLeadService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class LocalServicesLeadServiceGrpcTransport(LocalServicesLeadServiceTransport): + """gRPC backend transport for LocalServicesLeadService. + + This service allows management of LocalServicesLead + resources. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def append_lead_conversation( + self, + ) -> Callable[ + [local_services_lead_service.AppendLeadConversationRequest], + local_services_lead_service.AppendLeadConversationResponse, + ]: + r"""Return a callable for the append lead conversation method over gRPC. + + RPC to append Local Services Lead Conversation + resources to Local Services Lead resources. + + Returns: + Callable[[~.AppendLeadConversationRequest], + ~.AppendLeadConversationResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "append_lead_conversation" not in self._stubs: + self._stubs["append_lead_conversation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.LocalServicesLeadService/AppendLeadConversation", + request_serializer=local_services_lead_service.AppendLeadConversationRequest.serialize, + response_deserializer=local_services_lead_service.AppendLeadConversationResponse.deserialize, + ) + ) + return self._stubs["append_lead_conversation"] + + @property + def provide_lead_feedback( + self, + ) -> Callable[ + [local_services_lead_service.ProvideLeadFeedbackRequest], + local_services_lead_service.ProvideLeadFeedbackResponse, + ]: + r"""Return a callable for the provide lead feedback method over gRPC. + + RPC to provide feedback on Local Services Lead + resources. + + Returns: + Callable[[~.ProvideLeadFeedbackRequest], + ~.ProvideLeadFeedbackResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "provide_lead_feedback" not in self._stubs: + self._stubs["provide_lead_feedback"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.LocalServicesLeadService/ProvideLeadFeedback", + request_serializer=local_services_lead_service.ProvideLeadFeedbackRequest.serialize, + response_deserializer=local_services_lead_service.ProvideLeadFeedbackResponse.deserialize, + ) + ) + return self._stubs["provide_lead_feedback"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("LocalServicesLeadServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/local_services_lead_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/local_services_lead_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..684c1d2cf --- /dev/null +++ b/google/ads/googleads/v23/services/services/local_services_lead_service/transports/grpc_asyncio.py @@ -0,0 +1,445 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import local_services_lead_service +from .base import LocalServicesLeadServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.LocalServicesLeadService", + "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.ads.googleads.v23.services.LocalServicesLeadService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class LocalServicesLeadServiceGrpcAsyncIOTransport( + LocalServicesLeadServiceTransport +): + """gRPC AsyncIO backend transport for LocalServicesLeadService. + + This service allows management of LocalServicesLead + resources. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def append_lead_conversation( + self, + ) -> Callable[ + [local_services_lead_service.AppendLeadConversationRequest], + Awaitable[local_services_lead_service.AppendLeadConversationResponse], + ]: + r"""Return a callable for the append lead conversation method over gRPC. + + RPC to append Local Services Lead Conversation + resources to Local Services Lead resources. + + Returns: + Callable[[~.AppendLeadConversationRequest], + Awaitable[~.AppendLeadConversationResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "append_lead_conversation" not in self._stubs: + self._stubs["append_lead_conversation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.LocalServicesLeadService/AppendLeadConversation", + request_serializer=local_services_lead_service.AppendLeadConversationRequest.serialize, + response_deserializer=local_services_lead_service.AppendLeadConversationResponse.deserialize, + ) + ) + return self._stubs["append_lead_conversation"] + + @property + def provide_lead_feedback( + self, + ) -> Callable[ + [local_services_lead_service.ProvideLeadFeedbackRequest], + Awaitable[local_services_lead_service.ProvideLeadFeedbackResponse], + ]: + r"""Return a callable for the provide lead feedback method over gRPC. + + RPC to provide feedback on Local Services Lead + resources. + + Returns: + Callable[[~.ProvideLeadFeedbackRequest], + Awaitable[~.ProvideLeadFeedbackResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "provide_lead_feedback" not in self._stubs: + self._stubs["provide_lead_feedback"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.LocalServicesLeadService/ProvideLeadFeedback", + request_serializer=local_services_lead_service.ProvideLeadFeedbackRequest.serialize, + response_deserializer=local_services_lead_service.ProvideLeadFeedbackResponse.deserialize, + ) + ) + return self._stubs["provide_lead_feedback"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.append_lead_conversation: self._wrap_method( + self.append_lead_conversation, + default_timeout=None, + client_info=client_info, + ), + self.provide_lead_feedback: self._wrap_method( + self.provide_lead_feedback, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("LocalServicesLeadServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/offline_user_data_job_service/__init__.py b/google/ads/googleads/v23/services/services/offline_user_data_job_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/offline_user_data_job_service/__init__.py rename to google/ads/googleads/v23/services/services/offline_user_data_job_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/offline_user_data_job_service/async_client.py b/google/ads/googleads/v23/services/services/offline_user_data_job_service/async_client.py new file mode 100644 index 000000000..841fa2183 --- /dev/null +++ b/google/ads/googleads/v23/services/services/offline_user_data_job_service/async_client.py @@ -0,0 +1,682 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.resources.types import offline_user_data_job +from google.ads.googleads.v23.services.types import ( + offline_user_data_job_service, +) +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + OfflineUserDataJobServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import OfflineUserDataJobServiceClient + +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 OfflineUserDataJobServiceAsyncClient: + """Service to manage offline user data jobs.""" + + _client: OfflineUserDataJobServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = OfflineUserDataJobServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + OfflineUserDataJobServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + OfflineUserDataJobServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = OfflineUserDataJobServiceClient._DEFAULT_UNIVERSE + + offline_user_data_job_path = staticmethod( + OfflineUserDataJobServiceClient.offline_user_data_job_path + ) + parse_offline_user_data_job_path = staticmethod( + OfflineUserDataJobServiceClient.parse_offline_user_data_job_path + ) + common_billing_account_path = staticmethod( + OfflineUserDataJobServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + OfflineUserDataJobServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + OfflineUserDataJobServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + OfflineUserDataJobServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + OfflineUserDataJobServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + OfflineUserDataJobServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + OfflineUserDataJobServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + OfflineUserDataJobServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + OfflineUserDataJobServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + OfflineUserDataJobServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + OfflineUserDataJobServiceAsyncClient: The constructed client. + """ + return OfflineUserDataJobServiceClient.from_service_account_info.__func__(OfflineUserDataJobServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + OfflineUserDataJobServiceAsyncClient: The constructed client. + """ + return OfflineUserDataJobServiceClient.from_service_account_file.__func__(OfflineUserDataJobServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return OfflineUserDataJobServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> OfflineUserDataJobServiceTransport: + """Returns the transport used by the client instance. + + Returns: + OfflineUserDataJobServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = OfflineUserDataJobServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + OfflineUserDataJobServiceTransport, + Callable[..., OfflineUserDataJobServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the offline user data job service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,OfflineUserDataJobServiceTransport,Callable[..., OfflineUserDataJobServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the OfflineUserDataJobServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = OfflineUserDataJobServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.OfflineUserDataJobServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.OfflineUserDataJobService", + "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.ads.googleads.v23.services.OfflineUserDataJobService", + "credentialsType": None, + } + ), + ) + + async def create_offline_user_data_job( + self, + request: Optional[ + Union[ + offline_user_data_job_service.CreateOfflineUserDataJobRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + job: Optional[offline_user_data_job.OfflineUserDataJob] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> offline_user_data_job_service.CreateOfflineUserDataJobResponse: + r"""Creates an offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `NotAllowlistedError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.CreateOfflineUserDataJobRequest, dict]]): + The request object. Request message for + [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v23.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. + customer_id (:class:`str`): + Required. The ID of the customer for + which to create an offline user data + job. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + job (:class:`google.ads.googleads.v23.resources.types.OfflineUserDataJob`): + Required. The offline user data job + to be created. + + This corresponds to the ``job`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateOfflineUserDataJobResponse: + Response message for + [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v23.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, job] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + offline_user_data_job_service.CreateOfflineUserDataJobRequest, + ): + request = ( + offline_user_data_job_service.CreateOfflineUserDataJobRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if job is not None: + request.job = job + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_offline_user_data_job + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def add_offline_user_data_job_operations( + self, + request: Optional[ + Union[ + offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest, + dict, + ] + ] = None, + *, + resource_name: Optional[str] = None, + operations: Optional[ + MutableSequence[ + offline_user_data_job_service.OfflineUserDataJobOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse: + r"""Adds operations to the offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.AddOfflineUserDataJobOperationsRequest, dict]]): + The request object. Request message for + [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v23.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. + resource_name (:class:`str`): + Required. The resource name of the + OfflineUserDataJob. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.OfflineUserDataJobOperation]`): + Required. The list of operations to + be done. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.AddOfflineUserDataJobOperationsResponse: + Response message for + [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v23.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest, + ): + request = offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.add_offline_user_data_job_operations + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def run_offline_user_data_job( + self, + request: Optional[ + Union[ + offline_user_data_job_service.RunOfflineUserDataJobRequest, dict + ] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation_async.AsyncOperation: + r"""Runs the offline user data job. + + When finished, the long running operation will contain the + processing result or failure information, if any. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.RunOfflineUserDataJobRequest, dict]]): + The request object. Request message for + [OfflineUserDataJobService.RunOfflineUserDataJob][google.ads.googleads.v23.services.OfflineUserDataJobService.RunOfflineUserDataJob]. + resource_name (:class:`str`): + Required. The resource name of the + OfflineUserDataJob to run. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, offline_user_data_job_service.RunOfflineUserDataJobRequest + ): + request = ( + offline_user_data_job_service.RunOfflineUserDataJobRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.run_offline_user_data_job + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + empty_pb2.Empty, + metadata_type=offline_user_data_job.OfflineUserDataJobMetadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "OfflineUserDataJobServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("OfflineUserDataJobServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/offline_user_data_job_service/client.py b/google/ads/googleads/v23/services/services/offline_user_data_job_service/client.py new file mode 100644 index 000000000..16d60f323 --- /dev/null +++ b/google/ads/googleads/v23/services/services/offline_user_data_job_service/client.py @@ -0,0 +1,1160 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.resources.types import offline_user_data_job +from google.ads.googleads.v23.services.types import ( + offline_user_data_job_service, +) +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + OfflineUserDataJobServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import OfflineUserDataJobServiceGrpcTransport +from .transports.grpc_asyncio import ( + OfflineUserDataJobServiceGrpcAsyncIOTransport, +) + + +class OfflineUserDataJobServiceClientMeta(type): + """Metaclass for the OfflineUserDataJobService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[OfflineUserDataJobServiceTransport]] + _transport_registry["grpc"] = OfflineUserDataJobServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + OfflineUserDataJobServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[OfflineUserDataJobServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class OfflineUserDataJobServiceClient( + metaclass=OfflineUserDataJobServiceClientMeta +): + """Service to manage offline user data jobs.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + OfflineUserDataJobServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + OfflineUserDataJobServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> OfflineUserDataJobServiceTransport: + """Returns the transport used by the client instance. + + Returns: + OfflineUserDataJobServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def offline_user_data_job_path( + customer_id: str, + offline_user_data_update_id: str, + ) -> str: + """Returns a fully-qualified offline_user_data_job string.""" + return "customers/{customer_id}/offlineUserDataJobs/{offline_user_data_update_id}".format( + customer_id=customer_id, + offline_user_data_update_id=offline_user_data_update_id, + ) + + @staticmethod + def parse_offline_user_data_job_path(path: str) -> Dict[str, str]: + """Parses a offline_user_data_job path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/offlineUserDataJobs/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + OfflineUserDataJobServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + OfflineUserDataJobServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + OfflineUserDataJobServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = OfflineUserDataJobServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = OfflineUserDataJobServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = OfflineUserDataJobServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + OfflineUserDataJobServiceTransport, + Callable[..., OfflineUserDataJobServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the offline user data job service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,OfflineUserDataJobServiceTransport,Callable[..., OfflineUserDataJobServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the OfflineUserDataJobServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = OfflineUserDataJobServiceClient._read_environment_variables() + self._client_cert_source = ( + OfflineUserDataJobServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + OfflineUserDataJobServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, OfflineUserDataJobServiceTransport + ) + if transport_provided: + # transport is a OfflineUserDataJobServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + OfflineUserDataJobServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or OfflineUserDataJobServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[OfflineUserDataJobServiceTransport], + Callable[..., OfflineUserDataJobServiceTransport], + ] = ( + OfflineUserDataJobServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., OfflineUserDataJobServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.OfflineUserDataJobServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.OfflineUserDataJobService", + "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.ads.googleads.v23.services.OfflineUserDataJobService", + "credentialsType": None, + } + ), + ) + + def create_offline_user_data_job( + self, + request: Optional[ + Union[ + offline_user_data_job_service.CreateOfflineUserDataJobRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + job: Optional[offline_user_data_job.OfflineUserDataJob] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> offline_user_data_job_service.CreateOfflineUserDataJobResponse: + r"""Creates an offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `NotAllowlistedError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.CreateOfflineUserDataJobRequest, dict]): + The request object. Request message for + [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v23.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. + customer_id (str): + Required. The ID of the customer for + which to create an offline user data + job. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + job (google.ads.googleads.v23.resources.types.OfflineUserDataJob): + Required. The offline user data job + to be created. + + This corresponds to the ``job`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateOfflineUserDataJobResponse: + Response message for + [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v23.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, job] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + offline_user_data_job_service.CreateOfflineUserDataJobRequest, + ): + request = ( + offline_user_data_job_service.CreateOfflineUserDataJobRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if job is not None: + request.job = job + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_offline_user_data_job + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def add_offline_user_data_job_operations( + self, + request: Optional[ + Union[ + offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest, + dict, + ] + ] = None, + *, + resource_name: Optional[str] = None, + operations: Optional[ + MutableSequence[ + offline_user_data_job_service.OfflineUserDataJobOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse: + r"""Adds operations to the offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.AddOfflineUserDataJobOperationsRequest, dict]): + The request object. Request message for + [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v23.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. + resource_name (str): + Required. The resource name of the + OfflineUserDataJob. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.OfflineUserDataJobOperation]): + Required. The list of operations to + be done. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.AddOfflineUserDataJobOperationsResponse: + Response message for + [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v23.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest, + ): + request = offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.add_offline_user_data_job_operations + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def run_offline_user_data_job( + self, + request: Optional[ + Union[ + offline_user_data_job_service.RunOfflineUserDataJobRequest, dict + ] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> operation.Operation: + r"""Runs the offline user data job. + + When finished, the long running operation will contain the + processing result or failure information, if any. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.RunOfflineUserDataJobRequest, dict]): + The request object. Request message for + [OfflineUserDataJobService.RunOfflineUserDataJob][google.ads.googleads.v23.services.OfflineUserDataJobService.RunOfflineUserDataJob]. + resource_name (str): + Required. The resource name of the + OfflineUserDataJob to run. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.protobuf.empty_pb2.Empty` A generic empty message that you can re-use to avoid defining duplicated + empty messages in your APIs. A typical example is to + use it as the request or the response type of an API + method. For instance: + + service Foo { + rpc Bar(google.protobuf.Empty) returns + (google.protobuf.Empty); + + } + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, offline_user_data_job_service.RunOfflineUserDataJobRequest + ): + request = ( + offline_user_data_job_service.RunOfflineUserDataJobRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.run_offline_user_data_job + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + empty_pb2.Empty, + metadata_type=offline_user_data_job.OfflineUserDataJobMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "OfflineUserDataJobServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("OfflineUserDataJobServiceClient",) diff --git a/google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/README.rst b/google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/README.rst rename to google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/__init__.py b/google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/offline_user_data_job_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/base.py b/google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/base.py new file mode 100644 index 000000000..5e7eeba40 --- /dev/null +++ b/google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/base.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + offline_user_data_job_service, +) +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class OfflineUserDataJobServiceTransport(abc.ABC): + """Abstract transport class for OfflineUserDataJobService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_offline_user_data_job: gapic_v1.method.wrap_method( + self.create_offline_user_data_job, + default_timeout=None, + client_info=client_info, + ), + self.add_offline_user_data_job_operations: gapic_v1.method.wrap_method( + self.add_offline_user_data_job_operations, + default_timeout=None, + client_info=client_info, + ), + self.run_offline_user_data_job: gapic_v1.method.wrap_method( + self.run_offline_user_data_job, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + + @property + def create_offline_user_data_job( + self, + ) -> Callable[ + [offline_user_data_job_service.CreateOfflineUserDataJobRequest], + Union[ + offline_user_data_job_service.CreateOfflineUserDataJobResponse, + Awaitable[ + offline_user_data_job_service.CreateOfflineUserDataJobResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def add_offline_user_data_job_operations( + self, + ) -> Callable[ + [offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest], + Union[ + offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse, + Awaitable[ + offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def run_offline_user_data_job( + self, + ) -> Callable[ + [offline_user_data_job_service.RunOfflineUserDataJobRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("OfflineUserDataJobServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/grpc.py b/google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/grpc.py new file mode 100644 index 000000000..7db2490b4 --- /dev/null +++ b/google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/grpc.py @@ -0,0 +1,490 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import operations_v1 +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + offline_user_data_job_service, +) +from google.longrunning import operations_pb2 # type: ignore +from .base import OfflineUserDataJobServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.OfflineUserDataJobService", + "rpcName": str(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.ads.googleads.v23.services.OfflineUserDataJobService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class OfflineUserDataJobServiceGrpcTransport( + OfflineUserDataJobServiceTransport +): + """gRPC backend transport for OfflineUserDataJobService. + + Service to manage offline user data jobs. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # 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._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_offline_user_data_job( + self, + ) -> Callable[ + [offline_user_data_job_service.CreateOfflineUserDataJobRequest], + offline_user_data_job_service.CreateOfflineUserDataJobResponse, + ]: + r"""Return a callable for the create offline user data job method over gRPC. + + Creates an offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `NotAllowlistedError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.CreateOfflineUserDataJobRequest], + ~.CreateOfflineUserDataJobResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_offline_user_data_job" not in self._stubs: + self._stubs["create_offline_user_data_job"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.OfflineUserDataJobService/CreateOfflineUserDataJob", + request_serializer=offline_user_data_job_service.CreateOfflineUserDataJobRequest.serialize, + response_deserializer=offline_user_data_job_service.CreateOfflineUserDataJobResponse.deserialize, + ) + ) + return self._stubs["create_offline_user_data_job"] + + @property + def add_offline_user_data_job_operations( + self, + ) -> Callable[ + [offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest], + offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse, + ]: + r"""Return a callable for the add offline user data job + operations method over gRPC. + + Adds operations to the offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.AddOfflineUserDataJobOperationsRequest], + ~.AddOfflineUserDataJobOperationsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "add_offline_user_data_job_operations" not in self._stubs: + self._stubs["add_offline_user_data_job_operations"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.OfflineUserDataJobService/AddOfflineUserDataJobOperations", + request_serializer=offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest.serialize, + response_deserializer=offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse.deserialize, + ) + ) + return self._stubs["add_offline_user_data_job_operations"] + + @property + def run_offline_user_data_job( + self, + ) -> Callable[ + [offline_user_data_job_service.RunOfflineUserDataJobRequest], + operations_pb2.Operation, + ]: + r"""Return a callable for the run offline user data job method over gRPC. + + Runs the offline user data job. + + When finished, the long running operation will contain the + processing result or failure information, if any. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.RunOfflineUserDataJobRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "run_offline_user_data_job" not in self._stubs: + self._stubs["run_offline_user_data_job"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.OfflineUserDataJobService/RunOfflineUserDataJob", + request_serializer=offline_user_data_job_service.RunOfflineUserDataJobRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["run_offline_user_data_job"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("OfflineUserDataJobServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..db311c007 --- /dev/null +++ b/google/ads/googleads/v23/services/services/offline_user_data_job_service/transports/grpc_asyncio.py @@ -0,0 +1,527 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.api_core import operations_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + offline_user_data_job_service, +) +from google.longrunning import operations_pb2 # type: ignore +from .base import OfflineUserDataJobServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.OfflineUserDataJobService", + "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.ads.googleads.v23.services.OfflineUserDataJobService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class OfflineUserDataJobServiceGrpcAsyncIOTransport( + OfflineUserDataJobServiceTransport +): + """gRPC AsyncIO backend transport for OfflineUserDataJobService. + + Service to manage offline user data jobs. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[ + operations_v1.OperationsAsyncClient + ] = None + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # 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._logged_channel + ) + + # Return the client from cache. + return self._operations_client + + @property + def create_offline_user_data_job( + self, + ) -> Callable[ + [offline_user_data_job_service.CreateOfflineUserDataJobRequest], + Awaitable[ + offline_user_data_job_service.CreateOfflineUserDataJobResponse + ], + ]: + r"""Return a callable for the create offline user data job method over gRPC. + + Creates an offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `NotAllowlistedError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.CreateOfflineUserDataJobRequest], + Awaitable[~.CreateOfflineUserDataJobResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_offline_user_data_job" not in self._stubs: + self._stubs["create_offline_user_data_job"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.OfflineUserDataJobService/CreateOfflineUserDataJob", + request_serializer=offline_user_data_job_service.CreateOfflineUserDataJobRequest.serialize, + response_deserializer=offline_user_data_job_service.CreateOfflineUserDataJobResponse.deserialize, + ) + ) + return self._stubs["create_offline_user_data_job"] + + @property + def add_offline_user_data_job_operations( + self, + ) -> Callable[ + [offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest], + Awaitable[ + offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse + ], + ]: + r"""Return a callable for the add offline user data job + operations method over gRPC. + + Adds operations to the offline user data job. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.AddOfflineUserDataJobOperationsRequest], + Awaitable[~.AddOfflineUserDataJobOperationsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "add_offline_user_data_job_operations" not in self._stubs: + self._stubs["add_offline_user_data_job_operations"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.OfflineUserDataJobService/AddOfflineUserDataJobOperations", + request_serializer=offline_user_data_job_service.AddOfflineUserDataJobOperationsRequest.serialize, + response_deserializer=offline_user_data_job_service.AddOfflineUserDataJobOperationsResponse.deserialize, + ) + ) + return self._stubs["add_offline_user_data_job_operations"] + + @property + def run_offline_user_data_job( + self, + ) -> Callable[ + [offline_user_data_job_service.RunOfflineUserDataJobRequest], + Awaitable[operations_pb2.Operation], + ]: + r"""Return a callable for the run offline user data job method over gRPC. + + Runs the offline user data job. + + When finished, the long running operation will contain the + processing result or failure information, if any. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ + `HeaderError <>`__ `InternalError <>`__ + `OfflineUserDataJobError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.RunOfflineUserDataJobRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "run_offline_user_data_job" not in self._stubs: + self._stubs["run_offline_user_data_job"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.OfflineUserDataJobService/RunOfflineUserDataJob", + request_serializer=offline_user_data_job_service.RunOfflineUserDataJobRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + ) + return self._stubs["run_offline_user_data_job"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.create_offline_user_data_job: self._wrap_method( + self.create_offline_user_data_job, + default_timeout=None, + client_info=client_info, + ), + self.add_offline_user_data_job_operations: self._wrap_method( + self.add_offline_user_data_job_operations, + default_timeout=None, + client_info=client_info, + ), + self.run_offline_user_data_job: self._wrap_method( + self.run_offline_user_data_job, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("OfflineUserDataJobServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/payments_account_service/__init__.py b/google/ads/googleads/v23/services/services/payments_account_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/payments_account_service/__init__.py rename to google/ads/googleads/v23/services/services/payments_account_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/payments_account_service/async_client.py b/google/ads/googleads/v23/services/services/payments_account_service/async_client.py new file mode 100644 index 000000000..05fe0371e --- /dev/null +++ b/google/ads/googleads/v23/services/services/payments_account_service/async_client.py @@ -0,0 +1,423 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import payments_account_service +from .transports.base import ( + PaymentsAccountServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import PaymentsAccountServiceClient + +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 PaymentsAccountServiceAsyncClient: + """Service to provide payments accounts that can be used to set + up consolidated billing. + """ + + _client: PaymentsAccountServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = PaymentsAccountServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = PaymentsAccountServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + PaymentsAccountServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = PaymentsAccountServiceClient._DEFAULT_UNIVERSE + + customer_path = staticmethod(PaymentsAccountServiceClient.customer_path) + parse_customer_path = staticmethod( + PaymentsAccountServiceClient.parse_customer_path + ) + payments_account_path = staticmethod( + PaymentsAccountServiceClient.payments_account_path + ) + parse_payments_account_path = staticmethod( + PaymentsAccountServiceClient.parse_payments_account_path + ) + common_billing_account_path = staticmethod( + PaymentsAccountServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + PaymentsAccountServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + PaymentsAccountServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + PaymentsAccountServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + PaymentsAccountServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + PaymentsAccountServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + PaymentsAccountServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + PaymentsAccountServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + PaymentsAccountServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + PaymentsAccountServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + PaymentsAccountServiceAsyncClient: The constructed client. + """ + return PaymentsAccountServiceClient.from_service_account_info.__func__(PaymentsAccountServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + PaymentsAccountServiceAsyncClient: The constructed client. + """ + return PaymentsAccountServiceClient.from_service_account_file.__func__(PaymentsAccountServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return PaymentsAccountServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> PaymentsAccountServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PaymentsAccountServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = PaymentsAccountServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + PaymentsAccountServiceTransport, + Callable[..., PaymentsAccountServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the payments account service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,PaymentsAccountServiceTransport,Callable[..., PaymentsAccountServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the PaymentsAccountServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = PaymentsAccountServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.PaymentsAccountServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.PaymentsAccountService", + "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.ads.googleads.v23.services.PaymentsAccountService", + "credentialsType": None, + } + ), + ) + + async def list_payments_accounts( + self, + request: Optional[ + Union[payments_account_service.ListPaymentsAccountsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> payments_account_service.ListPaymentsAccountsResponse: + r"""Returns all payments accounts associated with all managers + between the login customer ID and specified serving customer in + the hierarchy, inclusive. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PaymentsAccountError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListPaymentsAccountsRequest, dict]]): + The request object. Request message for fetching all + accessible payments accounts. + customer_id (:class:`str`): + Required. The ID of the customer to + apply the PaymentsAccount list operation + to. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListPaymentsAccountsResponse: + Response message for + [PaymentsAccountService.ListPaymentsAccounts][google.ads.googleads.v23.services.PaymentsAccountService.ListPaymentsAccounts]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, payments_account_service.ListPaymentsAccountsRequest + ): + request = payments_account_service.ListPaymentsAccountsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_payments_accounts + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "PaymentsAccountServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("PaymentsAccountServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/payments_account_service/client.py b/google/ads/googleads/v23/services/services/payments_account_service/client.py new file mode 100644 index 000000000..8c1f94caa --- /dev/null +++ b/google/ads/googleads/v23/services/services/payments_account_service/client.py @@ -0,0 +1,900 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import payments_account_service +from .transports.base import ( + PaymentsAccountServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import PaymentsAccountServiceGrpcTransport +from .transports.grpc_asyncio import PaymentsAccountServiceGrpcAsyncIOTransport + + +class PaymentsAccountServiceClientMeta(type): + """Metaclass for the PaymentsAccountService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[PaymentsAccountServiceTransport]] + _transport_registry["grpc"] = PaymentsAccountServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + PaymentsAccountServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[PaymentsAccountServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class PaymentsAccountServiceClient(metaclass=PaymentsAccountServiceClientMeta): + """Service to provide payments accounts that can be used to set + up consolidated billing. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + PaymentsAccountServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + PaymentsAccountServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> PaymentsAccountServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PaymentsAccountServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def payments_account_path( + customer_id: str, + payments_account_id: str, + ) -> str: + """Returns a fully-qualified payments_account string.""" + return "customers/{customer_id}/paymentsAccounts/{payments_account_id}".format( + customer_id=customer_id, + payments_account_id=payments_account_id, + ) + + @staticmethod + def parse_payments_account_path(path: str) -> Dict[str, str]: + """Parses a payments_account path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/paymentsAccounts/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + PaymentsAccountServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + PaymentsAccountServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = PaymentsAccountServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = PaymentsAccountServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + PaymentsAccountServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = PaymentsAccountServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + PaymentsAccountServiceTransport, + Callable[..., PaymentsAccountServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the payments account service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,PaymentsAccountServiceTransport,Callable[..., PaymentsAccountServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the PaymentsAccountServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = PaymentsAccountServiceClient._read_environment_variables() + self._client_cert_source = ( + PaymentsAccountServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + PaymentsAccountServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, PaymentsAccountServiceTransport + ) + if transport_provided: + # transport is a PaymentsAccountServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(PaymentsAccountServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or PaymentsAccountServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[PaymentsAccountServiceTransport], + Callable[..., PaymentsAccountServiceTransport], + ] = ( + PaymentsAccountServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., PaymentsAccountServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.PaymentsAccountServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.PaymentsAccountService", + "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.ads.googleads.v23.services.PaymentsAccountService", + "credentialsType": None, + } + ), + ) + + def list_payments_accounts( + self, + request: Optional[ + Union[payments_account_service.ListPaymentsAccountsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> payments_account_service.ListPaymentsAccountsResponse: + r"""Returns all payments accounts associated with all managers + between the login customer ID and specified serving customer in + the hierarchy, inclusive. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PaymentsAccountError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListPaymentsAccountsRequest, dict]): + The request object. Request message for fetching all + accessible payments accounts. + customer_id (str): + Required. The ID of the customer to + apply the PaymentsAccount list operation + to. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListPaymentsAccountsResponse: + Response message for + [PaymentsAccountService.ListPaymentsAccounts][google.ads.googleads.v23.services.PaymentsAccountService.ListPaymentsAccounts]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, payments_account_service.ListPaymentsAccountsRequest + ): + request = payments_account_service.ListPaymentsAccountsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_payments_accounts + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "PaymentsAccountServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("PaymentsAccountServiceClient",) diff --git a/google/ads/googleads/v19/services/services/payments_account_service/transports/README.rst b/google/ads/googleads/v23/services/services/payments_account_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/payments_account_service/transports/README.rst rename to google/ads/googleads/v23/services/services/payments_account_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/payments_account_service/transports/__init__.py b/google/ads/googleads/v23/services/services/payments_account_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/payments_account_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/payments_account_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/payments_account_service/transports/base.py b/google/ads/googleads/v23/services/services/payments_account_service/transports/base.py new file mode 100644 index 000000000..ccb225960 --- /dev/null +++ b/google/ads/googleads/v23/services/services/payments_account_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import payments_account_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class PaymentsAccountServiceTransport(abc.ABC): + """Abstract transport class for PaymentsAccountService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.list_payments_accounts: gapic_v1.method.wrap_method( + self.list_payments_accounts, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def list_payments_accounts( + self, + ) -> Callable[ + [payments_account_service.ListPaymentsAccountsRequest], + Union[ + payments_account_service.ListPaymentsAccountsResponse, + Awaitable[payments_account_service.ListPaymentsAccountsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("PaymentsAccountServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/payments_account_service/transports/grpc.py b/google/ads/googleads/v23/services/services/payments_account_service/transports/grpc.py new file mode 100644 index 000000000..b9a62f646 --- /dev/null +++ b/google/ads/googleads/v23/services/services/payments_account_service/transports/grpc.py @@ -0,0 +1,391 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import payments_account_service +from .base import PaymentsAccountServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.PaymentsAccountService", + "rpcName": str(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.ads.googleads.v23.services.PaymentsAccountService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class PaymentsAccountServiceGrpcTransport(PaymentsAccountServiceTransport): + """gRPC backend transport for PaymentsAccountService. + + Service to provide payments accounts that can be used to set + up consolidated billing. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def list_payments_accounts( + self, + ) -> Callable[ + [payments_account_service.ListPaymentsAccountsRequest], + payments_account_service.ListPaymentsAccountsResponse, + ]: + r"""Return a callable for the list payments accounts method over gRPC. + + Returns all payments accounts associated with all managers + between the login customer ID and specified serving customer in + the hierarchy, inclusive. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PaymentsAccountError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListPaymentsAccountsRequest], + ~.ListPaymentsAccountsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_payments_accounts" not in self._stubs: + self._stubs["list_payments_accounts"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.PaymentsAccountService/ListPaymentsAccounts", + request_serializer=payments_account_service.ListPaymentsAccountsRequest.serialize, + response_deserializer=payments_account_service.ListPaymentsAccountsResponse.deserialize, + ) + ) + return self._stubs["list_payments_accounts"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("PaymentsAccountServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/payments_account_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/payments_account_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..1d854acdd --- /dev/null +++ b/google/ads/googleads/v23/services/services/payments_account_service/transports/grpc_asyncio.py @@ -0,0 +1,414 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import payments_account_service +from .base import PaymentsAccountServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.PaymentsAccountService", + "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.ads.googleads.v23.services.PaymentsAccountService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class PaymentsAccountServiceGrpcAsyncIOTransport( + PaymentsAccountServiceTransport +): + """gRPC AsyncIO backend transport for PaymentsAccountService. + + Service to provide payments accounts that can be used to set + up consolidated billing. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def list_payments_accounts( + self, + ) -> Callable[ + [payments_account_service.ListPaymentsAccountsRequest], + Awaitable[payments_account_service.ListPaymentsAccountsResponse], + ]: + r"""Return a callable for the list payments accounts method over gRPC. + + Returns all payments accounts associated with all managers + between the login customer ID and specified serving customer in + the hierarchy, inclusive. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `PaymentsAccountError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListPaymentsAccountsRequest], + Awaitable[~.ListPaymentsAccountsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_payments_accounts" not in self._stubs: + self._stubs["list_payments_accounts"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.PaymentsAccountService/ListPaymentsAccounts", + request_serializer=payments_account_service.ListPaymentsAccountsRequest.serialize, + response_deserializer=payments_account_service.ListPaymentsAccountsResponse.deserialize, + ) + ) + return self._stubs["list_payments_accounts"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.list_payments_accounts: self._wrap_method( + self.list_payments_accounts, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("PaymentsAccountServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/product_link_invitation_service/__init__.py b/google/ads/googleads/v23/services/services/product_link_invitation_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/product_link_invitation_service/__init__.py rename to google/ads/googleads/v23/services/services/product_link_invitation_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/product_link_invitation_service/async_client.py b/google/ads/googleads/v23/services/services/product_link_invitation_service/async_client.py new file mode 100644 index 000000000..e9484276e --- /dev/null +++ b/google/ads/googleads/v23/services/services/product_link_invitation_service/async_client.py @@ -0,0 +1,677 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.enums.types import ( + product_link_invitation_status as gage_product_link_invitation_status, +) +from google.ads.googleads.v23.resources.types import ( + product_link_invitation as gagr_product_link_invitation, +) +from google.ads.googleads.v23.services.types import ( + product_link_invitation_service, +) +from .transports.base import ( + ProductLinkInvitationServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import ProductLinkInvitationServiceClient + +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 ProductLinkInvitationServiceAsyncClient: + """This service allows management of product link invitations + from Google Ads accounts to other accounts. + """ + + _client: ProductLinkInvitationServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ProductLinkInvitationServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + ProductLinkInvitationServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + ProductLinkInvitationServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ProductLinkInvitationServiceClient._DEFAULT_UNIVERSE + + customer_path = staticmethod( + ProductLinkInvitationServiceClient.customer_path + ) + parse_customer_path = staticmethod( + ProductLinkInvitationServiceClient.parse_customer_path + ) + product_link_invitation_path = staticmethod( + ProductLinkInvitationServiceClient.product_link_invitation_path + ) + parse_product_link_invitation_path = staticmethod( + ProductLinkInvitationServiceClient.parse_product_link_invitation_path + ) + common_billing_account_path = staticmethod( + ProductLinkInvitationServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ProductLinkInvitationServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ProductLinkInvitationServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ProductLinkInvitationServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ProductLinkInvitationServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ProductLinkInvitationServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ProductLinkInvitationServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ProductLinkInvitationServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ProductLinkInvitationServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ProductLinkInvitationServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductLinkInvitationServiceAsyncClient: The constructed client. + """ + return ProductLinkInvitationServiceClient.from_service_account_info.__func__(ProductLinkInvitationServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductLinkInvitationServiceAsyncClient: The constructed client. + """ + return ProductLinkInvitationServiceClient.from_service_account_file.__func__(ProductLinkInvitationServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ProductLinkInvitationServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ProductLinkInvitationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductLinkInvitationServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ProductLinkInvitationServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ProductLinkInvitationServiceTransport, + Callable[..., ProductLinkInvitationServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product link invitation service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ProductLinkInvitationServiceTransport,Callable[..., ProductLinkInvitationServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ProductLinkInvitationServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ProductLinkInvitationServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ProductLinkInvitationServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ProductLinkInvitationService", + "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.ads.googleads.v23.services.ProductLinkInvitationService", + "credentialsType": None, + } + ), + ) + + async def create_product_link_invitation( + self, + request: Optional[ + Union[ + product_link_invitation_service.CreateProductLinkInvitationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + product_link_invitation: Optional[ + gagr_product_link_invitation.ProductLinkInvitation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> product_link_invitation_service.CreateProductLinkInvitationResponse: + r"""Creates a product link invitation. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.CreateProductLinkInvitationRequest, dict]]): + The request object. Request message for + [ProductLinkInvitationService.CreateProductLinkInvitation][google.ads.googleads.v23.services.ProductLinkInvitationService.CreateProductLinkInvitation]. + customer_id (:class:`str`): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_link_invitation (:class:`google.ads.googleads.v23.resources.types.ProductLinkInvitation`): + Required. The product link invitation + to be created. + + This corresponds to the ``product_link_invitation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateProductLinkInvitationResponse: + Response message for product link + invitation create. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, product_link_invitation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + product_link_invitation_service.CreateProductLinkInvitationRequest, + ): + request = product_link_invitation_service.CreateProductLinkInvitationRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if product_link_invitation is not None: + request.product_link_invitation = product_link_invitation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_product_link_invitation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_product_link_invitation( + self, + request: Optional[ + Union[ + product_link_invitation_service.UpdateProductLinkInvitationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + product_link_invitation_status: Optional[ + gage_product_link_invitation_status.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus + ] = None, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> product_link_invitation_service.UpdateProductLinkInvitationResponse: + r"""Update a product link invitation. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.UpdateProductLinkInvitationRequest, dict]]): + The request object. Request message for + [ProductLinkInvitationService.UpdateProductLinkInvitation][google.ads.googleads.v23.services.ProductLinkInvitationService.UpdateProductLinkInvitation]. + customer_id (:class:`str`): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_link_invitation_status (:class:`google.ads.googleads.v23.enums.types.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus`): + Required. The product link invitation + to be created. + + This corresponds to the ``product_link_invitation_status`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + resource_name (:class:`str`): + Required. Resource name of the + product link invitation. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UpdateProductLinkInvitationResponse: + Response message for product link + invitation update. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + product_link_invitation_status, + resource_name, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + product_link_invitation_service.UpdateProductLinkInvitationRequest, + ): + request = product_link_invitation_service.UpdateProductLinkInvitationRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if product_link_invitation_status is not None: + request.product_link_invitation_status = ( + product_link_invitation_status + ) + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.update_product_link_invitation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def remove_product_link_invitation( + self, + request: Optional[ + Union[ + product_link_invitation_service.RemoveProductLinkInvitationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> product_link_invitation_service.RemoveProductLinkInvitationResponse: + r"""Remove a product link invitation. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.RemoveProductLinkInvitationRequest, dict]]): + The request object. Request message for + [ProductLinkInvitationService.RemoveProductLinkInvitation][google.ads.googleads.v23.services.ProductLinkInvitationService.RemoveProductLinkInvitation]. + customer_id (:class:`str`): + Required. The ID of the product link + invitation being removed. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + resource_name (:class:`str`): + Required. The resource name of the product link + invitation being removed. expected, in this format: + + ``customers/{customer_id}/productLinkInvitations/{product_link_invitation_id}`` + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.RemoveProductLinkInvitationResponse: + Response message for product link + invitation removeal. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + product_link_invitation_service.RemoveProductLinkInvitationRequest, + ): + request = product_link_invitation_service.RemoveProductLinkInvitationRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.remove_product_link_invitation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ProductLinkInvitationServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ProductLinkInvitationServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/product_link_invitation_service/client.py b/google/ads/googleads/v23/services/services/product_link_invitation_service/client.py new file mode 100644 index 000000000..648bfc87a --- /dev/null +++ b/google/ads/googleads/v23/services/services/product_link_invitation_service/client.py @@ -0,0 +1,1159 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.enums.types import ( + product_link_invitation_status as gage_product_link_invitation_status, +) +from google.ads.googleads.v23.resources.types import ( + product_link_invitation as gagr_product_link_invitation, +) +from google.ads.googleads.v23.services.types import ( + product_link_invitation_service, +) +from .transports.base import ( + ProductLinkInvitationServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ProductLinkInvitationServiceGrpcTransport +from .transports.grpc_asyncio import ( + ProductLinkInvitationServiceGrpcAsyncIOTransport, +) + + +class ProductLinkInvitationServiceClientMeta(type): + """Metaclass for the ProductLinkInvitationService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ProductLinkInvitationServiceTransport]] + _transport_registry["grpc"] = ProductLinkInvitationServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + ProductLinkInvitationServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ProductLinkInvitationServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ProductLinkInvitationServiceClient( + metaclass=ProductLinkInvitationServiceClientMeta +): + """This service allows management of product link invitations + from Google Ads accounts to other accounts. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductLinkInvitationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductLinkInvitationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ProductLinkInvitationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductLinkInvitationServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_link_invitation_path( + customer_id: str, + customer_invitation_id: str, + ) -> str: + """Returns a fully-qualified product_link_invitation string.""" + return "customers/{customer_id}/productLinkInvitations/{customer_invitation_id}".format( + customer_id=customer_id, + customer_invitation_id=customer_invitation_id, + ) + + @staticmethod + def parse_product_link_invitation_path(path: str) -> Dict[str, str]: + """Parses a product_link_invitation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/productLinkInvitations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ProductLinkInvitationServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ProductLinkInvitationServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + ProductLinkInvitationServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + ProductLinkInvitationServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = ProductLinkInvitationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ProductLinkInvitationServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ProductLinkInvitationServiceTransport, + Callable[..., ProductLinkInvitationServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product link invitation service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ProductLinkInvitationServiceTransport,Callable[..., ProductLinkInvitationServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ProductLinkInvitationServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ProductLinkInvitationServiceClient._read_environment_variables() + self._client_cert_source = ( + ProductLinkInvitationServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + ProductLinkInvitationServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ProductLinkInvitationServiceTransport + ) + if transport_provided: + # transport is a ProductLinkInvitationServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + ProductLinkInvitationServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ProductLinkInvitationServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ProductLinkInvitationServiceTransport], + Callable[..., ProductLinkInvitationServiceTransport], + ] = ( + ProductLinkInvitationServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ProductLinkInvitationServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ProductLinkInvitationServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ProductLinkInvitationService", + "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.ads.googleads.v23.services.ProductLinkInvitationService", + "credentialsType": None, + } + ), + ) + + def create_product_link_invitation( + self, + request: Optional[ + Union[ + product_link_invitation_service.CreateProductLinkInvitationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + product_link_invitation: Optional[ + gagr_product_link_invitation.ProductLinkInvitation + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> product_link_invitation_service.CreateProductLinkInvitationResponse: + r"""Creates a product link invitation. + + Args: + request (Union[google.ads.googleads.v23.services.types.CreateProductLinkInvitationRequest, dict]): + The request object. Request message for + [ProductLinkInvitationService.CreateProductLinkInvitation][google.ads.googleads.v23.services.ProductLinkInvitationService.CreateProductLinkInvitation]. + customer_id (str): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_link_invitation (google.ads.googleads.v23.resources.types.ProductLinkInvitation): + Required. The product link invitation + to be created. + + This corresponds to the ``product_link_invitation`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateProductLinkInvitationResponse: + Response message for product link + invitation create. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, product_link_invitation] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + product_link_invitation_service.CreateProductLinkInvitationRequest, + ): + request = product_link_invitation_service.CreateProductLinkInvitationRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if product_link_invitation is not None: + request.product_link_invitation = product_link_invitation + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_product_link_invitation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_product_link_invitation( + self, + request: Optional[ + Union[ + product_link_invitation_service.UpdateProductLinkInvitationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + product_link_invitation_status: Optional[ + gage_product_link_invitation_status.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus + ] = None, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> product_link_invitation_service.UpdateProductLinkInvitationResponse: + r"""Update a product link invitation. + + Args: + request (Union[google.ads.googleads.v23.services.types.UpdateProductLinkInvitationRequest, dict]): + The request object. Request message for + [ProductLinkInvitationService.UpdateProductLinkInvitation][google.ads.googleads.v23.services.ProductLinkInvitationService.UpdateProductLinkInvitation]. + customer_id (str): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_link_invitation_status (google.ads.googleads.v23.enums.types.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus): + Required. The product link invitation + to be created. + + This corresponds to the ``product_link_invitation_status`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + resource_name (str): + Required. Resource name of the + product link invitation. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UpdateProductLinkInvitationResponse: + Response message for product link + invitation update. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + product_link_invitation_status, + resource_name, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + product_link_invitation_service.UpdateProductLinkInvitationRequest, + ): + request = product_link_invitation_service.UpdateProductLinkInvitationRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if product_link_invitation_status is not None: + request.product_link_invitation_status = ( + product_link_invitation_status + ) + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.update_product_link_invitation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def remove_product_link_invitation( + self, + request: Optional[ + Union[ + product_link_invitation_service.RemoveProductLinkInvitationRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> product_link_invitation_service.RemoveProductLinkInvitationResponse: + r"""Remove a product link invitation. + + Args: + request (Union[google.ads.googleads.v23.services.types.RemoveProductLinkInvitationRequest, dict]): + The request object. Request message for + [ProductLinkInvitationService.RemoveProductLinkInvitation][google.ads.googleads.v23.services.ProductLinkInvitationService.RemoveProductLinkInvitation]. + customer_id (str): + Required. The ID of the product link + invitation being removed. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + resource_name (str): + Required. The resource name of the product link + invitation being removed. expected, in this format: + + ``customers/{customer_id}/productLinkInvitations/{product_link_invitation_id}`` + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.RemoveProductLinkInvitationResponse: + Response message for product link + invitation removeal. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + product_link_invitation_service.RemoveProductLinkInvitationRequest, + ): + request = product_link_invitation_service.RemoveProductLinkInvitationRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.remove_product_link_invitation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ProductLinkInvitationServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ProductLinkInvitationServiceClient",) diff --git a/google/ads/googleads/v19/services/services/product_link_invitation_service/transports/README.rst b/google/ads/googleads/v23/services/services/product_link_invitation_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/product_link_invitation_service/transports/README.rst rename to google/ads/googleads/v23/services/services/product_link_invitation_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/product_link_invitation_service/transports/__init__.py b/google/ads/googleads/v23/services/services/product_link_invitation_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/product_link_invitation_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/product_link_invitation_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/product_link_invitation_service/transports/base.py b/google/ads/googleads/v23/services/services/product_link_invitation_service/transports/base.py new file mode 100644 index 000000000..ff557bc2c --- /dev/null +++ b/google/ads/googleads/v23/services/services/product_link_invitation_service/transports/base.py @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + product_link_invitation_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ProductLinkInvitationServiceTransport(abc.ABC): + """Abstract transport class for ProductLinkInvitationService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_product_link_invitation: gapic_v1.method.wrap_method( + self.create_product_link_invitation, + default_timeout=None, + client_info=client_info, + ), + self.update_product_link_invitation: gapic_v1.method.wrap_method( + self.update_product_link_invitation, + default_timeout=None, + client_info=client_info, + ), + self.remove_product_link_invitation: gapic_v1.method.wrap_method( + self.remove_product_link_invitation, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def create_product_link_invitation( + self, + ) -> Callable[ + [product_link_invitation_service.CreateProductLinkInvitationRequest], + Union[ + product_link_invitation_service.CreateProductLinkInvitationResponse, + Awaitable[ + product_link_invitation_service.CreateProductLinkInvitationResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def update_product_link_invitation( + self, + ) -> Callable[ + [product_link_invitation_service.UpdateProductLinkInvitationRequest], + Union[ + product_link_invitation_service.UpdateProductLinkInvitationResponse, + Awaitable[ + product_link_invitation_service.UpdateProductLinkInvitationResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def remove_product_link_invitation( + self, + ) -> Callable[ + [product_link_invitation_service.RemoveProductLinkInvitationRequest], + Union[ + product_link_invitation_service.RemoveProductLinkInvitationResponse, + Awaitable[ + product_link_invitation_service.RemoveProductLinkInvitationResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ProductLinkInvitationServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/product_link_invitation_service/transports/grpc.py b/google/ads/googleads/v23/services/services/product_link_invitation_service/transports/grpc.py new file mode 100644 index 000000000..a395fb2b5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/product_link_invitation_service/transports/grpc.py @@ -0,0 +1,450 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + product_link_invitation_service, +) +from .base import ProductLinkInvitationServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ProductLinkInvitationService", + "rpcName": str(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.ads.googleads.v23.services.ProductLinkInvitationService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ProductLinkInvitationServiceGrpcTransport( + ProductLinkInvitationServiceTransport +): + """gRPC backend transport for ProductLinkInvitationService. + + This service allows management of product link invitations + from Google Ads accounts to other accounts. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def create_product_link_invitation( + self, + ) -> Callable[ + [product_link_invitation_service.CreateProductLinkInvitationRequest], + product_link_invitation_service.CreateProductLinkInvitationResponse, + ]: + r"""Return a callable for the create product link invitation method over gRPC. + + Creates a product link invitation. + + Returns: + Callable[[~.CreateProductLinkInvitationRequest], + ~.CreateProductLinkInvitationResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_product_link_invitation" not in self._stubs: + self._stubs["create_product_link_invitation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ProductLinkInvitationService/CreateProductLinkInvitation", + request_serializer=product_link_invitation_service.CreateProductLinkInvitationRequest.serialize, + response_deserializer=product_link_invitation_service.CreateProductLinkInvitationResponse.deserialize, + ) + ) + return self._stubs["create_product_link_invitation"] + + @property + def update_product_link_invitation( + self, + ) -> Callable[ + [product_link_invitation_service.UpdateProductLinkInvitationRequest], + product_link_invitation_service.UpdateProductLinkInvitationResponse, + ]: + r"""Return a callable for the update product link invitation method over gRPC. + + Update a product link invitation. + + Returns: + Callable[[~.UpdateProductLinkInvitationRequest], + ~.UpdateProductLinkInvitationResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_product_link_invitation" not in self._stubs: + self._stubs["update_product_link_invitation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ProductLinkInvitationService/UpdateProductLinkInvitation", + request_serializer=product_link_invitation_service.UpdateProductLinkInvitationRequest.serialize, + response_deserializer=product_link_invitation_service.UpdateProductLinkInvitationResponse.deserialize, + ) + ) + return self._stubs["update_product_link_invitation"] + + @property + def remove_product_link_invitation( + self, + ) -> Callable[ + [product_link_invitation_service.RemoveProductLinkInvitationRequest], + product_link_invitation_service.RemoveProductLinkInvitationResponse, + ]: + r"""Return a callable for the remove product link invitation method over gRPC. + + Remove a product link invitation. + + Returns: + Callable[[~.RemoveProductLinkInvitationRequest], + ~.RemoveProductLinkInvitationResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "remove_product_link_invitation" not in self._stubs: + self._stubs["remove_product_link_invitation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ProductLinkInvitationService/RemoveProductLinkInvitation", + request_serializer=product_link_invitation_service.RemoveProductLinkInvitationRequest.serialize, + response_deserializer=product_link_invitation_service.RemoveProductLinkInvitationResponse.deserialize, + ) + ) + return self._stubs["remove_product_link_invitation"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ProductLinkInvitationServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/product_link_invitation_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/product_link_invitation_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..d3f8a99a6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/product_link_invitation_service/transports/grpc_asyncio.py @@ -0,0 +1,487 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + product_link_invitation_service, +) +from .base import ProductLinkInvitationServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ProductLinkInvitationService", + "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.ads.googleads.v23.services.ProductLinkInvitationService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ProductLinkInvitationServiceGrpcAsyncIOTransport( + ProductLinkInvitationServiceTransport +): + """gRPC AsyncIO backend transport for ProductLinkInvitationService. + + This service allows management of product link invitations + from Google Ads accounts to other accounts. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def create_product_link_invitation( + self, + ) -> Callable[ + [product_link_invitation_service.CreateProductLinkInvitationRequest], + Awaitable[ + product_link_invitation_service.CreateProductLinkInvitationResponse + ], + ]: + r"""Return a callable for the create product link invitation method over gRPC. + + Creates a product link invitation. + + Returns: + Callable[[~.CreateProductLinkInvitationRequest], + Awaitable[~.CreateProductLinkInvitationResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_product_link_invitation" not in self._stubs: + self._stubs["create_product_link_invitation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ProductLinkInvitationService/CreateProductLinkInvitation", + request_serializer=product_link_invitation_service.CreateProductLinkInvitationRequest.serialize, + response_deserializer=product_link_invitation_service.CreateProductLinkInvitationResponse.deserialize, + ) + ) + return self._stubs["create_product_link_invitation"] + + @property + def update_product_link_invitation( + self, + ) -> Callable[ + [product_link_invitation_service.UpdateProductLinkInvitationRequest], + Awaitable[ + product_link_invitation_service.UpdateProductLinkInvitationResponse + ], + ]: + r"""Return a callable for the update product link invitation method over gRPC. + + Update a product link invitation. + + Returns: + Callable[[~.UpdateProductLinkInvitationRequest], + Awaitable[~.UpdateProductLinkInvitationResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_product_link_invitation" not in self._stubs: + self._stubs["update_product_link_invitation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ProductLinkInvitationService/UpdateProductLinkInvitation", + request_serializer=product_link_invitation_service.UpdateProductLinkInvitationRequest.serialize, + response_deserializer=product_link_invitation_service.UpdateProductLinkInvitationResponse.deserialize, + ) + ) + return self._stubs["update_product_link_invitation"] + + @property + def remove_product_link_invitation( + self, + ) -> Callable[ + [product_link_invitation_service.RemoveProductLinkInvitationRequest], + Awaitable[ + product_link_invitation_service.RemoveProductLinkInvitationResponse + ], + ]: + r"""Return a callable for the remove product link invitation method over gRPC. + + Remove a product link invitation. + + Returns: + Callable[[~.RemoveProductLinkInvitationRequest], + Awaitable[~.RemoveProductLinkInvitationResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "remove_product_link_invitation" not in self._stubs: + self._stubs["remove_product_link_invitation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ProductLinkInvitationService/RemoveProductLinkInvitation", + request_serializer=product_link_invitation_service.RemoveProductLinkInvitationRequest.serialize, + response_deserializer=product_link_invitation_service.RemoveProductLinkInvitationResponse.deserialize, + ) + ) + return self._stubs["remove_product_link_invitation"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.create_product_link_invitation: self._wrap_method( + self.create_product_link_invitation, + default_timeout=None, + client_info=client_info, + ), + self.update_product_link_invitation: self._wrap_method( + self.update_product_link_invitation, + default_timeout=None, + client_info=client_info, + ), + self.remove_product_link_invitation: self._wrap_method( + self.remove_product_link_invitation, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ProductLinkInvitationServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/product_link_service/__init__.py b/google/ads/googleads/v23/services/services/product_link_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/product_link_service/__init__.py rename to google/ads/googleads/v23/services/services/product_link_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/product_link_service/async_client.py b/google/ads/googleads/v23/services/services/product_link_service/async_client.py new file mode 100644 index 000000000..34ceed7a8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/product_link_service/async_client.py @@ -0,0 +1,534 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.resources.types import ( + product_link as gagr_product_link, +) +from google.ads.googleads.v23.services.types import product_link_service +from .transports.base import ProductLinkServiceTransport, DEFAULT_CLIENT_INFO +from .client import ProductLinkServiceClient + +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 ProductLinkServiceAsyncClient: + """This service allows management of links between a Google + Ads customer and another product. + """ + + _client: ProductLinkServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ProductLinkServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ProductLinkServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + ProductLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ProductLinkServiceClient._DEFAULT_UNIVERSE + + customer_path = staticmethod(ProductLinkServiceClient.customer_path) + parse_customer_path = staticmethod( + ProductLinkServiceClient.parse_customer_path + ) + product_link_path = staticmethod(ProductLinkServiceClient.product_link_path) + parse_product_link_path = staticmethod( + ProductLinkServiceClient.parse_product_link_path + ) + common_billing_account_path = staticmethod( + ProductLinkServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ProductLinkServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ProductLinkServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ProductLinkServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ProductLinkServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ProductLinkServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ProductLinkServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ProductLinkServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ProductLinkServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ProductLinkServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductLinkServiceAsyncClient: The constructed client. + """ + return ProductLinkServiceClient.from_service_account_info.__func__(ProductLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductLinkServiceAsyncClient: The constructed client. + """ + return ProductLinkServiceClient.from_service_account_file.__func__(ProductLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ProductLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ProductLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductLinkServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ProductLinkServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ProductLinkServiceTransport, + Callable[..., ProductLinkServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product link service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ProductLinkServiceTransport,Callable[..., ProductLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ProductLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ProductLinkServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ProductLinkServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ProductLinkService", + "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.ads.googleads.v23.services.ProductLinkService", + "credentialsType": None, + } + ), + ) + + async def create_product_link( + self, + request: Optional[ + Union[product_link_service.CreateProductLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + product_link: Optional[gagr_product_link.ProductLink] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> product_link_service.CreateProductLinkResponse: + r"""Creates a product link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.CreateProductLinkRequest, dict]]): + The request object. Request message for + [ProductLinkService.CreateProductLink][google.ads.googleads.v23.services.ProductLinkService.CreateProductLink]. + customer_id (:class:`str`): + Required. The ID of the customer for + which the product link is created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_link (:class:`google.ads.googleads.v23.resources.types.ProductLink`): + Required. The product link to be + created. + + This corresponds to the ``product_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateProductLinkResponse: + Response message for + [ProductLinkService.CreateProductLink][google.ads.googleads.v23.services.ProductLinkService.CreateProductLink]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, product_link] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, product_link_service.CreateProductLinkRequest + ): + request = product_link_service.CreateProductLinkRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if product_link is not None: + request.product_link = product_link + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.create_product_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def remove_product_link( + self, + request: Optional[ + Union[product_link_service.RemoveProductLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> product_link_service.RemoveProductLinkResponse: + r"""Removes a product link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.RemoveProductLinkRequest, dict]]): + The request object. Request message for + [ProductLinkService.RemoveProductLink][google.ads.googleads.v23.services.ProductLinkService.RemoveProductLink]. + customer_id (:class:`str`): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + resource_name (:class:`str`): + Required. Remove operation: A resource name for the + product link to remove is expected, in this format: + + ``customers/{customer_id}/productLinks/{product_link_id}`` + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.RemoveProductLinkResponse: + Response message for product link + removal. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, product_link_service.RemoveProductLinkRequest + ): + request = product_link_service.RemoveProductLinkRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.remove_product_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ProductLinkServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ProductLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/product_link_service/client.py b/google/ads/googleads/v23/services/services/product_link_service/client.py new file mode 100644 index 000000000..1ff9f7b62 --- /dev/null +++ b/google/ads/googleads/v23/services/services/product_link_service/client.py @@ -0,0 +1,1000 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.resources.types import ( + product_link as gagr_product_link, +) +from google.ads.googleads.v23.services.types import product_link_service +from .transports.base import ProductLinkServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ProductLinkServiceGrpcTransport +from .transports.grpc_asyncio import ProductLinkServiceGrpcAsyncIOTransport + + +class ProductLinkServiceClientMeta(type): + """Metaclass for the ProductLinkService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ProductLinkServiceTransport]] + _transport_registry["grpc"] = ProductLinkServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ProductLinkServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ProductLinkServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ProductLinkServiceClient(metaclass=ProductLinkServiceClientMeta): + """This service allows management of links between a Google + Ads customer and another product. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ProductLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ProductLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def customer_path( + customer_id: str, + ) -> str: + """Returns a fully-qualified customer string.""" + return "customers/{customer_id}".format( + customer_id=customer_id, + ) + + @staticmethod + def parse_customer_path(path: str) -> Dict[str, str]: + """Parses a customer path into its component segments.""" + m = re.match(r"^customers/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_link_path( + customer_id: str, + product_link_id: str, + ) -> str: + """Returns a fully-qualified product_link string.""" + return "customers/{customer_id}/productLinks/{product_link_id}".format( + customer_id=customer_id, + product_link_id=product_link_id, + ) + + @staticmethod + def parse_product_link_path(path: str) -> Dict[str, str]: + """Parses a product_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/productLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ProductLinkServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ProductLinkServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ProductLinkServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ProductLinkServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + ProductLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ProductLinkServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ProductLinkServiceTransport, + Callable[..., ProductLinkServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ProductLinkServiceTransport,Callable[..., ProductLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ProductLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ProductLinkServiceClient._read_environment_variables() + self._client_cert_source = ( + ProductLinkServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ProductLinkServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, ProductLinkServiceTransport) + if transport_provided: + # transport is a ProductLinkServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(ProductLinkServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ProductLinkServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ProductLinkServiceTransport], + Callable[..., ProductLinkServiceTransport], + ] = ( + ProductLinkServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., ProductLinkServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ProductLinkServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ProductLinkService", + "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.ads.googleads.v23.services.ProductLinkService", + "credentialsType": None, + } + ), + ) + + def create_product_link( + self, + request: Optional[ + Union[product_link_service.CreateProductLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + product_link: Optional[gagr_product_link.ProductLink] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> product_link_service.CreateProductLinkResponse: + r"""Creates a product link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.CreateProductLinkRequest, dict]): + The request object. Request message for + [ProductLinkService.CreateProductLink][google.ads.googleads.v23.services.ProductLinkService.CreateProductLink]. + customer_id (str): + Required. The ID of the customer for + which the product link is created. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product_link (google.ads.googleads.v23.resources.types.ProductLink): + Required. The product link to be + created. + + This corresponds to the ``product_link`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.CreateProductLinkResponse: + Response message for + [ProductLinkService.CreateProductLink][google.ads.googleads.v23.services.ProductLinkService.CreateProductLink]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, product_link] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, product_link_service.CreateProductLinkRequest + ): + request = product_link_service.CreateProductLinkRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if product_link is not None: + request.product_link = product_link + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.create_product_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def remove_product_link( + self, + request: Optional[ + Union[product_link_service.RemoveProductLinkRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> product_link_service.RemoveProductLinkResponse: + r"""Removes a product link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.RemoveProductLinkRequest, dict]): + The request object. Request message for + [ProductLinkService.RemoveProductLink][google.ads.googleads.v23.services.ProductLinkService.RemoveProductLink]. + customer_id (str): + Required. The ID of the customer + being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + resource_name (str): + Required. Remove operation: A resource name for the + product link to remove is expected, in this format: + + ``customers/{customer_id}/productLinks/{product_link_id}`` + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.RemoveProductLinkResponse: + Response message for product link + removal. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, product_link_service.RemoveProductLinkRequest + ): + request = product_link_service.RemoveProductLinkRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.remove_product_link + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ProductLinkServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ProductLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/product_link_service/transports/README.rst b/google/ads/googleads/v23/services/services/product_link_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/product_link_service/transports/README.rst rename to google/ads/googleads/v23/services/services/product_link_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/product_link_service/transports/__init__.py b/google/ads/googleads/v23/services/services/product_link_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/product_link_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/product_link_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/product_link_service/transports/base.py b/google/ads/googleads/v23/services/services/product_link_service/transports/base.py new file mode 100644 index 000000000..1a31249ff --- /dev/null +++ b/google/ads/googleads/v23/services/services/product_link_service/transports/base.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import product_link_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ProductLinkServiceTransport(abc.ABC): + """Abstract transport class for ProductLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.create_product_link: gapic_v1.method.wrap_method( + self.create_product_link, + default_timeout=None, + client_info=client_info, + ), + self.remove_product_link: gapic_v1.method.wrap_method( + self.remove_product_link, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def create_product_link( + self, + ) -> Callable[ + [product_link_service.CreateProductLinkRequest], + Union[ + product_link_service.CreateProductLinkResponse, + Awaitable[product_link_service.CreateProductLinkResponse], + ], + ]: + raise NotImplementedError() + + @property + def remove_product_link( + self, + ) -> Callable[ + [product_link_service.RemoveProductLinkRequest], + Union[ + product_link_service.RemoveProductLinkResponse, + Awaitable[product_link_service.RemoveProductLinkResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ProductLinkServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/product_link_service/transports/grpc.py b/google/ads/googleads/v23/services/services/product_link_service/transports/grpc.py new file mode 100644 index 000000000..7232f99a0 --- /dev/null +++ b/google/ads/googleads/v23/services/services/product_link_service/transports/grpc.py @@ -0,0 +1,425 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import product_link_service +from .base import ProductLinkServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ProductLinkService", + "rpcName": str(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.ads.googleads.v23.services.ProductLinkService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ProductLinkServiceGrpcTransport(ProductLinkServiceTransport): + """gRPC backend transport for ProductLinkService. + + This service allows management of links between a Google + Ads customer and another product. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def create_product_link( + self, + ) -> Callable[ + [product_link_service.CreateProductLinkRequest], + product_link_service.CreateProductLinkResponse, + ]: + r"""Return a callable for the create product link method over gRPC. + + Creates a product link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.CreateProductLinkRequest], + ~.CreateProductLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_product_link" not in self._stubs: + self._stubs["create_product_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ProductLinkService/CreateProductLink", + request_serializer=product_link_service.CreateProductLinkRequest.serialize, + response_deserializer=product_link_service.CreateProductLinkResponse.deserialize, + ) + ) + return self._stubs["create_product_link"] + + @property + def remove_product_link( + self, + ) -> Callable[ + [product_link_service.RemoveProductLinkRequest], + product_link_service.RemoveProductLinkResponse, + ]: + r"""Return a callable for the remove product link method over gRPC. + + Removes a product link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.RemoveProductLinkRequest], + ~.RemoveProductLinkResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "remove_product_link" not in self._stubs: + self._stubs["remove_product_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ProductLinkService/RemoveProductLink", + request_serializer=product_link_service.RemoveProductLinkRequest.serialize, + response_deserializer=product_link_service.RemoveProductLinkResponse.deserialize, + ) + ) + return self._stubs["remove_product_link"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ProductLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/product_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/product_link_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..eef7208d1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/product_link_service/transports/grpc_asyncio.py @@ -0,0 +1,451 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import product_link_service +from .base import ProductLinkServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ProductLinkService", + "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.ads.googleads.v23.services.ProductLinkService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ProductLinkServiceGrpcAsyncIOTransport(ProductLinkServiceTransport): + """gRPC AsyncIO backend transport for ProductLinkService. + + This service allows management of links between a Google + Ads customer and another product. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def create_product_link( + self, + ) -> Callable[ + [product_link_service.CreateProductLinkRequest], + Awaitable[product_link_service.CreateProductLinkResponse], + ]: + r"""Return a callable for the create product link method over gRPC. + + Creates a product link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.CreateProductLinkRequest], + Awaitable[~.CreateProductLinkResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_product_link" not in self._stubs: + self._stubs["create_product_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ProductLinkService/CreateProductLink", + request_serializer=product_link_service.CreateProductLinkRequest.serialize, + response_deserializer=product_link_service.CreateProductLinkResponse.deserialize, + ) + ) + return self._stubs["create_product_link"] + + @property + def remove_product_link( + self, + ) -> Callable[ + [product_link_service.RemoveProductLinkRequest], + Awaitable[product_link_service.RemoveProductLinkResponse], + ]: + r"""Return a callable for the remove product link method over gRPC. + + Removes a product link. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.RemoveProductLinkRequest], + Awaitable[~.RemoveProductLinkResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "remove_product_link" not in self._stubs: + self._stubs["remove_product_link"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ProductLinkService/RemoveProductLink", + request_serializer=product_link_service.RemoveProductLinkRequest.serialize, + response_deserializer=product_link_service.RemoveProductLinkResponse.deserialize, + ) + ) + return self._stubs["remove_product_link"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.create_product_link: self._wrap_method( + self.create_product_link, + default_timeout=None, + client_info=client_info, + ), + self.remove_product_link: self._wrap_method( + self.remove_product_link, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ProductLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/reach_plan_service/__init__.py b/google/ads/googleads/v23/services/services/reach_plan_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/reach_plan_service/__init__.py rename to google/ads/googleads/v23/services/services/reach_plan_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/reach_plan_service/async_client.py b/google/ads/googleads/v23/services/services/reach_plan_service/async_client.py new file mode 100644 index 000000000..222ab7ec5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/reach_plan_service/async_client.py @@ -0,0 +1,850 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import reach_plan_service +from .transports.base import ReachPlanServiceTransport, DEFAULT_CLIENT_INFO +from .client import ReachPlanServiceClient + +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 ReachPlanServiceAsyncClient: + """Reach Plan Service gives users information about audience + size that can be reached through advertisement on YouTube. In + particular, GenerateReachForecast provides estimated number of + people of specified demographics that can be reached by an ad in + a given market by a campaign of certain duration with a defined + budget. + """ + + _client: ReachPlanServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ReachPlanServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ReachPlanServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + ReachPlanServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ReachPlanServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod( + ReachPlanServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ReachPlanServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(ReachPlanServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + ReachPlanServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ReachPlanServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ReachPlanServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ReachPlanServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ReachPlanServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ReachPlanServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ReachPlanServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ReachPlanServiceAsyncClient: The constructed client. + """ + return ReachPlanServiceClient.from_service_account_info.__func__(ReachPlanServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ReachPlanServiceAsyncClient: The constructed client. + """ + return ReachPlanServiceClient.from_service_account_file.__func__(ReachPlanServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ReachPlanServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ReachPlanServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ReachPlanServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ReachPlanServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ReachPlanServiceTransport, + Callable[..., ReachPlanServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the reach plan service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ReachPlanServiceTransport,Callable[..., ReachPlanServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ReachPlanServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ReachPlanServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ReachPlanServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ReachPlanService", + "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.ads.googleads.v23.services.ReachPlanService", + "credentialsType": None, + } + ), + ) + + async def generate_conversion_rates( + self, + request: Optional[ + Union[reach_plan_service.GenerateConversionRatesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.GenerateConversionRatesResponse: + r"""Returns a collection of conversion rate suggestions for + supported plannable products. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateConversionRatesRequest, dict]]): + The request object. Request message for + [ReachPlanService.GenerateConversionRates][google.ads.googleads.v23.services.ReachPlanService.GenerateConversionRates]. + customer_id (:class:`str`): + Required. The ID of the customer. A + conversion rate based on the historical + data of this customer may be suggested. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateConversionRatesResponse: + Response message for + [ReachPlanService.GenerateConversionRates][google.ads.googleads.v23.services.ReachPlanService.GenerateConversionRates], + containing conversion rate suggestions for supported + plannable products. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.GenerateConversionRatesRequest + ): + request = reach_plan_service.GenerateConversionRatesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_conversion_rates + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_plannable_locations( + self, + request: Optional[ + Union[reach_plan_service.ListPlannableLocationsRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.ListPlannableLocationsResponse: + r"""Returns the list of plannable locations (for example, + countries). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListPlannableLocationsRequest, dict]]): + The request object. Request message for + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v23.services.ReachPlanService.ListPlannableLocations]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListPlannableLocationsResponse: + The list of plannable locations. + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.ListPlannableLocationsRequest + ): + request = reach_plan_service.ListPlannableLocationsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_plannable_locations + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_plannable_products( + self, + request: Optional[ + Union[reach_plan_service.ListPlannableProductsRequest, dict] + ] = None, + *, + plannable_location_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.ListPlannableProductsResponse: + r"""Returns the list of per-location plannable YouTube ad formats + with allowed targeting. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListPlannableProductsRequest, dict]]): + The request object. Request to list available products in + a given location. + plannable_location_id (:class:`str`): + Required. The ID of the selected location for planning. + To list the available plannable location IDs use + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v23.services.ReachPlanService.ListPlannableLocations]. + + This corresponds to the ``plannable_location_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListPlannableProductsResponse: + A response with all available + products. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [plannable_location_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.ListPlannableProductsRequest + ): + request = reach_plan_service.ListPlannableProductsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if plannable_location_id is not None: + request.plannable_location_id = plannable_location_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_plannable_products + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_reach_forecast( + self, + request: Optional[ + Union[reach_plan_service.GenerateReachForecastRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + campaign_duration: Optional[reach_plan_service.CampaignDuration] = None, + planned_products: Optional[ + MutableSequence[reach_plan_service.PlannedProduct] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.GenerateReachForecastResponse: + r"""Generates a reach forecast for a given targeting / product mix. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `ReachPlanError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateReachForecastRequest, dict]]): + The request object. Request message for + [ReachPlanService.GenerateReachForecast][google.ads.googleads.v23.services.ReachPlanService.GenerateReachForecast]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + campaign_duration (:class:`google.ads.googleads.v23.services.types.CampaignDuration`): + Required. Campaign duration. + This corresponds to the ``campaign_duration`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + planned_products (:class:`MutableSequence[google.ads.googleads.v23.services.types.PlannedProduct]`): + Required. The products to be + forecast. The max number of allowed + planned products is 15. + + This corresponds to the ``planned_products`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateReachForecastResponse: + Response message containing the + generated reach curve. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, campaign_duration, planned_products] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.GenerateReachForecastRequest + ): + request = reach_plan_service.GenerateReachForecastRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if campaign_duration is not None: + request.campaign_duration = campaign_duration + if planned_products: + request.planned_products.extend(planned_products) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_reach_forecast + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_plannable_user_lists( + self, + request: Optional[ + Union[reach_plan_service.ListPlannableUserListsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.ListPlannableUserListsResponse: + r"""Returns the list of plannable user lists with their plannable + status. User lists may not be plannable for a number of reasons, + including: + + - They are less than 10 days old. + - They have a membership lifespan that is less than 30 days + - They have less than 10,000 or more than 700,000 users. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `ReachPlanError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListPlannableUserListsRequest, dict]]): + The request object. Request message for + [ReachPlanService.ListPlannableUserLists][google.ads.googleads.v23.services.ReachPlanService.ListPlannableUserLists] + that lists the available user lists for a customer. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListPlannableUserListsResponse: + A response with all available user + lists with their plannable status. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.ListPlannableUserListsRequest + ): + request = reach_plan_service.ListPlannableUserListsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_plannable_user_lists + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_plannable_user_interests( + self, + request: Optional[ + Union[reach_plan_service.ListPlannableUserInterestsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.ListPlannableUserInterestsResponse: + r"""Returns the list of plannable user interests. A plannable user + interest is one that can be targeted in a reach forecast using + [ReachPlanService.GenerateReachForecast][google.ads.googleads.v23.services.ReachPlanService.GenerateReachForecast]. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `ListOperationError <>`__ `QuotaError <>`__ + `RequestError <>`__ `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ListPlannableUserInterestsRequest, dict]]): + The request object. Request message for + [ReachPlanService.ListPlannableUserInterests][google.ads.googleads.v23.services.ReachPlanService.ListPlannableUserInterests]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListPlannableUserInterestsResponse: + Response message for + [ReachPlanService.ListPlannableUserInterests][google.ads.googleads.v23.services.ReachPlanService.ListPlannableUserInterests]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.ListPlannableUserInterestsRequest + ): + request = reach_plan_service.ListPlannableUserInterestsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.list_plannable_user_interests + ] + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ReachPlanServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ReachPlanServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/reach_plan_service/client.py b/google/ads/googleads/v23/services/services/reach_plan_service/client.py new file mode 100644 index 000000000..bcf4ad301 --- /dev/null +++ b/google/ads/googleads/v23/services/services/reach_plan_service/client.py @@ -0,0 +1,1298 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import reach_plan_service +from .transports.base import ReachPlanServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ReachPlanServiceGrpcTransport +from .transports.grpc_asyncio import ReachPlanServiceGrpcAsyncIOTransport + + +class ReachPlanServiceClientMeta(type): + """Metaclass for the ReachPlanService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ReachPlanServiceTransport]] + _transport_registry["grpc"] = ReachPlanServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ReachPlanServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ReachPlanServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ReachPlanServiceClient(metaclass=ReachPlanServiceClientMeta): + """Reach Plan Service gives users information about audience + size that can be reached through advertisement on YouTube. In + particular, GenerateReachForecast provides estimated number of + people of specified demographics that can be reached by an ad in + a given market by a campaign of certain duration with a defined + budget. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ReachPlanServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ReachPlanServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ReachPlanServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ReachPlanServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ReachPlanServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ReachPlanServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ReachPlanServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ReachPlanServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + ReachPlanServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ReachPlanServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ReachPlanServiceTransport, + Callable[..., ReachPlanServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the reach plan service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ReachPlanServiceTransport,Callable[..., ReachPlanServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ReachPlanServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ReachPlanServiceClient._read_environment_variables() + self._client_cert_source = ( + ReachPlanServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ReachPlanServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, ReachPlanServiceTransport) + if transport_provided: + # transport is a ReachPlanServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(ReachPlanServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ReachPlanServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ReachPlanServiceTransport], + Callable[..., ReachPlanServiceTransport], + ] = ( + ReachPlanServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., ReachPlanServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ReachPlanServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ReachPlanService", + "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.ads.googleads.v23.services.ReachPlanService", + "credentialsType": None, + } + ), + ) + + def generate_conversion_rates( + self, + request: Optional[ + Union[reach_plan_service.GenerateConversionRatesRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.GenerateConversionRatesResponse: + r"""Returns a collection of conversion rate suggestions for + supported plannable products. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateConversionRatesRequest, dict]): + The request object. Request message for + [ReachPlanService.GenerateConversionRates][google.ads.googleads.v23.services.ReachPlanService.GenerateConversionRates]. + customer_id (str): + Required. The ID of the customer. A + conversion rate based on the historical + data of this customer may be suggested. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateConversionRatesResponse: + Response message for + [ReachPlanService.GenerateConversionRates][google.ads.googleads.v23.services.ReachPlanService.GenerateConversionRates], + containing conversion rate suggestions for supported + plannable products. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.GenerateConversionRatesRequest + ): + request = reach_plan_service.GenerateConversionRatesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_conversion_rates + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_plannable_locations( + self, + request: Optional[ + Union[reach_plan_service.ListPlannableLocationsRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.ListPlannableLocationsResponse: + r"""Returns the list of plannable locations (for example, + countries). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListPlannableLocationsRequest, dict]): + The request object. Request message for + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v23.services.ReachPlanService.ListPlannableLocations]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListPlannableLocationsResponse: + The list of plannable locations. + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.ListPlannableLocationsRequest + ): + request = reach_plan_service.ListPlannableLocationsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_plannable_locations + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_plannable_products( + self, + request: Optional[ + Union[reach_plan_service.ListPlannableProductsRequest, dict] + ] = None, + *, + plannable_location_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.ListPlannableProductsResponse: + r"""Returns the list of per-location plannable YouTube ad formats + with allowed targeting. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListPlannableProductsRequest, dict]): + The request object. Request to list available products in + a given location. + plannable_location_id (str): + Required. The ID of the selected location for planning. + To list the available plannable location IDs use + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v23.services.ReachPlanService.ListPlannableLocations]. + + This corresponds to the ``plannable_location_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListPlannableProductsResponse: + A response with all available + products. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [plannable_location_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.ListPlannableProductsRequest + ): + request = reach_plan_service.ListPlannableProductsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if plannable_location_id is not None: + request.plannable_location_id = plannable_location_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_plannable_products + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_reach_forecast( + self, + request: Optional[ + Union[reach_plan_service.GenerateReachForecastRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + campaign_duration: Optional[reach_plan_service.CampaignDuration] = None, + planned_products: Optional[ + MutableSequence[reach_plan_service.PlannedProduct] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.GenerateReachForecastResponse: + r"""Generates a reach forecast for a given targeting / product mix. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `ReachPlanError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateReachForecastRequest, dict]): + The request object. Request message for + [ReachPlanService.GenerateReachForecast][google.ads.googleads.v23.services.ReachPlanService.GenerateReachForecast]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + campaign_duration (google.ads.googleads.v23.services.types.CampaignDuration): + Required. Campaign duration. + This corresponds to the ``campaign_duration`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + planned_products (MutableSequence[google.ads.googleads.v23.services.types.PlannedProduct]): + Required. The products to be + forecast. The max number of allowed + planned products is 15. + + This corresponds to the ``planned_products`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateReachForecastResponse: + Response message containing the + generated reach curve. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, campaign_duration, planned_products] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.GenerateReachForecastRequest + ): + request = reach_plan_service.GenerateReachForecastRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if campaign_duration is not None: + request.campaign_duration = campaign_duration + if planned_products is not None: + request.planned_products = planned_products + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_reach_forecast + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_plannable_user_lists( + self, + request: Optional[ + Union[reach_plan_service.ListPlannableUserListsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.ListPlannableUserListsResponse: + r"""Returns the list of plannable user lists with their plannable + status. User lists may not be plannable for a number of reasons, + including: + + - They are less than 10 days old. + - They have a membership lifespan that is less than 30 days + - They have less than 10,000 or more than 700,000 users. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `ReachPlanError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListPlannableUserListsRequest, dict]): + The request object. Request message for + [ReachPlanService.ListPlannableUserLists][google.ads.googleads.v23.services.ReachPlanService.ListPlannableUserLists] + that lists the available user lists for a customer. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListPlannableUserListsResponse: + A response with all available user + lists with their plannable status. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.ListPlannableUserListsRequest + ): + request = reach_plan_service.ListPlannableUserListsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_plannable_user_lists + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_plannable_user_interests( + self, + request: Optional[ + Union[reach_plan_service.ListPlannableUserInterestsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> reach_plan_service.ListPlannableUserInterestsResponse: + r"""Returns the list of plannable user interests. A plannable user + interest is one that can be targeted in a reach forecast using + [ReachPlanService.GenerateReachForecast][google.ads.googleads.v23.services.ReachPlanService.GenerateReachForecast]. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `ListOperationError <>`__ `QuotaError <>`__ + `RequestError <>`__ `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ListPlannableUserInterestsRequest, dict]): + The request object. Request message for + [ReachPlanService.ListPlannableUserInterests][google.ads.googleads.v23.services.ReachPlanService.ListPlannableUserInterests]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ListPlannableUserInterestsResponse: + Response message for + [ReachPlanService.ListPlannableUserInterests][google.ads.googleads.v23.services.ReachPlanService.ListPlannableUserInterests]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, reach_plan_service.ListPlannableUserInterestsRequest + ): + request = reach_plan_service.ListPlannableUserInterestsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.list_plannable_user_interests + ] + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ReachPlanServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ReachPlanServiceClient",) diff --git a/google/ads/googleads/v19/services/services/reach_plan_service/transports/README.rst b/google/ads/googleads/v23/services/services/reach_plan_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/reach_plan_service/transports/README.rst rename to google/ads/googleads/v23/services/services/reach_plan_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/reach_plan_service/transports/__init__.py b/google/ads/googleads/v23/services/services/reach_plan_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/reach_plan_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/reach_plan_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/reach_plan_service/transports/base.py b/google/ads/googleads/v23/services/services/reach_plan_service/transports/base.py new file mode 100644 index 000000000..8d742d87c --- /dev/null +++ b/google/ads/googleads/v23/services/services/reach_plan_service/transports/base.py @@ -0,0 +1,258 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import reach_plan_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ReachPlanServiceTransport(abc.ABC): + """Abstract transport class for ReachPlanService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.generate_conversion_rates: gapic_v1.method.wrap_method( + self.generate_conversion_rates, + default_timeout=None, + client_info=client_info, + ), + self.list_plannable_locations: gapic_v1.method.wrap_method( + self.list_plannable_locations, + default_timeout=None, + client_info=client_info, + ), + self.list_plannable_products: gapic_v1.method.wrap_method( + self.list_plannable_products, + default_timeout=None, + client_info=client_info, + ), + self.generate_reach_forecast: gapic_v1.method.wrap_method( + self.generate_reach_forecast, + default_timeout=None, + client_info=client_info, + ), + self.list_plannable_user_lists: gapic_v1.method.wrap_method( + self.list_plannable_user_lists, + default_timeout=None, + client_info=client_info, + ), + self.list_plannable_user_interests: gapic_v1.method.wrap_method( + self.list_plannable_user_interests, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def generate_conversion_rates( + self, + ) -> Callable[ + [reach_plan_service.GenerateConversionRatesRequest], + Union[ + reach_plan_service.GenerateConversionRatesResponse, + Awaitable[reach_plan_service.GenerateConversionRatesResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_plannable_locations( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableLocationsRequest], + Union[ + reach_plan_service.ListPlannableLocationsResponse, + Awaitable[reach_plan_service.ListPlannableLocationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_plannable_products( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableProductsRequest], + Union[ + reach_plan_service.ListPlannableProductsResponse, + Awaitable[reach_plan_service.ListPlannableProductsResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_reach_forecast( + self, + ) -> Callable[ + [reach_plan_service.GenerateReachForecastRequest], + Union[ + reach_plan_service.GenerateReachForecastResponse, + Awaitable[reach_plan_service.GenerateReachForecastResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_plannable_user_lists( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableUserListsRequest], + Union[ + reach_plan_service.ListPlannableUserListsResponse, + Awaitable[reach_plan_service.ListPlannableUserListsResponse], + ], + ]: + raise NotImplementedError() + + @property + def list_plannable_user_interests( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableUserInterestsRequest], + Union[ + reach_plan_service.ListPlannableUserInterestsResponse, + Awaitable[reach_plan_service.ListPlannableUserInterestsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ReachPlanServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/reach_plan_service/transports/grpc.py b/google/ads/googleads/v23/services/services/reach_plan_service/transports/grpc.py new file mode 100644 index 000000000..eb7605569 --- /dev/null +++ b/google/ads/googleads/v23/services/services/reach_plan_service/transports/grpc.py @@ -0,0 +1,581 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import reach_plan_service +from .base import ReachPlanServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ReachPlanService", + "rpcName": str(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.ads.googleads.v23.services.ReachPlanService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ReachPlanServiceGrpcTransport(ReachPlanServiceTransport): + """gRPC backend transport for ReachPlanService. + + Reach Plan Service gives users information about audience + size that can be reached through advertisement on YouTube. In + particular, GenerateReachForecast provides estimated number of + people of specified demographics that can be reached by an ad in + a given market by a campaign of certain duration with a defined + budget. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def generate_conversion_rates( + self, + ) -> Callable[ + [reach_plan_service.GenerateConversionRatesRequest], + reach_plan_service.GenerateConversionRatesResponse, + ]: + r"""Return a callable for the generate conversion rates method over gRPC. + + Returns a collection of conversion rate suggestions for + supported plannable products. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateConversionRatesRequest], + ~.GenerateConversionRatesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_conversion_rates" not in self._stubs: + self._stubs["generate_conversion_rates"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/GenerateConversionRates", + request_serializer=reach_plan_service.GenerateConversionRatesRequest.serialize, + response_deserializer=reach_plan_service.GenerateConversionRatesResponse.deserialize, + ) + ) + return self._stubs["generate_conversion_rates"] + + @property + def list_plannable_locations( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableLocationsRequest], + reach_plan_service.ListPlannableLocationsResponse, + ]: + r"""Return a callable for the list plannable locations method over gRPC. + + Returns the list of plannable locations (for example, + countries). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListPlannableLocationsRequest], + ~.ListPlannableLocationsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_plannable_locations" not in self._stubs: + self._stubs["list_plannable_locations"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/ListPlannableLocations", + request_serializer=reach_plan_service.ListPlannableLocationsRequest.serialize, + response_deserializer=reach_plan_service.ListPlannableLocationsResponse.deserialize, + ) + ) + return self._stubs["list_plannable_locations"] + + @property + def list_plannable_products( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableProductsRequest], + reach_plan_service.ListPlannableProductsResponse, + ]: + r"""Return a callable for the list plannable products method over gRPC. + + Returns the list of per-location plannable YouTube ad formats + with allowed targeting. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListPlannableProductsRequest], + ~.ListPlannableProductsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_plannable_products" not in self._stubs: + self._stubs["list_plannable_products"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/ListPlannableProducts", + request_serializer=reach_plan_service.ListPlannableProductsRequest.serialize, + response_deserializer=reach_plan_service.ListPlannableProductsResponse.deserialize, + ) + ) + return self._stubs["list_plannable_products"] + + @property + def generate_reach_forecast( + self, + ) -> Callable[ + [reach_plan_service.GenerateReachForecastRequest], + reach_plan_service.GenerateReachForecastResponse, + ]: + r"""Return a callable for the generate reach forecast method over gRPC. + + Generates a reach forecast for a given targeting / product mix. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `ReachPlanError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateReachForecastRequest], + ~.GenerateReachForecastResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_reach_forecast" not in self._stubs: + self._stubs["generate_reach_forecast"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/GenerateReachForecast", + request_serializer=reach_plan_service.GenerateReachForecastRequest.serialize, + response_deserializer=reach_plan_service.GenerateReachForecastResponse.deserialize, + ) + ) + return self._stubs["generate_reach_forecast"] + + @property + def list_plannable_user_lists( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableUserListsRequest], + reach_plan_service.ListPlannableUserListsResponse, + ]: + r"""Return a callable for the list plannable user lists method over gRPC. + + Returns the list of plannable user lists with their plannable + status. User lists may not be plannable for a number of reasons, + including: + + - They are less than 10 days old. + - They have a membership lifespan that is less than 30 days + - They have less than 10,000 or more than 700,000 users. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `ReachPlanError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListPlannableUserListsRequest], + ~.ListPlannableUserListsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_plannable_user_lists" not in self._stubs: + self._stubs["list_plannable_user_lists"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/ListPlannableUserLists", + request_serializer=reach_plan_service.ListPlannableUserListsRequest.serialize, + response_deserializer=reach_plan_service.ListPlannableUserListsResponse.deserialize, + ) + ) + return self._stubs["list_plannable_user_lists"] + + @property + def list_plannable_user_interests( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableUserInterestsRequest], + reach_plan_service.ListPlannableUserInterestsResponse, + ]: + r"""Return a callable for the list plannable user interests method over gRPC. + + Returns the list of plannable user interests. A plannable user + interest is one that can be targeted in a reach forecast using + [ReachPlanService.GenerateReachForecast][google.ads.googleads.v23.services.ReachPlanService.GenerateReachForecast]. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `ListOperationError <>`__ `QuotaError <>`__ + `RequestError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.ListPlannableUserInterestsRequest], + ~.ListPlannableUserInterestsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_plannable_user_interests" not in self._stubs: + self._stubs["list_plannable_user_interests"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/ListPlannableUserInterests", + request_serializer=reach_plan_service.ListPlannableUserInterestsRequest.serialize, + response_deserializer=reach_plan_service.ListPlannableUserInterestsResponse.deserialize, + ) + ) + return self._stubs["list_plannable_user_interests"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ReachPlanServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/reach_plan_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/reach_plan_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..b6f0db322 --- /dev/null +++ b/google/ads/googleads/v23/services/services/reach_plan_service/transports/grpc_asyncio.py @@ -0,0 +1,627 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import reach_plan_service +from .base import ReachPlanServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ReachPlanService", + "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.ads.googleads.v23.services.ReachPlanService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ReachPlanServiceGrpcAsyncIOTransport(ReachPlanServiceTransport): + """gRPC AsyncIO backend transport for ReachPlanService. + + Reach Plan Service gives users information about audience + size that can be reached through advertisement on YouTube. In + particular, GenerateReachForecast provides estimated number of + people of specified demographics that can be reached by an ad in + a given market by a campaign of certain duration with a defined + budget. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def generate_conversion_rates( + self, + ) -> Callable[ + [reach_plan_service.GenerateConversionRatesRequest], + Awaitable[reach_plan_service.GenerateConversionRatesResponse], + ]: + r"""Return a callable for the generate conversion rates method over gRPC. + + Returns a collection of conversion rate suggestions for + supported plannable products. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateConversionRatesRequest], + Awaitable[~.GenerateConversionRatesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_conversion_rates" not in self._stubs: + self._stubs["generate_conversion_rates"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/GenerateConversionRates", + request_serializer=reach_plan_service.GenerateConversionRatesRequest.serialize, + response_deserializer=reach_plan_service.GenerateConversionRatesResponse.deserialize, + ) + ) + return self._stubs["generate_conversion_rates"] + + @property + def list_plannable_locations( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableLocationsRequest], + Awaitable[reach_plan_service.ListPlannableLocationsResponse], + ]: + r"""Return a callable for the list plannable locations method over gRPC. + + Returns the list of plannable locations (for example, + countries). + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListPlannableLocationsRequest], + Awaitable[~.ListPlannableLocationsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_plannable_locations" not in self._stubs: + self._stubs["list_plannable_locations"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/ListPlannableLocations", + request_serializer=reach_plan_service.ListPlannableLocationsRequest.serialize, + response_deserializer=reach_plan_service.ListPlannableLocationsResponse.deserialize, + ) + ) + return self._stubs["list_plannable_locations"] + + @property + def list_plannable_products( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableProductsRequest], + Awaitable[reach_plan_service.ListPlannableProductsResponse], + ]: + r"""Return a callable for the list plannable products method over gRPC. + + Returns the list of per-location plannable YouTube ad formats + with allowed targeting. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListPlannableProductsRequest], + Awaitable[~.ListPlannableProductsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_plannable_products" not in self._stubs: + self._stubs["list_plannable_products"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/ListPlannableProducts", + request_serializer=reach_plan_service.ListPlannableProductsRequest.serialize, + response_deserializer=reach_plan_service.ListPlannableProductsResponse.deserialize, + ) + ) + return self._stubs["list_plannable_products"] + + @property + def generate_reach_forecast( + self, + ) -> Callable[ + [reach_plan_service.GenerateReachForecastRequest], + Awaitable[reach_plan_service.GenerateReachForecastResponse], + ]: + r"""Return a callable for the generate reach forecast method over gRPC. + + Generates a reach forecast for a given targeting / product mix. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `ReachPlanError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateReachForecastRequest], + Awaitable[~.GenerateReachForecastResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_reach_forecast" not in self._stubs: + self._stubs["generate_reach_forecast"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/GenerateReachForecast", + request_serializer=reach_plan_service.GenerateReachForecastRequest.serialize, + response_deserializer=reach_plan_service.GenerateReachForecastResponse.deserialize, + ) + ) + return self._stubs["generate_reach_forecast"] + + @property + def list_plannable_user_lists( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableUserListsRequest], + Awaitable[reach_plan_service.ListPlannableUserListsResponse], + ]: + r"""Return a callable for the list plannable user lists method over gRPC. + + Returns the list of plannable user lists with their plannable + status. User lists may not be plannable for a number of reasons, + including: + + - They are less than 10 days old. + - They have a membership lifespan that is less than 30 days + - They have less than 10,000 or more than 700,000 users. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RangeError <>`__ + `ReachPlanError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.ListPlannableUserListsRequest], + Awaitable[~.ListPlannableUserListsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_plannable_user_lists" not in self._stubs: + self._stubs["list_plannable_user_lists"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/ListPlannableUserLists", + request_serializer=reach_plan_service.ListPlannableUserListsRequest.serialize, + response_deserializer=reach_plan_service.ListPlannableUserListsResponse.deserialize, + ) + ) + return self._stubs["list_plannable_user_lists"] + + @property + def list_plannable_user_interests( + self, + ) -> Callable[ + [reach_plan_service.ListPlannableUserInterestsRequest], + Awaitable[reach_plan_service.ListPlannableUserInterestsResponse], + ]: + r"""Return a callable for the list plannable user interests method over gRPC. + + Returns the list of plannable user interests. A plannable user + interest is one that can be targeted in a reach forecast using + [ReachPlanService.GenerateReachForecast][google.ads.googleads.v23.services.ReachPlanService.GenerateReachForecast]. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `FieldError <>`__ `HeaderError <>`__ + `InternalError <>`__ `ListOperationError <>`__ `QuotaError <>`__ + `RequestError <>`__ `StringLengthError <>`__ + + Returns: + Callable[[~.ListPlannableUserInterestsRequest], + Awaitable[~.ListPlannableUserInterestsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_plannable_user_interests" not in self._stubs: + self._stubs["list_plannable_user_interests"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ReachPlanService/ListPlannableUserInterests", + request_serializer=reach_plan_service.ListPlannableUserInterestsRequest.serialize, + response_deserializer=reach_plan_service.ListPlannableUserInterestsResponse.deserialize, + ) + ) + return self._stubs["list_plannable_user_interests"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.generate_conversion_rates: self._wrap_method( + self.generate_conversion_rates, + default_timeout=None, + client_info=client_info, + ), + self.list_plannable_locations: self._wrap_method( + self.list_plannable_locations, + default_timeout=None, + client_info=client_info, + ), + self.list_plannable_products: self._wrap_method( + self.list_plannable_products, + default_timeout=None, + client_info=client_info, + ), + self.generate_reach_forecast: self._wrap_method( + self.generate_reach_forecast, + default_timeout=None, + client_info=client_info, + ), + self.list_plannable_user_lists: self._wrap_method( + self.list_plannable_user_lists, + default_timeout=None, + client_info=client_info, + ), + self.list_plannable_user_interests: self._wrap_method( + self.list_plannable_user_interests, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ReachPlanServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/recommendation_service/__init__.py b/google/ads/googleads/v23/services/services/recommendation_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/recommendation_service/__init__.py rename to google/ads/googleads/v23/services/services/recommendation_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/recommendation_service/async_client.py b/google/ads/googleads/v23/services/services/recommendation_service/async_client.py new file mode 100644 index 000000000..5af746e49 --- /dev/null +++ b/google/ads/googleads/v23/services/services/recommendation_service/async_client.py @@ -0,0 +1,713 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.enums.types import ( + advertising_channel_type as gage_advertising_channel_type, +) +from google.ads.googleads.v23.enums.types import recommendation_type +from google.ads.googleads.v23.services.types import recommendation_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import RecommendationServiceTransport, DEFAULT_CLIENT_INFO +from .client import RecommendationServiceClient + +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 RecommendationServiceAsyncClient: + """Service to manage recommendations.""" + + _client: RecommendationServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = RecommendationServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = RecommendationServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + RecommendationServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = RecommendationServiceClient._DEFAULT_UNIVERSE + + ad_path = staticmethod(RecommendationServiceClient.ad_path) + parse_ad_path = staticmethod(RecommendationServiceClient.parse_ad_path) + ad_group_path = staticmethod(RecommendationServiceClient.ad_group_path) + parse_ad_group_path = staticmethod( + RecommendationServiceClient.parse_ad_group_path + ) + asset_path = staticmethod(RecommendationServiceClient.asset_path) + parse_asset_path = staticmethod( + RecommendationServiceClient.parse_asset_path + ) + campaign_path = staticmethod(RecommendationServiceClient.campaign_path) + parse_campaign_path = staticmethod( + RecommendationServiceClient.parse_campaign_path + ) + campaign_budget_path = staticmethod( + RecommendationServiceClient.campaign_budget_path + ) + parse_campaign_budget_path = staticmethod( + RecommendationServiceClient.parse_campaign_budget_path + ) + conversion_action_path = staticmethod( + RecommendationServiceClient.conversion_action_path + ) + parse_conversion_action_path = staticmethod( + RecommendationServiceClient.parse_conversion_action_path + ) + recommendation_path = staticmethod( + RecommendationServiceClient.recommendation_path + ) + parse_recommendation_path = staticmethod( + RecommendationServiceClient.parse_recommendation_path + ) + common_billing_account_path = staticmethod( + RecommendationServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + RecommendationServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + RecommendationServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + RecommendationServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + RecommendationServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + RecommendationServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + RecommendationServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + RecommendationServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + RecommendationServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + RecommendationServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RecommendationServiceAsyncClient: The constructed client. + """ + return RecommendationServiceClient.from_service_account_info.__func__(RecommendationServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RecommendationServiceAsyncClient: The constructed client. + """ + return RecommendationServiceClient.from_service_account_file.__func__(RecommendationServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return RecommendationServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> RecommendationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + RecommendationServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = RecommendationServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + RecommendationServiceTransport, + Callable[..., RecommendationServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the recommendation service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,RecommendationServiceTransport,Callable[..., RecommendationServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the RecommendationServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = RecommendationServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.RecommendationServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.RecommendationService", + "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.ads.googleads.v23.services.RecommendationService", + "credentialsType": None, + } + ), + ) + + async def apply_recommendation( + self, + request: Optional[ + Union[recommendation_service.ApplyRecommendationRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[recommendation_service.ApplyRecommendationOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> recommendation_service.ApplyRecommendationResponse: + r"""Applies given recommendations with corresponding apply + parameters. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ + `UrlFieldError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.ApplyRecommendationRequest, dict]]): + The request object. Request message for + [RecommendationService.ApplyRecommendation][google.ads.googleads.v23.services.RecommendationService.ApplyRecommendation]. + customer_id (:class:`str`): + Required. The ID of the customer with + the recommendation. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.ApplyRecommendationOperation]`): + Required. The list of operations to apply + recommendations. If partial_failure=false all + recommendations should be of the same type There is a + limit of 100 operations per request. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ApplyRecommendationResponse: + Response message for + [RecommendationService.ApplyRecommendation][google.ads.googleads.v23.services.RecommendationService.ApplyRecommendation]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, recommendation_service.ApplyRecommendationRequest + ): + request = recommendation_service.ApplyRecommendationRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.apply_recommendation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def dismiss_recommendation( + self, + request: Optional[ + Union[recommendation_service.DismissRecommendationRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + recommendation_service.DismissRecommendationRequest.DismissRecommendationOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> recommendation_service.DismissRecommendationResponse: + r"""Dismisses given recommendations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ + `RecommendationError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.DismissRecommendationRequest, dict]]): + The request object. Request message for + [RecommendationService.DismissRecommendation][google.ads.googleads.v23.services.RecommendationService.DismissRecommendation]. + customer_id (:class:`str`): + Required. The ID of the customer with + the recommendation. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.DismissRecommendationRequest.DismissRecommendationOperation]`): + Required. The list of operations to dismiss + recommendations. If partial_failure=false all + recommendations should be of the same type There is a + limit of 100 operations per request. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.DismissRecommendationResponse: + Response message for + [RecommendationService.DismissRecommendation][google.ads.googleads.v23.services.RecommendationService.DismissRecommendation]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, recommendation_service.DismissRecommendationRequest + ): + request = recommendation_service.DismissRecommendationRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.dismiss_recommendation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def generate_recommendations( + self, + request: Optional[ + Union[recommendation_service.GenerateRecommendationsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + recommendation_types: Optional[ + MutableSequence[ + recommendation_type.RecommendationTypeEnum.RecommendationType + ] + ] = None, + advertising_channel_type: Optional[ + gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> recommendation_service.GenerateRecommendationsResponse: + r"""Generates Recommendations based off the requested + recommendation_types. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ + `RecommendationError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateRecommendationsRequest, dict]]): + The request object. Request message for + [RecommendationService.GenerateRecommendations][google.ads.googleads.v23.services.RecommendationService.GenerateRecommendations]. + customer_id (:class:`str`): + Required. The ID of the customer + generating recommendations. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + recommendation_types (:class:`MutableSequence[google.ads.googleads.v23.enums.types.RecommendationTypeEnum.RecommendationType]`): + Required. List of eligible recommendation_types to + generate. If the uploaded criteria isn't sufficient to + make a recommendation, or the campaign is already in the + recommended state, no recommendation will be returned + for that type. Generally, a recommendation is returned + if all required fields for that recommendation_type are + uploaded, but there are cases where this is still not + sufficient. + + The following recommendation_types are supported for + recommendation generation: CAMPAIGN_BUDGET, KEYWORD, + MAXIMIZE_CLICKS_OPT_IN, MAXIMIZE_CONVERSIONS_OPT_IN, + MAXIMIZE_CONVERSION_VALUE_OPT_IN, SET_TARGET_CPA, + SET_TARGET_ROAS, SITELINK_ASSET, TARGET_CPA_OPT_IN, + TARGET_ROAS_OPT_IN + + This corresponds to the ``recommendation_types`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + advertising_channel_type (:class:`google.ads.googleads.v23.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType`): + Required. Advertising channel type of the campaign. The + following advertising_channel_types are supported for + recommendation generation: PERFORMANCE_MAX and SEARCH + + This corresponds to the ``advertising_channel_type`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateRecommendationsResponse: + Response message for + [RecommendationService.GenerateRecommendations][google.ads.googleads.v23.services.RecommendationService.GenerateRecommendations]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + recommendation_types, + advertising_channel_type, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, recommendation_service.GenerateRecommendationsRequest + ): + request = recommendation_service.GenerateRecommendationsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if advertising_channel_type is not None: + request.advertising_channel_type = advertising_channel_type + if recommendation_types: + request.recommendation_types.extend(recommendation_types) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_recommendations + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "RecommendationServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("RecommendationServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/recommendation_service/client.py b/google/ads/googleads/v23/services/services/recommendation_service/client.py new file mode 100644 index 000000000..ccb0695b6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/recommendation_service/client.py @@ -0,0 +1,1279 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.enums.types import ( + advertising_channel_type as gage_advertising_channel_type, +) +from google.ads.googleads.v23.enums.types import recommendation_type +from google.ads.googleads.v23.services.types import recommendation_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import RecommendationServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import RecommendationServiceGrpcTransport +from .transports.grpc_asyncio import RecommendationServiceGrpcAsyncIOTransport + + +class RecommendationServiceClientMeta(type): + """Metaclass for the RecommendationService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[RecommendationServiceTransport]] + _transport_registry["grpc"] = RecommendationServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + RecommendationServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[RecommendationServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class RecommendationServiceClient(metaclass=RecommendationServiceClientMeta): + """Service to manage recommendations.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RecommendationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RecommendationServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> RecommendationServiceTransport: + """Returns the transport used by the client instance. + + Returns: + RecommendationServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def ad_path( + customer_id: str, + ad_id: str, + ) -> str: + """Returns a fully-qualified ad string.""" + return "customers/{customer_id}/ads/{ad_id}".format( + customer_id=customer_id, + ad_id=ad_id, + ) + + @staticmethod + def parse_ad_path(path: str) -> Dict[str, str]: + """Parses a ad path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/ads/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def ad_group_path( + customer_id: str, + ad_group_id: str, + ) -> str: + """Returns a fully-qualified ad_group string.""" + return "customers/{customer_id}/adGroups/{ad_group_id}".format( + customer_id=customer_id, + ad_group_id=ad_group_id, + ) + + @staticmethod + def parse_ad_group_path(path: str) -> Dict[str, str]: + """Parses a ad_group path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/adGroups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def asset_path( + customer_id: str, + asset_id: str, + ) -> str: + """Returns a fully-qualified asset string.""" + return "customers/{customer_id}/assets/{asset_id}".format( + customer_id=customer_id, + asset_id=asset_id, + ) + + @staticmethod + def parse_asset_path(path: str) -> Dict[str, str]: + """Parses a asset path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/assets/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def campaign_budget_path( + customer_id: str, + campaign_budget_id: str, + ) -> str: + """Returns a fully-qualified campaign_budget string.""" + return "customers/{customer_id}/campaignBudgets/{campaign_budget_id}".format( + customer_id=customer_id, + campaign_budget_id=campaign_budget_id, + ) + + @staticmethod + def parse_campaign_budget_path(path: str) -> Dict[str, str]: + """Parses a campaign_budget path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaignBudgets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def conversion_action_path( + customer_id: str, + conversion_action_id: str, + ) -> str: + """Returns a fully-qualified conversion_action string.""" + return "customers/{customer_id}/conversionActions/{conversion_action_id}".format( + customer_id=customer_id, + conversion_action_id=conversion_action_id, + ) + + @staticmethod + def parse_conversion_action_path(path: str) -> Dict[str, str]: + """Parses a conversion_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/conversionActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def recommendation_path( + customer_id: str, + recommendation_id: str, + ) -> str: + """Returns a fully-qualified recommendation string.""" + return "customers/{customer_id}/recommendations/{recommendation_id}".format( + customer_id=customer_id, + recommendation_id=recommendation_id, + ) + + @staticmethod + def parse_recommendation_path(path: str) -> Dict[str, str]: + """Parses a recommendation path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/recommendations/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + RecommendationServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + RecommendationServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = RecommendationServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = RecommendationServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + RecommendationServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = RecommendationServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + RecommendationServiceTransport, + Callable[..., RecommendationServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the recommendation service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,RecommendationServiceTransport,Callable[..., RecommendationServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the RecommendationServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = RecommendationServiceClient._read_environment_variables() + self._client_cert_source = ( + RecommendationServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + RecommendationServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, RecommendationServiceTransport + ) + if transport_provided: + # transport is a RecommendationServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(RecommendationServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or RecommendationServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[RecommendationServiceTransport], + Callable[..., RecommendationServiceTransport], + ] = ( + RecommendationServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., RecommendationServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.RecommendationServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.RecommendationService", + "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.ads.googleads.v23.services.RecommendationService", + "credentialsType": None, + } + ), + ) + + def apply_recommendation( + self, + request: Optional[ + Union[recommendation_service.ApplyRecommendationRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[recommendation_service.ApplyRecommendationOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> recommendation_service.ApplyRecommendationResponse: + r"""Applies given recommendations with corresponding apply + parameters. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.ApplyRecommendationRequest, dict]): + The request object. Request message for + [RecommendationService.ApplyRecommendation][google.ads.googleads.v23.services.RecommendationService.ApplyRecommendation]. + customer_id (str): + Required. The ID of the customer with + the recommendation. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.ApplyRecommendationOperation]): + Required. The list of operations to apply + recommendations. If partial_failure=false all + recommendations should be of the same type There is a + limit of 100 operations per request. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.ApplyRecommendationResponse: + Response message for + [RecommendationService.ApplyRecommendation][google.ads.googleads.v23.services.RecommendationService.ApplyRecommendation]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, recommendation_service.ApplyRecommendationRequest + ): + request = recommendation_service.ApplyRecommendationRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.apply_recommendation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def dismiss_recommendation( + self, + request: Optional[ + Union[recommendation_service.DismissRecommendationRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + recommendation_service.DismissRecommendationRequest.DismissRecommendationOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> recommendation_service.DismissRecommendationResponse: + r"""Dismisses given recommendations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ + `RecommendationError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.DismissRecommendationRequest, dict]): + The request object. Request message for + [RecommendationService.DismissRecommendation][google.ads.googleads.v23.services.RecommendationService.DismissRecommendation]. + customer_id (str): + Required. The ID of the customer with + the recommendation. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.DismissRecommendationRequest.DismissRecommendationOperation]): + Required. The list of operations to dismiss + recommendations. If partial_failure=false all + recommendations should be of the same type There is a + limit of 100 operations per request. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.DismissRecommendationResponse: + Response message for + [RecommendationService.DismissRecommendation][google.ads.googleads.v23.services.RecommendationService.DismissRecommendation]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, recommendation_service.DismissRecommendationRequest + ): + request = recommendation_service.DismissRecommendationRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.dismiss_recommendation + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def generate_recommendations( + self, + request: Optional[ + Union[recommendation_service.GenerateRecommendationsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + recommendation_types: Optional[ + MutableSequence[ + recommendation_type.RecommendationTypeEnum.RecommendationType + ] + ] = None, + advertising_channel_type: Optional[ + gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> recommendation_service.GenerateRecommendationsResponse: + r"""Generates Recommendations based off the requested + recommendation_types. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ + `RecommendationError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateRecommendationsRequest, dict]): + The request object. Request message for + [RecommendationService.GenerateRecommendations][google.ads.googleads.v23.services.RecommendationService.GenerateRecommendations]. + customer_id (str): + Required. The ID of the customer + generating recommendations. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + recommendation_types (MutableSequence[google.ads.googleads.v23.enums.types.RecommendationTypeEnum.RecommendationType]): + Required. List of eligible recommendation_types to + generate. If the uploaded criteria isn't sufficient to + make a recommendation, or the campaign is already in the + recommended state, no recommendation will be returned + for that type. Generally, a recommendation is returned + if all required fields for that recommendation_type are + uploaded, but there are cases where this is still not + sufficient. + + The following recommendation_types are supported for + recommendation generation: CAMPAIGN_BUDGET, KEYWORD, + MAXIMIZE_CLICKS_OPT_IN, MAXIMIZE_CONVERSIONS_OPT_IN, + MAXIMIZE_CONVERSION_VALUE_OPT_IN, SET_TARGET_CPA, + SET_TARGET_ROAS, SITELINK_ASSET, TARGET_CPA_OPT_IN, + TARGET_ROAS_OPT_IN + + This corresponds to the ``recommendation_types`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + advertising_channel_type (google.ads.googleads.v23.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): + Required. Advertising channel type of the campaign. The + following advertising_channel_types are supported for + recommendation generation: PERFORMANCE_MAX and SEARCH + + This corresponds to the ``advertising_channel_type`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateRecommendationsResponse: + Response message for + [RecommendationService.GenerateRecommendations][google.ads.googleads.v23.services.RecommendationService.GenerateRecommendations]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [ + customer_id, + recommendation_types, + advertising_channel_type, + ] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, recommendation_service.GenerateRecommendationsRequest + ): + request = recommendation_service.GenerateRecommendationsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if recommendation_types is not None: + request.recommendation_types = recommendation_types + if advertising_channel_type is not None: + request.advertising_channel_type = advertising_channel_type + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_recommendations + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "RecommendationServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("RecommendationServiceClient",) diff --git a/google/ads/googleads/v19/services/services/recommendation_service/transports/README.rst b/google/ads/googleads/v23/services/services/recommendation_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/recommendation_service/transports/README.rst rename to google/ads/googleads/v23/services/services/recommendation_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/recommendation_service/transports/__init__.py b/google/ads/googleads/v23/services/services/recommendation_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/recommendation_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/recommendation_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/recommendation_service/transports/base.py b/google/ads/googleads/v23/services/services/recommendation_service/transports/base.py new file mode 100644 index 000000000..38985f9eb --- /dev/null +++ b/google/ads/googleads/v23/services/services/recommendation_service/transports/base.py @@ -0,0 +1,207 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import recommendation_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class RecommendationServiceTransport(abc.ABC): + """Abstract transport class for RecommendationService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.apply_recommendation: gapic_v1.method.wrap_method( + self.apply_recommendation, + default_timeout=None, + client_info=client_info, + ), + self.dismiss_recommendation: gapic_v1.method.wrap_method( + self.dismiss_recommendation, + default_timeout=None, + client_info=client_info, + ), + self.generate_recommendations: gapic_v1.method.wrap_method( + self.generate_recommendations, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def apply_recommendation( + self, + ) -> Callable[ + [recommendation_service.ApplyRecommendationRequest], + Union[ + recommendation_service.ApplyRecommendationResponse, + Awaitable[recommendation_service.ApplyRecommendationResponse], + ], + ]: + raise NotImplementedError() + + @property + def dismiss_recommendation( + self, + ) -> Callable[ + [recommendation_service.DismissRecommendationRequest], + Union[ + recommendation_service.DismissRecommendationResponse, + Awaitable[recommendation_service.DismissRecommendationResponse], + ], + ]: + raise NotImplementedError() + + @property + def generate_recommendations( + self, + ) -> Callable[ + [recommendation_service.GenerateRecommendationsRequest], + Union[ + recommendation_service.GenerateRecommendationsResponse, + Awaitable[recommendation_service.GenerateRecommendationsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("RecommendationServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/recommendation_service/transports/grpc.py b/google/ads/googleads/v23/services/services/recommendation_service/transports/grpc.py new file mode 100644 index 000000000..b4ec0167b --- /dev/null +++ b/google/ads/googleads/v23/services/services/recommendation_service/transports/grpc.py @@ -0,0 +1,463 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import recommendation_service +from .base import RecommendationServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.RecommendationService", + "rpcName": str(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.ads.googleads.v23.services.RecommendationService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class RecommendationServiceGrpcTransport(RecommendationServiceTransport): + """gRPC backend transport for RecommendationService. + + Service to manage recommendations. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def apply_recommendation( + self, + ) -> Callable[ + [recommendation_service.ApplyRecommendationRequest], + recommendation_service.ApplyRecommendationResponse, + ]: + r"""Return a callable for the apply recommendation method over gRPC. + + Applies given recommendations with corresponding apply + parameters. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.ApplyRecommendationRequest], + ~.ApplyRecommendationResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "apply_recommendation" not in self._stubs: + self._stubs["apply_recommendation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.RecommendationService/ApplyRecommendation", + request_serializer=recommendation_service.ApplyRecommendationRequest.serialize, + response_deserializer=recommendation_service.ApplyRecommendationResponse.deserialize, + ) + ) + return self._stubs["apply_recommendation"] + + @property + def dismiss_recommendation( + self, + ) -> Callable[ + [recommendation_service.DismissRecommendationRequest], + recommendation_service.DismissRecommendationResponse, + ]: + r"""Return a callable for the dismiss recommendation method over gRPC. + + Dismisses given recommendations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ + `RecommendationError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.DismissRecommendationRequest], + ~.DismissRecommendationResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "dismiss_recommendation" not in self._stubs: + self._stubs["dismiss_recommendation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.RecommendationService/DismissRecommendation", + request_serializer=recommendation_service.DismissRecommendationRequest.serialize, + response_deserializer=recommendation_service.DismissRecommendationResponse.deserialize, + ) + ) + return self._stubs["dismiss_recommendation"] + + @property + def generate_recommendations( + self, + ) -> Callable[ + [recommendation_service.GenerateRecommendationsRequest], + recommendation_service.GenerateRecommendationsResponse, + ]: + r"""Return a callable for the generate recommendations method over gRPC. + + Generates Recommendations based off the requested + recommendation_types. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ + `RecommendationError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateRecommendationsRequest], + ~.GenerateRecommendationsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_recommendations" not in self._stubs: + self._stubs["generate_recommendations"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.RecommendationService/GenerateRecommendations", + request_serializer=recommendation_service.GenerateRecommendationsRequest.serialize, + response_deserializer=recommendation_service.GenerateRecommendationsResponse.deserialize, + ) + ) + return self._stubs["generate_recommendations"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("RecommendationServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/recommendation_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/recommendation_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..ceb4b587a --- /dev/null +++ b/google/ads/googleads/v23/services/services/recommendation_service/transports/grpc_asyncio.py @@ -0,0 +1,494 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import recommendation_service +from .base import RecommendationServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.RecommendationService", + "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.ads.googleads.v23.services.RecommendationService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class RecommendationServiceGrpcAsyncIOTransport(RecommendationServiceTransport): + """gRPC AsyncIO backend transport for RecommendationService. + + Service to manage recommendations. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def apply_recommendation( + self, + ) -> Callable[ + [recommendation_service.ApplyRecommendationRequest], + Awaitable[recommendation_service.ApplyRecommendationResponse], + ]: + r"""Return a callable for the apply recommendation method over gRPC. + + Applies given recommendations with corresponding apply + parameters. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RecommendationError <>`__ `RequestError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.ApplyRecommendationRequest], + Awaitable[~.ApplyRecommendationResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "apply_recommendation" not in self._stubs: + self._stubs["apply_recommendation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.RecommendationService/ApplyRecommendation", + request_serializer=recommendation_service.ApplyRecommendationRequest.serialize, + response_deserializer=recommendation_service.ApplyRecommendationResponse.deserialize, + ) + ) + return self._stubs["apply_recommendation"] + + @property + def dismiss_recommendation( + self, + ) -> Callable[ + [recommendation_service.DismissRecommendationRequest], + Awaitable[recommendation_service.DismissRecommendationResponse], + ]: + r"""Return a callable for the dismiss recommendation method over gRPC. + + Dismisses given recommendations. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ + `RecommendationError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.DismissRecommendationRequest], + Awaitable[~.DismissRecommendationResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "dismiss_recommendation" not in self._stubs: + self._stubs["dismiss_recommendation"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.RecommendationService/DismissRecommendation", + request_serializer=recommendation_service.DismissRecommendationRequest.serialize, + response_deserializer=recommendation_service.DismissRecommendationResponse.deserialize, + ) + ) + return self._stubs["dismiss_recommendation"] + + @property + def generate_recommendations( + self, + ) -> Callable[ + [recommendation_service.GenerateRecommendationsRequest], + Awaitable[recommendation_service.GenerateRecommendationsResponse], + ]: + r"""Return a callable for the generate recommendations method over gRPC. + + Generates Recommendations based off the requested + recommendation_types. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ + `RecommendationError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.GenerateRecommendationsRequest], + Awaitable[~.GenerateRecommendationsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_recommendations" not in self._stubs: + self._stubs["generate_recommendations"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.RecommendationService/GenerateRecommendations", + request_serializer=recommendation_service.GenerateRecommendationsRequest.serialize, + response_deserializer=recommendation_service.GenerateRecommendationsResponse.deserialize, + ) + ) + return self._stubs["generate_recommendations"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.apply_recommendation: self._wrap_method( + self.apply_recommendation, + default_timeout=None, + client_info=client_info, + ), + self.dismiss_recommendation: self._wrap_method( + self.dismiss_recommendation, + default_timeout=None, + client_info=client_info, + ), + self.generate_recommendations: self._wrap_method( + self.generate_recommendations, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("RecommendationServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/recommendation_subscription_service/__init__.py b/google/ads/googleads/v23/services/services/recommendation_subscription_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/recommendation_subscription_service/__init__.py rename to google/ads/googleads/v23/services/services/recommendation_subscription_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/recommendation_subscription_service/async_client.py b/google/ads/googleads/v23/services/services/recommendation_subscription_service/async_client.py new file mode 100644 index 000000000..9d1d1f30f --- /dev/null +++ b/google/ads/googleads/v23/services/services/recommendation_subscription_service/async_client.py @@ -0,0 +1,447 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + recommendation_subscription_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + RecommendationSubscriptionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import RecommendationSubscriptionServiceClient + +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 RecommendationSubscriptionServiceAsyncClient: + """Service to manage recommendation subscriptions.""" + + _client: RecommendationSubscriptionServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = RecommendationSubscriptionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + RecommendationSubscriptionServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + RecommendationSubscriptionServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ( + RecommendationSubscriptionServiceClient._DEFAULT_UNIVERSE + ) + + recommendation_subscription_path = staticmethod( + RecommendationSubscriptionServiceClient.recommendation_subscription_path + ) + parse_recommendation_subscription_path = staticmethod( + RecommendationSubscriptionServiceClient.parse_recommendation_subscription_path + ) + common_billing_account_path = staticmethod( + RecommendationSubscriptionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + RecommendationSubscriptionServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + RecommendationSubscriptionServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + RecommendationSubscriptionServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + RecommendationSubscriptionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + RecommendationSubscriptionServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + RecommendationSubscriptionServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + RecommendationSubscriptionServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + RecommendationSubscriptionServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + RecommendationSubscriptionServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RecommendationSubscriptionServiceAsyncClient: The constructed client. + """ + return RecommendationSubscriptionServiceClient.from_service_account_info.__func__(RecommendationSubscriptionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RecommendationSubscriptionServiceAsyncClient: The constructed client. + """ + return RecommendationSubscriptionServiceClient.from_service_account_file.__func__(RecommendationSubscriptionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return RecommendationSubscriptionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> RecommendationSubscriptionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + RecommendationSubscriptionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + RecommendationSubscriptionServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + RecommendationSubscriptionServiceTransport, + Callable[..., RecommendationSubscriptionServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the recommendation subscription service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,RecommendationSubscriptionServiceTransport,Callable[..., RecommendationSubscriptionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the RecommendationSubscriptionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = RecommendationSubscriptionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.RecommendationSubscriptionServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.RecommendationSubscriptionService", + "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.ads.googleads.v23.services.RecommendationSubscriptionService", + "credentialsType": None, + } + ), + ) + + async def mutate_recommendation_subscription( + self, + request: Optional[ + Union[ + recommendation_subscription_service.MutateRecommendationSubscriptionRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + recommendation_subscription_service.RecommendationSubscriptionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + recommendation_subscription_service.MutateRecommendationSubscriptionResponse + ): + r"""Mutates given subscription with corresponding apply parameters. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RecommendationError <>`__ + `RecommendationSubscriptionError <>`__ `RequestError <>`__ + `UrlFieldError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateRecommendationSubscriptionRequest, dict]]): + The request object. Request message for + [RecommendationSubscriptionService.MutateRecommendationSubscription][google.ads.googleads.v23.services.RecommendationSubscriptionService.MutateRecommendationSubscription] + customer_id (:class:`str`): + Required. The ID of the subscribing + customer. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.RecommendationSubscriptionOperation]`): + Required. The list of create or + update operations. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateRecommendationSubscriptionResponse: + Response message for + [RecommendationSubscriptionService.MutateRecommendationSubscription][google.ads.googleads.v23.services.RecommendationSubscriptionService.MutateRecommendationSubscription] + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + recommendation_subscription_service.MutateRecommendationSubscriptionRequest, + ): + request = recommendation_subscription_service.MutateRecommendationSubscriptionRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_recommendation_subscription + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__( + self, + ) -> "RecommendationSubscriptionServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("RecommendationSubscriptionServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/recommendation_subscription_service/client.py b/google/ads/googleads/v23/services/services/recommendation_subscription_service/client.py new file mode 100644 index 000000000..a5c8fd30f --- /dev/null +++ b/google/ads/googleads/v23/services/services/recommendation_subscription_service/client.py @@ -0,0 +1,930 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + recommendation_subscription_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + RecommendationSubscriptionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import RecommendationSubscriptionServiceGrpcTransport +from .transports.grpc_asyncio import ( + RecommendationSubscriptionServiceGrpcAsyncIOTransport, +) + + +class RecommendationSubscriptionServiceClientMeta(type): + """Metaclass for the RecommendationSubscriptionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[RecommendationSubscriptionServiceTransport]] + _transport_registry["grpc"] = RecommendationSubscriptionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + RecommendationSubscriptionServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[RecommendationSubscriptionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class RecommendationSubscriptionServiceClient( + metaclass=RecommendationSubscriptionServiceClientMeta +): + """Service to manage recommendation subscriptions.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RecommendationSubscriptionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RecommendationSubscriptionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> RecommendationSubscriptionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + RecommendationSubscriptionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def recommendation_subscription_path( + customer_id: str, + recommendation_type: str, + ) -> str: + """Returns a fully-qualified recommendation_subscription string.""" + return "customers/{customer_id}/recommendationSubscriptions/{recommendation_type}".format( + customer_id=customer_id, + recommendation_type=recommendation_type, + ) + + @staticmethod + def parse_recommendation_subscription_path(path: str) -> Dict[str, str]: + """Parses a recommendation_subscription path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/recommendationSubscriptions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + RecommendationSubscriptionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + RecommendationSubscriptionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + RecommendationSubscriptionServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + RecommendationSubscriptionServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = RecommendationSubscriptionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + RecommendationSubscriptionServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + RecommendationSubscriptionServiceTransport, + Callable[..., RecommendationSubscriptionServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the recommendation subscription service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,RecommendationSubscriptionServiceTransport,Callable[..., RecommendationSubscriptionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the RecommendationSubscriptionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ( + RecommendationSubscriptionServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + RecommendationSubscriptionServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + RecommendationSubscriptionServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, RecommendationSubscriptionServiceTransport + ) + if transport_provided: + # transport is a RecommendationSubscriptionServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + RecommendationSubscriptionServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or RecommendationSubscriptionServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[RecommendationSubscriptionServiceTransport], + Callable[..., RecommendationSubscriptionServiceTransport], + ] = ( + RecommendationSubscriptionServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., RecommendationSubscriptionServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.RecommendationSubscriptionServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.RecommendationSubscriptionService", + "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.ads.googleads.v23.services.RecommendationSubscriptionService", + "credentialsType": None, + } + ), + ) + + def mutate_recommendation_subscription( + self, + request: Optional[ + Union[ + recommendation_subscription_service.MutateRecommendationSubscriptionRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + recommendation_subscription_service.RecommendationSubscriptionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + recommendation_subscription_service.MutateRecommendationSubscriptionResponse + ): + r"""Mutates given subscription with corresponding apply parameters. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RecommendationError <>`__ + `RecommendationSubscriptionError <>`__ `RequestError <>`__ + `UrlFieldError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateRecommendationSubscriptionRequest, dict]): + The request object. Request message for + [RecommendationSubscriptionService.MutateRecommendationSubscription][google.ads.googleads.v23.services.RecommendationSubscriptionService.MutateRecommendationSubscription] + customer_id (str): + Required. The ID of the subscribing + customer. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.RecommendationSubscriptionOperation]): + Required. The list of create or + update operations. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateRecommendationSubscriptionResponse: + Response message for + [RecommendationSubscriptionService.MutateRecommendationSubscription][google.ads.googleads.v23.services.RecommendationSubscriptionService.MutateRecommendationSubscription] + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + recommendation_subscription_service.MutateRecommendationSubscriptionRequest, + ): + request = recommendation_subscription_service.MutateRecommendationSubscriptionRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_recommendation_subscription + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "RecommendationSubscriptionServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("RecommendationSubscriptionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/README.rst b/google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/README.rst rename to google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/__init__.py b/google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/recommendation_subscription_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/base.py b/google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/base.py new file mode 100644 index 000000000..bdd530eee --- /dev/null +++ b/google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + recommendation_subscription_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class RecommendationSubscriptionServiceTransport(abc.ABC): + """Abstract transport class for RecommendationSubscriptionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_recommendation_subscription: gapic_v1.method.wrap_method( + self.mutate_recommendation_subscription, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_recommendation_subscription( + self, + ) -> Callable[ + [ + recommendation_subscription_service.MutateRecommendationSubscriptionRequest + ], + Union[ + recommendation_subscription_service.MutateRecommendationSubscriptionResponse, + Awaitable[ + recommendation_subscription_service.MutateRecommendationSubscriptionResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("RecommendationSubscriptionServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/grpc.py b/google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/grpc.py new file mode 100644 index 000000000..4cfc4bb00 --- /dev/null +++ b/google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/grpc.py @@ -0,0 +1,400 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + recommendation_subscription_service, +) +from .base import ( + RecommendationSubscriptionServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.RecommendationSubscriptionService", + "rpcName": str(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.ads.googleads.v23.services.RecommendationSubscriptionService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class RecommendationSubscriptionServiceGrpcTransport( + RecommendationSubscriptionServiceTransport +): + """gRPC backend transport for RecommendationSubscriptionService. + + Service to manage recommendation subscriptions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_recommendation_subscription( + self, + ) -> Callable[ + [ + recommendation_subscription_service.MutateRecommendationSubscriptionRequest + ], + recommendation_subscription_service.MutateRecommendationSubscriptionResponse, + ]: + r"""Return a callable for the mutate recommendation + subscription method over gRPC. + + Mutates given subscription with corresponding apply parameters. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RecommendationError <>`__ + `RecommendationSubscriptionError <>`__ `RequestError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateRecommendationSubscriptionRequest], + ~.MutateRecommendationSubscriptionResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_recommendation_subscription" not in self._stubs: + self._stubs["mutate_recommendation_subscription"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.RecommendationSubscriptionService/MutateRecommendationSubscription", + request_serializer=recommendation_subscription_service.MutateRecommendationSubscriptionRequest.serialize, + response_deserializer=recommendation_subscription_service.MutateRecommendationSubscriptionResponse.deserialize, + ) + ) + return self._stubs["mutate_recommendation_subscription"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("RecommendationSubscriptionServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..45dfed6d5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/recommendation_subscription_service/transports/grpc_asyncio.py @@ -0,0 +1,423 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + recommendation_subscription_service, +) +from .base import ( + RecommendationSubscriptionServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.RecommendationSubscriptionService", + "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.ads.googleads.v23.services.RecommendationSubscriptionService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class RecommendationSubscriptionServiceGrpcAsyncIOTransport( + RecommendationSubscriptionServiceTransport +): + """gRPC AsyncIO backend transport for RecommendationSubscriptionService. + + Service to manage recommendation subscriptions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_recommendation_subscription( + self, + ) -> Callable[ + [ + recommendation_subscription_service.MutateRecommendationSubscriptionRequest + ], + Awaitable[ + recommendation_subscription_service.MutateRecommendationSubscriptionResponse + ], + ]: + r"""Return a callable for the mutate recommendation + subscription method over gRPC. + + Mutates given subscription with corresponding apply parameters. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `FieldError <>`__ + `HeaderError <>`__ `InternalError <>`__ `MutateError <>`__ + `QuotaError <>`__ `RecommendationError <>`__ + `RecommendationSubscriptionError <>`__ `RequestError <>`__ + `UrlFieldError <>`__ + + Returns: + Callable[[~.MutateRecommendationSubscriptionRequest], + Awaitable[~.MutateRecommendationSubscriptionResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_recommendation_subscription" not in self._stubs: + self._stubs["mutate_recommendation_subscription"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.RecommendationSubscriptionService/MutateRecommendationSubscription", + request_serializer=recommendation_subscription_service.MutateRecommendationSubscriptionRequest.serialize, + response_deserializer=recommendation_subscription_service.MutateRecommendationSubscriptionResponse.deserialize, + ) + ) + return self._stubs["mutate_recommendation_subscription"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_recommendation_subscription: self._wrap_method( + self.mutate_recommendation_subscription, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("RecommendationSubscriptionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/remarketing_action_service/__init__.py b/google/ads/googleads/v23/services/services/remarketing_action_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/remarketing_action_service/__init__.py rename to google/ads/googleads/v23/services/services/remarketing_action_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/remarketing_action_service/async_client.py b/google/ads/googleads/v23/services/services/remarketing_action_service/async_client.py new file mode 100644 index 000000000..0a8d3ce71 --- /dev/null +++ b/google/ads/googleads/v23/services/services/remarketing_action_service/async_client.py @@ -0,0 +1,436 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import remarketing_action_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + RemarketingActionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import RemarketingActionServiceClient + +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 RemarketingActionServiceAsyncClient: + """Service to manage remarketing actions.""" + + _client: RemarketingActionServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = RemarketingActionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = RemarketingActionServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + RemarketingActionServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = RemarketingActionServiceClient._DEFAULT_UNIVERSE + + remarketing_action_path = staticmethod( + RemarketingActionServiceClient.remarketing_action_path + ) + parse_remarketing_action_path = staticmethod( + RemarketingActionServiceClient.parse_remarketing_action_path + ) + common_billing_account_path = staticmethod( + RemarketingActionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + RemarketingActionServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + RemarketingActionServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + RemarketingActionServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + RemarketingActionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + RemarketingActionServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + RemarketingActionServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + RemarketingActionServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + RemarketingActionServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + RemarketingActionServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RemarketingActionServiceAsyncClient: The constructed client. + """ + return RemarketingActionServiceClient.from_service_account_info.__func__(RemarketingActionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RemarketingActionServiceAsyncClient: The constructed client. + """ + return RemarketingActionServiceClient.from_service_account_file.__func__(RemarketingActionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return RemarketingActionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> RemarketingActionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + RemarketingActionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = RemarketingActionServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + RemarketingActionServiceTransport, + Callable[..., RemarketingActionServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the remarketing action service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,RemarketingActionServiceTransport,Callable[..., RemarketingActionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the RemarketingActionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = RemarketingActionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.RemarketingActionServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.RemarketingActionService", + "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.ads.googleads.v23.services.RemarketingActionService", + "credentialsType": None, + } + ), + ) + + async def mutate_remarketing_actions( + self, + request: Optional[ + Union[ + remarketing_action_service.MutateRemarketingActionsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + remarketing_action_service.RemarketingActionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> remarketing_action_service.MutateRemarketingActionsResponse: + r"""Creates or updates remarketing actions. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateRemarketingActionsRequest, dict]]): + The request object. Request message for + [RemarketingActionService.MutateRemarketingActions][google.ads.googleads.v23.services.RemarketingActionService.MutateRemarketingActions]. + customer_id (:class:`str`): + Required. The ID of the customer + whose remarketing actions are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.RemarketingActionOperation]`): + Required. The list of operations to + perform on individual remarketing + actions. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateRemarketingActionsResponse: + Response message for remarketing + action mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, remarketing_action_service.MutateRemarketingActionsRequest + ): + request = ( + remarketing_action_service.MutateRemarketingActionsRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_remarketing_actions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "RemarketingActionServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("RemarketingActionServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/remarketing_action_service/client.py b/google/ads/googleads/v23/services/services/remarketing_action_service/client.py new file mode 100644 index 000000000..369f028f2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/remarketing_action_service/client.py @@ -0,0 +1,914 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import remarketing_action_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + RemarketingActionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import RemarketingActionServiceGrpcTransport +from .transports.grpc_asyncio import ( + RemarketingActionServiceGrpcAsyncIOTransport, +) + + +class RemarketingActionServiceClientMeta(type): + """Metaclass for the RemarketingActionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[RemarketingActionServiceTransport]] + _transport_registry["grpc"] = RemarketingActionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + RemarketingActionServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[RemarketingActionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class RemarketingActionServiceClient( + metaclass=RemarketingActionServiceClientMeta +): + """Service to manage remarketing actions.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RemarketingActionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + RemarketingActionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> RemarketingActionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + RemarketingActionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def remarketing_action_path( + customer_id: str, + remarketing_action_id: str, + ) -> str: + """Returns a fully-qualified remarketing_action string.""" + return "customers/{customer_id}/remarketingActions/{remarketing_action_id}".format( + customer_id=customer_id, + remarketing_action_id=remarketing_action_id, + ) + + @staticmethod + def parse_remarketing_action_path(path: str) -> Dict[str, str]: + """Parses a remarketing_action path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/remarketingActions/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + RemarketingActionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + RemarketingActionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = RemarketingActionServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = RemarketingActionServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = RemarketingActionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = RemarketingActionServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + RemarketingActionServiceTransport, + Callable[..., RemarketingActionServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the remarketing action service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,RemarketingActionServiceTransport,Callable[..., RemarketingActionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the RemarketingActionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = RemarketingActionServiceClient._read_environment_variables() + self._client_cert_source = ( + RemarketingActionServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + RemarketingActionServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, RemarketingActionServiceTransport + ) + if transport_provided: + # transport is a RemarketingActionServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(RemarketingActionServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or RemarketingActionServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[RemarketingActionServiceTransport], + Callable[..., RemarketingActionServiceTransport], + ] = ( + RemarketingActionServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., RemarketingActionServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.RemarketingActionServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.RemarketingActionService", + "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.ads.googleads.v23.services.RemarketingActionService", + "credentialsType": None, + } + ), + ) + + def mutate_remarketing_actions( + self, + request: Optional[ + Union[ + remarketing_action_service.MutateRemarketingActionsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + remarketing_action_service.RemarketingActionOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> remarketing_action_service.MutateRemarketingActionsResponse: + r"""Creates or updates remarketing actions. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateRemarketingActionsRequest, dict]): + The request object. Request message for + [RemarketingActionService.MutateRemarketingActions][google.ads.googleads.v23.services.RemarketingActionService.MutateRemarketingActions]. + customer_id (str): + Required. The ID of the customer + whose remarketing actions are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.RemarketingActionOperation]): + Required. The list of operations to + perform on individual remarketing + actions. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateRemarketingActionsResponse: + Response message for remarketing + action mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, remarketing_action_service.MutateRemarketingActionsRequest + ): + request = ( + remarketing_action_service.MutateRemarketingActionsRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_remarketing_actions + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "RemarketingActionServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("RemarketingActionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/remarketing_action_service/transports/README.rst b/google/ads/googleads/v23/services/services/remarketing_action_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/remarketing_action_service/transports/README.rst rename to google/ads/googleads/v23/services/services/remarketing_action_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/remarketing_action_service/transports/__init__.py b/google/ads/googleads/v23/services/services/remarketing_action_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/remarketing_action_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/remarketing_action_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/remarketing_action_service/transports/base.py b/google/ads/googleads/v23/services/services/remarketing_action_service/transports/base.py new file mode 100644 index 000000000..8fb2fb231 --- /dev/null +++ b/google/ads/googleads/v23/services/services/remarketing_action_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import remarketing_action_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class RemarketingActionServiceTransport(abc.ABC): + """Abstract transport class for RemarketingActionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_remarketing_actions: gapic_v1.method.wrap_method( + self.mutate_remarketing_actions, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_remarketing_actions( + self, + ) -> Callable[ + [remarketing_action_service.MutateRemarketingActionsRequest], + Union[ + remarketing_action_service.MutateRemarketingActionsResponse, + Awaitable[ + remarketing_action_service.MutateRemarketingActionsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("RemarketingActionServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/remarketing_action_service/transports/grpc.py b/google/ads/googleads/v23/services/services/remarketing_action_service/transports/grpc.py new file mode 100644 index 000000000..2536c832a --- /dev/null +++ b/google/ads/googleads/v23/services/services/remarketing_action_service/transports/grpc.py @@ -0,0 +1,389 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import remarketing_action_service +from .base import RemarketingActionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.RemarketingActionService", + "rpcName": str(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.ads.googleads.v23.services.RemarketingActionService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class RemarketingActionServiceGrpcTransport(RemarketingActionServiceTransport): + """gRPC backend transport for RemarketingActionService. + + Service to manage remarketing actions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_remarketing_actions( + self, + ) -> Callable[ + [remarketing_action_service.MutateRemarketingActionsRequest], + remarketing_action_service.MutateRemarketingActionsResponse, + ]: + r"""Return a callable for the mutate remarketing actions method over gRPC. + + Creates or updates remarketing actions. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateRemarketingActionsRequest], + ~.MutateRemarketingActionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_remarketing_actions" not in self._stubs: + self._stubs["mutate_remarketing_actions"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.RemarketingActionService/MutateRemarketingActions", + request_serializer=remarketing_action_service.MutateRemarketingActionsRequest.serialize, + response_deserializer=remarketing_action_service.MutateRemarketingActionsResponse.deserialize, + ) + ) + return self._stubs["mutate_remarketing_actions"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("RemarketingActionServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/remarketing_action_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/remarketing_action_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..5b596518d --- /dev/null +++ b/google/ads/googleads/v23/services/services/remarketing_action_service/transports/grpc_asyncio.py @@ -0,0 +1,412 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import remarketing_action_service +from .base import RemarketingActionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.RemarketingActionService", + "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.ads.googleads.v23.services.RemarketingActionService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class RemarketingActionServiceGrpcAsyncIOTransport( + RemarketingActionServiceTransport +): + """gRPC AsyncIO backend transport for RemarketingActionService. + + Service to manage remarketing actions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_remarketing_actions( + self, + ) -> Callable[ + [remarketing_action_service.MutateRemarketingActionsRequest], + Awaitable[remarketing_action_service.MutateRemarketingActionsResponse], + ]: + r"""Return a callable for the mutate remarketing actions method over gRPC. + + Creates or updates remarketing actions. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `ConversionActionError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateRemarketingActionsRequest], + Awaitable[~.MutateRemarketingActionsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_remarketing_actions" not in self._stubs: + self._stubs["mutate_remarketing_actions"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.RemarketingActionService/MutateRemarketingActions", + request_serializer=remarketing_action_service.MutateRemarketingActionsRequest.serialize, + response_deserializer=remarketing_action_service.MutateRemarketingActionsResponse.deserialize, + ) + ) + return self._stubs["mutate_remarketing_actions"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_remarketing_actions: self._wrap_method( + self.mutate_remarketing_actions, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("RemarketingActionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/shareable_preview_service/__init__.py b/google/ads/googleads/v23/services/services/shareable_preview_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/shareable_preview_service/__init__.py rename to google/ads/googleads/v23/services/services/shareable_preview_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/shareable_preview_service/async_client.py b/google/ads/googleads/v23/services/services/shareable_preview_service/async_client.py new file mode 100644 index 000000000..59f4d5f4e --- /dev/null +++ b/google/ads/googleads/v23/services/services/shareable_preview_service/async_client.py @@ -0,0 +1,419 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import shareable_preview_service +from .transports.base import ( + ShareablePreviewServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import ShareablePreviewServiceClient + +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 ShareablePreviewServiceAsyncClient: + """Service to generate Shareable Previews.""" + + _client: ShareablePreviewServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ShareablePreviewServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ShareablePreviewServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + ShareablePreviewServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ShareablePreviewServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod( + ShareablePreviewServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ShareablePreviewServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ShareablePreviewServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ShareablePreviewServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ShareablePreviewServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ShareablePreviewServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ShareablePreviewServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ShareablePreviewServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ShareablePreviewServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ShareablePreviewServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ShareablePreviewServiceAsyncClient: The constructed client. + """ + return ShareablePreviewServiceClient.from_service_account_info.__func__(ShareablePreviewServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ShareablePreviewServiceAsyncClient: The constructed client. + """ + return ShareablePreviewServiceClient.from_service_account_file.__func__(ShareablePreviewServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ShareablePreviewServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ShareablePreviewServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ShareablePreviewServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ShareablePreviewServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ShareablePreviewServiceTransport, + Callable[..., ShareablePreviewServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the shareable preview service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ShareablePreviewServiceTransport,Callable[..., ShareablePreviewServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ShareablePreviewServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ShareablePreviewServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ShareablePreviewServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ShareablePreviewService", + "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.ads.googleads.v23.services.ShareablePreviewService", + "credentialsType": None, + } + ), + ) + + async def generate_shareable_previews( + self, + request: Optional[ + Union[ + shareable_preview_service.GenerateShareablePreviewsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + shareable_previews: Optional[ + MutableSequence[shareable_preview_service.ShareablePreview] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> shareable_preview_service.GenerateShareablePreviewsResponse: + r"""Returns the requested Shareable Preview. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GenerateShareablePreviewsRequest, dict]]): + The request object. Request message for + [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v23.services.ShareablePreviewService.GenerateShareablePreviews]. + customer_id (:class:`str`): + Required. The customer creating the + shareable previews request. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + shareable_previews (:class:`MutableSequence[google.ads.googleads.v23.services.types.ShareablePreview]`): + Required. The list of shareable + previews to generate. + + This corresponds to the ``shareable_previews`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateShareablePreviewsResponse: + Response message for + [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v23.services.ShareablePreviewService.GenerateShareablePreviews]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, shareable_previews] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, shareable_preview_service.GenerateShareablePreviewsRequest + ): + request = ( + shareable_preview_service.GenerateShareablePreviewsRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if shareable_previews: + request.shareable_previews.extend(shareable_previews) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.generate_shareable_previews + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ShareablePreviewServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ShareablePreviewServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/shareable_preview_service/client.py b/google/ads/googleads/v23/services/services/shareable_preview_service/client.py new file mode 100644 index 000000000..2451572e9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/shareable_preview_service/client.py @@ -0,0 +1,883 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import shareable_preview_service +from .transports.base import ( + ShareablePreviewServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ShareablePreviewServiceGrpcTransport +from .transports.grpc_asyncio import ShareablePreviewServiceGrpcAsyncIOTransport + + +class ShareablePreviewServiceClientMeta(type): + """Metaclass for the ShareablePreviewService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ShareablePreviewServiceTransport]] + _transport_registry["grpc"] = ShareablePreviewServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + ShareablePreviewServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ShareablePreviewServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ShareablePreviewServiceClient( + metaclass=ShareablePreviewServiceClientMeta +): + """Service to generate Shareable Previews.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ShareablePreviewServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ShareablePreviewServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ShareablePreviewServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ShareablePreviewServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ShareablePreviewServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ShareablePreviewServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ShareablePreviewServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ShareablePreviewServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + ShareablePreviewServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ShareablePreviewServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ShareablePreviewServiceTransport, + Callable[..., ShareablePreviewServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the shareable preview service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ShareablePreviewServiceTransport,Callable[..., ShareablePreviewServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ShareablePreviewServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ShareablePreviewServiceClient._read_environment_variables() + self._client_cert_source = ( + ShareablePreviewServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + ShareablePreviewServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ShareablePreviewServiceTransport + ) + if transport_provided: + # transport is a ShareablePreviewServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(ShareablePreviewServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ShareablePreviewServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ShareablePreviewServiceTransport], + Callable[..., ShareablePreviewServiceTransport], + ] = ( + ShareablePreviewServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ShareablePreviewServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ShareablePreviewServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ShareablePreviewService", + "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.ads.googleads.v23.services.ShareablePreviewService", + "credentialsType": None, + } + ), + ) + + def generate_shareable_previews( + self, + request: Optional[ + Union[ + shareable_preview_service.GenerateShareablePreviewsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + shareable_previews: Optional[ + MutableSequence[shareable_preview_service.ShareablePreview] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> shareable_preview_service.GenerateShareablePreviewsResponse: + r"""Returns the requested Shareable Preview. + + Args: + request (Union[google.ads.googleads.v23.services.types.GenerateShareablePreviewsRequest, dict]): + The request object. Request message for + [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v23.services.ShareablePreviewService.GenerateShareablePreviews]. + customer_id (str): + Required. The customer creating the + shareable previews request. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + shareable_previews (MutableSequence[google.ads.googleads.v23.services.types.ShareablePreview]): + Required. The list of shareable + previews to generate. + + This corresponds to the ``shareable_previews`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GenerateShareablePreviewsResponse: + Response message for + [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v23.services.ShareablePreviewService.GenerateShareablePreviews]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, shareable_previews] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, shareable_preview_service.GenerateShareablePreviewsRequest + ): + request = ( + shareable_preview_service.GenerateShareablePreviewsRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if shareable_previews is not None: + request.shareable_previews = shareable_previews + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.generate_shareable_previews + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ShareablePreviewServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ShareablePreviewServiceClient",) diff --git a/google/ads/googleads/v19/services/services/shareable_preview_service/transports/README.rst b/google/ads/googleads/v23/services/services/shareable_preview_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/shareable_preview_service/transports/README.rst rename to google/ads/googleads/v23/services/services/shareable_preview_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/shareable_preview_service/transports/__init__.py b/google/ads/googleads/v23/services/services/shareable_preview_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/shareable_preview_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/shareable_preview_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/shareable_preview_service/transports/base.py b/google/ads/googleads/v23/services/services/shareable_preview_service/transports/base.py new file mode 100644 index 000000000..31bd5629a --- /dev/null +++ b/google/ads/googleads/v23/services/services/shareable_preview_service/transports/base.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import shareable_preview_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ShareablePreviewServiceTransport(abc.ABC): + """Abstract transport class for ShareablePreviewService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.generate_shareable_previews: gapic_v1.method.wrap_method( + self.generate_shareable_previews, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def generate_shareable_previews( + self, + ) -> Callable[ + [shareable_preview_service.GenerateShareablePreviewsRequest], + Union[ + shareable_preview_service.GenerateShareablePreviewsResponse, + Awaitable[ + shareable_preview_service.GenerateShareablePreviewsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ShareablePreviewServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/shareable_preview_service/transports/grpc.py b/google/ads/googleads/v23/services/services/shareable_preview_service/transports/grpc.py new file mode 100644 index 000000000..a4082fca6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/shareable_preview_service/transports/grpc.py @@ -0,0 +1,383 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import shareable_preview_service +from .base import ShareablePreviewServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ShareablePreviewService", + "rpcName": str(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.ads.googleads.v23.services.ShareablePreviewService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ShareablePreviewServiceGrpcTransport(ShareablePreviewServiceTransport): + """gRPC backend transport for ShareablePreviewService. + + Service to generate Shareable Previews. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def generate_shareable_previews( + self, + ) -> Callable[ + [shareable_preview_service.GenerateShareablePreviewsRequest], + shareable_preview_service.GenerateShareablePreviewsResponse, + ]: + r"""Return a callable for the generate shareable previews method over gRPC. + + Returns the requested Shareable Preview. + + Returns: + Callable[[~.GenerateShareablePreviewsRequest], + ~.GenerateShareablePreviewsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_shareable_previews" not in self._stubs: + self._stubs["generate_shareable_previews"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ShareablePreviewService/GenerateShareablePreviews", + request_serializer=shareable_preview_service.GenerateShareablePreviewsRequest.serialize, + response_deserializer=shareable_preview_service.GenerateShareablePreviewsResponse.deserialize, + ) + ) + return self._stubs["generate_shareable_previews"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ShareablePreviewServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/shareable_preview_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/shareable_preview_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..521d8a524 --- /dev/null +++ b/google/ads/googleads/v23/services/services/shareable_preview_service/transports/grpc_asyncio.py @@ -0,0 +1,406 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import shareable_preview_service +from .base import ShareablePreviewServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ShareablePreviewService", + "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.ads.googleads.v23.services.ShareablePreviewService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ShareablePreviewServiceGrpcAsyncIOTransport( + ShareablePreviewServiceTransport +): + """gRPC AsyncIO backend transport for ShareablePreviewService. + + Service to generate Shareable Previews. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def generate_shareable_previews( + self, + ) -> Callable[ + [shareable_preview_service.GenerateShareablePreviewsRequest], + Awaitable[shareable_preview_service.GenerateShareablePreviewsResponse], + ]: + r"""Return a callable for the generate shareable previews method over gRPC. + + Returns the requested Shareable Preview. + + Returns: + Callable[[~.GenerateShareablePreviewsRequest], + Awaitable[~.GenerateShareablePreviewsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "generate_shareable_previews" not in self._stubs: + self._stubs["generate_shareable_previews"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ShareablePreviewService/GenerateShareablePreviews", + request_serializer=shareable_preview_service.GenerateShareablePreviewsRequest.serialize, + response_deserializer=shareable_preview_service.GenerateShareablePreviewsResponse.deserialize, + ) + ) + return self._stubs["generate_shareable_previews"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.generate_shareable_previews: self._wrap_method( + self.generate_shareable_previews, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ShareablePreviewServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/shared_criterion_service/__init__.py b/google/ads/googleads/v23/services/services/shared_criterion_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/shared_criterion_service/__init__.py rename to google/ads/googleads/v23/services/services/shared_criterion_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/shared_criterion_service/async_client.py b/google/ads/googleads/v23/services/services/shared_criterion_service/async_client.py new file mode 100644 index 000000000..f1ceee26f --- /dev/null +++ b/google/ads/googleads/v23/services/services/shared_criterion_service/async_client.py @@ -0,0 +1,444 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import shared_criterion_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + SharedCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import SharedCriterionServiceClient + +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 SharedCriterionServiceAsyncClient: + """Service to manage shared criteria.""" + + _client: SharedCriterionServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = SharedCriterionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = SharedCriterionServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + SharedCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = SharedCriterionServiceClient._DEFAULT_UNIVERSE + + mobile_app_category_constant_path = staticmethod( + SharedCriterionServiceClient.mobile_app_category_constant_path + ) + parse_mobile_app_category_constant_path = staticmethod( + SharedCriterionServiceClient.parse_mobile_app_category_constant_path + ) + shared_criterion_path = staticmethod( + SharedCriterionServiceClient.shared_criterion_path + ) + parse_shared_criterion_path = staticmethod( + SharedCriterionServiceClient.parse_shared_criterion_path + ) + shared_set_path = staticmethod(SharedCriterionServiceClient.shared_set_path) + parse_shared_set_path = staticmethod( + SharedCriterionServiceClient.parse_shared_set_path + ) + common_billing_account_path = staticmethod( + SharedCriterionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + SharedCriterionServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + SharedCriterionServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + SharedCriterionServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + SharedCriterionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + SharedCriterionServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + SharedCriterionServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + SharedCriterionServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + SharedCriterionServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + SharedCriterionServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedCriterionServiceAsyncClient: The constructed client. + """ + return SharedCriterionServiceClient.from_service_account_info.__func__(SharedCriterionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedCriterionServiceAsyncClient: The constructed client. + """ + return SharedCriterionServiceClient.from_service_account_file.__func__(SharedCriterionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return SharedCriterionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> SharedCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SharedCriterionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = SharedCriterionServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + SharedCriterionServiceTransport, + Callable[..., SharedCriterionServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the shared criterion service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,SharedCriterionServiceTransport,Callable[..., SharedCriterionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the SharedCriterionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = SharedCriterionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.SharedCriterionServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.SharedCriterionService", + "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.ads.googleads.v23.services.SharedCriterionService", + "credentialsType": None, + } + ), + ) + + async def mutate_shared_criteria( + self, + request: Optional[ + Union[shared_criterion_service.MutateSharedCriteriaRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[shared_criterion_service.SharedCriterionOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> shared_criterion_service.MutateSharedCriteriaResponse: + r"""Creates or removes shared criteria. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateSharedCriteriaRequest, dict]]): + The request object. Request message for + [SharedCriterionService.MutateSharedCriteria][google.ads.googleads.v23.services.SharedCriterionService.MutateSharedCriteria]. + customer_id (:class:`str`): + Required. The ID of the customer + whose shared criteria are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.SharedCriterionOperation]`): + Required. The list of operations to + perform on individual shared criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateSharedCriteriaResponse: + Response message for a shared + criterion mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, shared_criterion_service.MutateSharedCriteriaRequest + ): + request = shared_criterion_service.MutateSharedCriteriaRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_shared_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "SharedCriterionServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("SharedCriterionServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/shared_criterion_service/client.py b/google/ads/googleads/v23/services/services/shared_criterion_service/client.py new file mode 100644 index 000000000..d4f9c3184 --- /dev/null +++ b/google/ads/googleads/v23/services/services/shared_criterion_service/client.py @@ -0,0 +1,950 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import shared_criterion_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + SharedCriterionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import SharedCriterionServiceGrpcTransport +from .transports.grpc_asyncio import SharedCriterionServiceGrpcAsyncIOTransport + + +class SharedCriterionServiceClientMeta(type): + """Metaclass for the SharedCriterionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[SharedCriterionServiceTransport]] + _transport_registry["grpc"] = SharedCriterionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + SharedCriterionServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[SharedCriterionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class SharedCriterionServiceClient(metaclass=SharedCriterionServiceClientMeta): + """Service to manage shared criteria.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedCriterionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SharedCriterionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SharedCriterionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def mobile_app_category_constant_path( + mobile_app_category_id: str, + ) -> str: + """Returns a fully-qualified mobile_app_category_constant string.""" + return "mobileAppCategoryConstants/{mobile_app_category_id}".format( + mobile_app_category_id=mobile_app_category_id, + ) + + @staticmethod + def parse_mobile_app_category_constant_path(path: str) -> Dict[str, str]: + """Parses a mobile_app_category_constant path into its component segments.""" + m = re.match( + r"^mobileAppCategoryConstants/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_criterion_path( + customer_id: str, + shared_set_id: str, + criterion_id: str, + ) -> str: + """Returns a fully-qualified shared_criterion string.""" + return "customers/{customer_id}/sharedCriteria/{shared_set_id}~{criterion_id}".format( + customer_id=customer_id, + shared_set_id=shared_set_id, + criterion_id=criterion_id, + ) + + @staticmethod + def parse_shared_criterion_path(path: str) -> Dict[str, str]: + """Parses a shared_criterion path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedCriteria/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def shared_set_path( + customer_id: str, + shared_set_id: str, + ) -> str: + """Returns a fully-qualified shared_set string.""" + return "customers/{customer_id}/sharedSets/{shared_set_id}".format( + customer_id=customer_id, + shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_shared_set_path(path: str) -> Dict[str, str]: + """Parses a shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + SharedCriterionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + SharedCriterionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = SharedCriterionServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = SharedCriterionServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + SharedCriterionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = SharedCriterionServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + SharedCriterionServiceTransport, + Callable[..., SharedCriterionServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the shared criterion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,SharedCriterionServiceTransport,Callable[..., SharedCriterionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the SharedCriterionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = SharedCriterionServiceClient._read_environment_variables() + self._client_cert_source = ( + SharedCriterionServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + SharedCriterionServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, SharedCriterionServiceTransport + ) + if transport_provided: + # transport is a SharedCriterionServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(SharedCriterionServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or SharedCriterionServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[SharedCriterionServiceTransport], + Callable[..., SharedCriterionServiceTransport], + ] = ( + SharedCriterionServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., SharedCriterionServiceTransport], transport + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.SharedCriterionServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.SharedCriterionService", + "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.ads.googleads.v23.services.SharedCriterionService", + "credentialsType": None, + } + ), + ) + + def mutate_shared_criteria( + self, + request: Optional[ + Union[shared_criterion_service.MutateSharedCriteriaRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[shared_criterion_service.SharedCriterionOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> shared_criterion_service.MutateSharedCriteriaResponse: + r"""Creates or removes shared criteria. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateSharedCriteriaRequest, dict]): + The request object. Request message for + [SharedCriterionService.MutateSharedCriteria][google.ads.googleads.v23.services.SharedCriterionService.MutateSharedCriteria]. + customer_id (str): + Required. The ID of the customer + whose shared criteria are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.SharedCriterionOperation]): + Required. The list of operations to + perform on individual shared criteria. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateSharedCriteriaResponse: + Response message for a shared + criterion mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, shared_criterion_service.MutateSharedCriteriaRequest + ): + request = shared_criterion_service.MutateSharedCriteriaRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_shared_criteria + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "SharedCriterionServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("SharedCriterionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/shared_criterion_service/transports/README.rst b/google/ads/googleads/v23/services/services/shared_criterion_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/shared_criterion_service/transports/README.rst rename to google/ads/googleads/v23/services/services/shared_criterion_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/shared_criterion_service/transports/__init__.py b/google/ads/googleads/v23/services/services/shared_criterion_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/shared_criterion_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/shared_criterion_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/shared_criterion_service/transports/base.py b/google/ads/googleads/v23/services/services/shared_criterion_service/transports/base.py new file mode 100644 index 000000000..c50f94bda --- /dev/null +++ b/google/ads/googleads/v23/services/services/shared_criterion_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import shared_criterion_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class SharedCriterionServiceTransport(abc.ABC): + """Abstract transport class for SharedCriterionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_shared_criteria: gapic_v1.method.wrap_method( + self.mutate_shared_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_shared_criteria( + self, + ) -> Callable[ + [shared_criterion_service.MutateSharedCriteriaRequest], + Union[ + shared_criterion_service.MutateSharedCriteriaResponse, + Awaitable[shared_criterion_service.MutateSharedCriteriaResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("SharedCriterionServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/shared_criterion_service/transports/grpc.py b/google/ads/googleads/v23/services/services/shared_criterion_service/transports/grpc.py new file mode 100644 index 000000000..6e24a6deb --- /dev/null +++ b/google/ads/googleads/v23/services/services/shared_criterion_service/transports/grpc.py @@ -0,0 +1,394 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import shared_criterion_service +from .base import SharedCriterionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.SharedCriterionService", + "rpcName": str(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.ads.googleads.v23.services.SharedCriterionService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class SharedCriterionServiceGrpcTransport(SharedCriterionServiceTransport): + """gRPC backend transport for SharedCriterionService. + + Service to manage shared criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_shared_criteria( + self, + ) -> Callable[ + [shared_criterion_service.MutateSharedCriteriaRequest], + shared_criterion_service.MutateSharedCriteriaResponse, + ]: + r"""Return a callable for the mutate shared criteria method over gRPC. + + Creates or removes shared criteria. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateSharedCriteriaRequest], + ~.MutateSharedCriteriaResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_shared_criteria" not in self._stubs: + self._stubs["mutate_shared_criteria"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SharedCriterionService/MutateSharedCriteria", + request_serializer=shared_criterion_service.MutateSharedCriteriaRequest.serialize, + response_deserializer=shared_criterion_service.MutateSharedCriteriaResponse.deserialize, + ) + ) + return self._stubs["mutate_shared_criteria"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("SharedCriterionServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/shared_criterion_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/shared_criterion_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..f01fa24de --- /dev/null +++ b/google/ads/googleads/v23/services/services/shared_criterion_service/transports/grpc_asyncio.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import shared_criterion_service +from .base import SharedCriterionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.SharedCriterionService", + "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.ads.googleads.v23.services.SharedCriterionService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class SharedCriterionServiceGrpcAsyncIOTransport( + SharedCriterionServiceTransport +): + """gRPC AsyncIO backend transport for SharedCriterionService. + + Service to manage shared criteria. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_shared_criteria( + self, + ) -> Callable[ + [shared_criterion_service.MutateSharedCriteriaRequest], + Awaitable[shared_criterion_service.MutateSharedCriteriaResponse], + ]: + r"""Return a callable for the mutate shared criteria method over gRPC. + + Creates or removes shared criteria. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CriterionError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NotEmptyError <>`__ `NullError <>`__ + `OperatorError <>`__ `QuotaError <>`__ `RangeError <>`__ + `RequestError <>`__ `ResourceCountLimitExceededError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateSharedCriteriaRequest], + Awaitable[~.MutateSharedCriteriaResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_shared_criteria" not in self._stubs: + self._stubs["mutate_shared_criteria"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SharedCriterionService/MutateSharedCriteria", + request_serializer=shared_criterion_service.MutateSharedCriteriaRequest.serialize, + response_deserializer=shared_criterion_service.MutateSharedCriteriaResponse.deserialize, + ) + ) + return self._stubs["mutate_shared_criteria"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_shared_criteria: self._wrap_method( + self.mutate_shared_criteria, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("SharedCriterionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/shared_set_service/__init__.py b/google/ads/googleads/v23/services/services/shared_set_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/shared_set_service/__init__.py rename to google/ads/googleads/v23/services/services/shared_set_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/shared_set_service/async_client.py b/google/ads/googleads/v23/services/services/shared_set_service/async_client.py new file mode 100644 index 000000000..fb1eb7459 --- /dev/null +++ b/google/ads/googleads/v23/services/services/shared_set_service/async_client.py @@ -0,0 +1,423 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import shared_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import SharedSetServiceTransport, DEFAULT_CLIENT_INFO +from .client import SharedSetServiceClient + +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 SharedSetServiceAsyncClient: + """Service to manage shared sets.""" + + _client: SharedSetServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = SharedSetServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = SharedSetServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + SharedSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = SharedSetServiceClient._DEFAULT_UNIVERSE + + shared_set_path = staticmethod(SharedSetServiceClient.shared_set_path) + parse_shared_set_path = staticmethod( + SharedSetServiceClient.parse_shared_set_path + ) + common_billing_account_path = staticmethod( + SharedSetServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + SharedSetServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(SharedSetServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + SharedSetServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + SharedSetServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + SharedSetServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + SharedSetServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + SharedSetServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + SharedSetServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + SharedSetServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedSetServiceAsyncClient: The constructed client. + """ + return SharedSetServiceClient.from_service_account_info.__func__(SharedSetServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedSetServiceAsyncClient: The constructed client. + """ + return SharedSetServiceClient.from_service_account_file.__func__(SharedSetServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return SharedSetServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> SharedSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SharedSetServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = SharedSetServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + SharedSetServiceTransport, + Callable[..., SharedSetServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the shared set service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,SharedSetServiceTransport,Callable[..., SharedSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the SharedSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = SharedSetServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.SharedSetServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.SharedSetService", + "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.ads.googleads.v23.services.SharedSetService", + "credentialsType": None, + } + ), + ) + + async def mutate_shared_sets( + self, + request: Optional[ + Union[shared_set_service.MutateSharedSetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[shared_set_service.SharedSetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> shared_set_service.MutateSharedSetsResponse: + r"""Creates, updates, or removes shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SharedSetError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateSharedSetsRequest, dict]]): + The request object. Request message for + [SharedSetService.MutateSharedSets][google.ads.googleads.v23.services.SharedSetService.MutateSharedSets]. + customer_id (:class:`str`): + Required. The ID of the customer + whose shared sets are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.SharedSetOperation]`): + Required. The list of operations to + perform on individual shared sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateSharedSetsResponse: + Response message for a shared set + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, shared_set_service.MutateSharedSetsRequest): + request = shared_set_service.MutateSharedSetsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_shared_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "SharedSetServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("SharedSetServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/shared_set_service/client.py b/google/ads/googleads/v23/services/services/shared_set_service/client.py new file mode 100644 index 000000000..82a26d919 --- /dev/null +++ b/google/ads/googleads/v23/services/services/shared_set_service/client.py @@ -0,0 +1,891 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import shared_set_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import SharedSetServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import SharedSetServiceGrpcTransport +from .transports.grpc_asyncio import SharedSetServiceGrpcAsyncIOTransport + + +class SharedSetServiceClientMeta(type): + """Metaclass for the SharedSetService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[SharedSetServiceTransport]] + _transport_registry["grpc"] = SharedSetServiceGrpcTransport + _transport_registry["grpc_asyncio"] = SharedSetServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[SharedSetServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class SharedSetServiceClient(metaclass=SharedSetServiceClientMeta): + """Service to manage shared sets.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SharedSetServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SharedSetServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SharedSetServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def shared_set_path( + customer_id: str, + shared_set_id: str, + ) -> str: + """Returns a fully-qualified shared_set string.""" + return "customers/{customer_id}/sharedSets/{shared_set_id}".format( + customer_id=customer_id, + shared_set_id=shared_set_id, + ) + + @staticmethod + def parse_shared_set_path(path: str) -> Dict[str, str]: + """Parses a shared_set path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/sharedSets/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = SharedSetServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = SharedSetServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = SharedSetServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = SharedSetServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + SharedSetServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = SharedSetServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + SharedSetServiceTransport, + Callable[..., SharedSetServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the shared set service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,SharedSetServiceTransport,Callable[..., SharedSetServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the SharedSetServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = SharedSetServiceClient._read_environment_variables() + self._client_cert_source = ( + SharedSetServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = SharedSetServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, SharedSetServiceTransport) + if transport_provided: + # transport is a SharedSetServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(SharedSetServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or SharedSetServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[SharedSetServiceTransport], + Callable[..., SharedSetServiceTransport], + ] = ( + SharedSetServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., SharedSetServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.SharedSetServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.SharedSetService", + "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.ads.googleads.v23.services.SharedSetService", + "credentialsType": None, + } + ), + ) + + def mutate_shared_sets( + self, + request: Optional[ + Union[shared_set_service.MutateSharedSetsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[shared_set_service.SharedSetOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> shared_set_service.MutateSharedSetsResponse: + r"""Creates, updates, or removes shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SharedSetError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateSharedSetsRequest, dict]): + The request object. Request message for + [SharedSetService.MutateSharedSets][google.ads.googleads.v23.services.SharedSetService.MutateSharedSets]. + customer_id (str): + Required. The ID of the customer + whose shared sets are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.SharedSetOperation]): + Required. The list of operations to + perform on individual shared sets. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateSharedSetsResponse: + Response message for a shared set + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, shared_set_service.MutateSharedSetsRequest): + request = shared_set_service.MutateSharedSetsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_shared_sets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "SharedSetServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("SharedSetServiceClient",) diff --git a/google/ads/googleads/v19/services/services/shared_set_service/transports/README.rst b/google/ads/googleads/v23/services/services/shared_set_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/shared_set_service/transports/README.rst rename to google/ads/googleads/v23/services/services/shared_set_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/shared_set_service/transports/__init__.py b/google/ads/googleads/v23/services/services/shared_set_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/shared_set_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/shared_set_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/shared_set_service/transports/base.py b/google/ads/googleads/v23/services/services/shared_set_service/transports/base.py new file mode 100644 index 000000000..a6cdaaf83 --- /dev/null +++ b/google/ads/googleads/v23/services/services/shared_set_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import shared_set_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class SharedSetServiceTransport(abc.ABC): + """Abstract transport class for SharedSetService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_shared_sets: gapic_v1.method.wrap_method( + self.mutate_shared_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_shared_sets( + self, + ) -> Callable[ + [shared_set_service.MutateSharedSetsRequest], + Union[ + shared_set_service.MutateSharedSetsResponse, + Awaitable[shared_set_service.MutateSharedSetsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("SharedSetServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/shared_set_service/transports/grpc.py b/google/ads/googleads/v23/services/services/shared_set_service/transports/grpc.py new file mode 100644 index 000000000..573e17de7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/shared_set_service/transports/grpc.py @@ -0,0 +1,395 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import shared_set_service +from .base import SharedSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.SharedSetService", + "rpcName": str(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.ads.googleads.v23.services.SharedSetService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class SharedSetServiceGrpcTransport(SharedSetServiceTransport): + """gRPC backend transport for SharedSetService. + + Service to manage shared sets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_shared_sets( + self, + ) -> Callable[ + [shared_set_service.MutateSharedSetsRequest], + shared_set_service.MutateSharedSetsResponse, + ]: + r"""Return a callable for the mutate shared sets method over gRPC. + + Creates, updates, or removes shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SharedSetError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateSharedSetsRequest], + ~.MutateSharedSetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_shared_sets" not in self._stubs: + self._stubs["mutate_shared_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SharedSetService/MutateSharedSets", + request_serializer=shared_set_service.MutateSharedSetsRequest.serialize, + response_deserializer=shared_set_service.MutateSharedSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_shared_sets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("SharedSetServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/shared_set_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/shared_set_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..f2c8c710f --- /dev/null +++ b/google/ads/googleads/v23/services/services/shared_set_service/transports/grpc_asyncio.py @@ -0,0 +1,416 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import shared_set_service +from .base import SharedSetServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.SharedSetService", + "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.ads.googleads.v23.services.SharedSetService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class SharedSetServiceGrpcAsyncIOTransport(SharedSetServiceTransport): + """gRPC AsyncIO backend transport for SharedSetService. + + Service to manage shared sets. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_shared_sets( + self, + ) -> Callable[ + [shared_set_service.MutateSharedSetsRequest], + Awaitable[shared_set_service.MutateSharedSetsResponse], + ]: + r"""Return a callable for the mutate shared sets method over gRPC. + + Creates, updates, or removes shared sets. Operation statuses are + returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `DatabaseError <>`__ `DateError <>`__ + `DistinctError <>`__ `FieldError <>`__ `FieldMaskError <>`__ + `HeaderError <>`__ `IdError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotEmptyError <>`__ `NullError <>`__ `OperatorError <>`__ + `QuotaError <>`__ `RangeError <>`__ `RequestError <>`__ + `ResourceCountLimitExceededError <>`__ `SharedSetError <>`__ + `SizeLimitError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ + + Returns: + Callable[[~.MutateSharedSetsRequest], + Awaitable[~.MutateSharedSetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_shared_sets" not in self._stubs: + self._stubs["mutate_shared_sets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SharedSetService/MutateSharedSets", + request_serializer=shared_set_service.MutateSharedSetsRequest.serialize, + response_deserializer=shared_set_service.MutateSharedSetsResponse.deserialize, + ) + ) + return self._stubs["mutate_shared_sets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_shared_sets: self._wrap_method( + self.mutate_shared_sets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("SharedSetServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/__init__.py b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/smart_campaign_setting_service/__init__.py rename to google/ads/googleads/v23/services/services/smart_campaign_setting_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/smart_campaign_setting_service/async_client.py b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/async_client.py new file mode 100644 index 000000000..91e88c6a0 --- /dev/null +++ b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/async_client.py @@ -0,0 +1,538 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + smart_campaign_setting_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + SmartCampaignSettingServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import SmartCampaignSettingServiceClient + +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 SmartCampaignSettingServiceAsyncClient: + """Service to manage Smart campaign settings.""" + + _client: SmartCampaignSettingServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = SmartCampaignSettingServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + SmartCampaignSettingServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + SmartCampaignSettingServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = SmartCampaignSettingServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod( + SmartCampaignSettingServiceClient.campaign_path + ) + parse_campaign_path = staticmethod( + SmartCampaignSettingServiceClient.parse_campaign_path + ) + smart_campaign_setting_path = staticmethod( + SmartCampaignSettingServiceClient.smart_campaign_setting_path + ) + parse_smart_campaign_setting_path = staticmethod( + SmartCampaignSettingServiceClient.parse_smart_campaign_setting_path + ) + common_billing_account_path = staticmethod( + SmartCampaignSettingServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + SmartCampaignSettingServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + SmartCampaignSettingServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + SmartCampaignSettingServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + SmartCampaignSettingServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + SmartCampaignSettingServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + SmartCampaignSettingServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + SmartCampaignSettingServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + SmartCampaignSettingServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + SmartCampaignSettingServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSettingServiceAsyncClient: The constructed client. + """ + return SmartCampaignSettingServiceClient.from_service_account_info.__func__(SmartCampaignSettingServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSettingServiceAsyncClient: The constructed client. + """ + return SmartCampaignSettingServiceClient.from_service_account_file.__func__(SmartCampaignSettingServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return SmartCampaignSettingServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> SmartCampaignSettingServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SmartCampaignSettingServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = SmartCampaignSettingServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + SmartCampaignSettingServiceTransport, + Callable[..., SmartCampaignSettingServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the smart campaign setting service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,SmartCampaignSettingServiceTransport,Callable[..., SmartCampaignSettingServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the SmartCampaignSettingServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = SmartCampaignSettingServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.SmartCampaignSettingServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.SmartCampaignSettingService", + "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.ads.googleads.v23.services.SmartCampaignSettingService", + "credentialsType": None, + } + ), + ) + + async def get_smart_campaign_status( + self, + request: Optional[ + Union[ + smart_campaign_setting_service.GetSmartCampaignStatusRequest, + dict, + ] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> smart_campaign_setting_service.GetSmartCampaignStatusResponse: + r"""Returns the status of the requested Smart campaign. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.GetSmartCampaignStatusRequest, dict]]): + The request object. Request message for + [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v23.services.SmartCampaignSettingService.GetSmartCampaignStatus]. + resource_name (:class:`str`): + Required. The resource name of the + Smart campaign setting belonging to the + Smart campaign to fetch the status of. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GetSmartCampaignStatusResponse: + Response message for + [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v23.services.SmartCampaignSettingService.GetSmartCampaignStatus]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + smart_campaign_setting_service.GetSmartCampaignStatusRequest, + ): + request = ( + smart_campaign_setting_service.GetSmartCampaignStatusRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.get_smart_campaign_status + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def mutate_smart_campaign_settings( + self, + request: Optional[ + Union[ + smart_campaign_setting_service.MutateSmartCampaignSettingsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + smart_campaign_setting_service.SmartCampaignSettingOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> smart_campaign_setting_service.MutateSmartCampaignSettingsResponse: + r"""Updates Smart campaign settings for campaigns. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateSmartCampaignSettingsRequest, dict]]): + The request object. Request message for + [SmartCampaignSettingService.MutateSmartCampaignSettings][google.ads.googleads.v23.services.SmartCampaignSettingService.MutateSmartCampaignSettings]. + customer_id (:class:`str`): + Required. The ID of the customer + whose Smart campaign settings are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.SmartCampaignSettingOperation]`): + Required. The list of operations to + perform on individual Smart campaign + settings. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateSmartCampaignSettingsResponse: + Response message for campaign mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + smart_campaign_setting_service.MutateSmartCampaignSettingsRequest, + ): + request = smart_campaign_setting_service.MutateSmartCampaignSettingsRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_smart_campaign_settings + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "SmartCampaignSettingServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("SmartCampaignSettingServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/smart_campaign_setting_service/client.py b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/client.py new file mode 100644 index 000000000..2c0d735ec --- /dev/null +++ b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/client.py @@ -0,0 +1,1034 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + smart_campaign_setting_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + SmartCampaignSettingServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import SmartCampaignSettingServiceGrpcTransport +from .transports.grpc_asyncio import ( + SmartCampaignSettingServiceGrpcAsyncIOTransport, +) + + +class SmartCampaignSettingServiceClientMeta(type): + """Metaclass for the SmartCampaignSettingService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[SmartCampaignSettingServiceTransport]] + _transport_registry["grpc"] = SmartCampaignSettingServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + SmartCampaignSettingServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[SmartCampaignSettingServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class SmartCampaignSettingServiceClient( + metaclass=SmartCampaignSettingServiceClientMeta +): + """Service to manage Smart campaign settings.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSettingServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSettingServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SmartCampaignSettingServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SmartCampaignSettingServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def smart_campaign_setting_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified smart_campaign_setting string.""" + return "customers/{customer_id}/smartCampaignSettings/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_smart_campaign_setting_path(path: str) -> Dict[str, str]: + """Parses a smart_campaign_setting path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/smartCampaignSettings/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + SmartCampaignSettingServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + SmartCampaignSettingServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + SmartCampaignSettingServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + SmartCampaignSettingServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = SmartCampaignSettingServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = SmartCampaignSettingServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + SmartCampaignSettingServiceTransport, + Callable[..., SmartCampaignSettingServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the smart campaign setting service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,SmartCampaignSettingServiceTransport,Callable[..., SmartCampaignSettingServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the SmartCampaignSettingServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = SmartCampaignSettingServiceClient._read_environment_variables() + self._client_cert_source = ( + SmartCampaignSettingServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + SmartCampaignSettingServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, SmartCampaignSettingServiceTransport + ) + if transport_provided: + # transport is a SmartCampaignSettingServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + SmartCampaignSettingServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or SmartCampaignSettingServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[SmartCampaignSettingServiceTransport], + Callable[..., SmartCampaignSettingServiceTransport], + ] = ( + SmartCampaignSettingServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., SmartCampaignSettingServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.SmartCampaignSettingServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.SmartCampaignSettingService", + "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.ads.googleads.v23.services.SmartCampaignSettingService", + "credentialsType": None, + } + ), + ) + + def get_smart_campaign_status( + self, + request: Optional[ + Union[ + smart_campaign_setting_service.GetSmartCampaignStatusRequest, + dict, + ] + ] = None, + *, + resource_name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> smart_campaign_setting_service.GetSmartCampaignStatusResponse: + r"""Returns the status of the requested Smart campaign. + + Args: + request (Union[google.ads.googleads.v23.services.types.GetSmartCampaignStatusRequest, dict]): + The request object. Request message for + [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v23.services.SmartCampaignSettingService.GetSmartCampaignStatus]. + resource_name (str): + Required. The resource name of the + Smart campaign setting belonging to the + Smart campaign to fetch the status of. + + This corresponds to the ``resource_name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.GetSmartCampaignStatusResponse: + Response message for + [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v23.services.SmartCampaignSettingService.GetSmartCampaignStatus]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [resource_name] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + smart_campaign_setting_service.GetSmartCampaignStatusRequest, + ): + request = ( + smart_campaign_setting_service.GetSmartCampaignStatusRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if resource_name is not None: + request.resource_name = resource_name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.get_smart_campaign_status + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def mutate_smart_campaign_settings( + self, + request: Optional[ + Union[ + smart_campaign_setting_service.MutateSmartCampaignSettingsRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + smart_campaign_setting_service.SmartCampaignSettingOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> smart_campaign_setting_service.MutateSmartCampaignSettingsResponse: + r"""Updates Smart campaign settings for campaigns. + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateSmartCampaignSettingsRequest, dict]): + The request object. Request message for + [SmartCampaignSettingService.MutateSmartCampaignSettings][google.ads.googleads.v23.services.SmartCampaignSettingService.MutateSmartCampaignSettings]. + customer_id (str): + Required. The ID of the customer + whose Smart campaign settings are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.SmartCampaignSettingOperation]): + Required. The list of operations to + perform on individual Smart campaign + settings. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateSmartCampaignSettingsResponse: + Response message for campaign mutate. + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + smart_campaign_setting_service.MutateSmartCampaignSettingsRequest, + ): + request = smart_campaign_setting_service.MutateSmartCampaignSettingsRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_smart_campaign_settings + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "SmartCampaignSettingServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("SmartCampaignSettingServiceClient",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/README.rst b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/README.rst rename to google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/__init__.py b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/smart_campaign_setting_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/base.py b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/base.py new file mode 100644 index 000000000..37eead274 --- /dev/null +++ b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/base.py @@ -0,0 +1,196 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + smart_campaign_setting_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class SmartCampaignSettingServiceTransport(abc.ABC): + """Abstract transport class for SmartCampaignSettingService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.get_smart_campaign_status: gapic_v1.method.wrap_method( + self.get_smart_campaign_status, + default_timeout=None, + client_info=client_info, + ), + self.mutate_smart_campaign_settings: gapic_v1.method.wrap_method( + self.mutate_smart_campaign_settings, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def get_smart_campaign_status( + self, + ) -> Callable[ + [smart_campaign_setting_service.GetSmartCampaignStatusRequest], + Union[ + smart_campaign_setting_service.GetSmartCampaignStatusResponse, + Awaitable[ + smart_campaign_setting_service.GetSmartCampaignStatusResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def mutate_smart_campaign_settings( + self, + ) -> Callable[ + [smart_campaign_setting_service.MutateSmartCampaignSettingsRequest], + Union[ + smart_campaign_setting_service.MutateSmartCampaignSettingsResponse, + Awaitable[ + smart_campaign_setting_service.MutateSmartCampaignSettingsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("SmartCampaignSettingServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/grpc.py b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/grpc.py new file mode 100644 index 000000000..2f2dc4829 --- /dev/null +++ b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/grpc.py @@ -0,0 +1,418 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + smart_campaign_setting_service, +) +from .base import SmartCampaignSettingServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.SmartCampaignSettingService", + "rpcName": str(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.ads.googleads.v23.services.SmartCampaignSettingService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class SmartCampaignSettingServiceGrpcTransport( + SmartCampaignSettingServiceTransport +): + """gRPC backend transport for SmartCampaignSettingService. + + Service to manage Smart campaign settings. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def get_smart_campaign_status( + self, + ) -> Callable[ + [smart_campaign_setting_service.GetSmartCampaignStatusRequest], + smart_campaign_setting_service.GetSmartCampaignStatusResponse, + ]: + r"""Return a callable for the get smart campaign status method over gRPC. + + Returns the status of the requested Smart campaign. + + Returns: + Callable[[~.GetSmartCampaignStatusRequest], + ~.GetSmartCampaignStatusResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_smart_campaign_status" not in self._stubs: + self._stubs["get_smart_campaign_status"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SmartCampaignSettingService/GetSmartCampaignStatus", + request_serializer=smart_campaign_setting_service.GetSmartCampaignStatusRequest.serialize, + response_deserializer=smart_campaign_setting_service.GetSmartCampaignStatusResponse.deserialize, + ) + ) + return self._stubs["get_smart_campaign_status"] + + @property + def mutate_smart_campaign_settings( + self, + ) -> Callable[ + [smart_campaign_setting_service.MutateSmartCampaignSettingsRequest], + smart_campaign_setting_service.MutateSmartCampaignSettingsResponse, + ]: + r"""Return a callable for the mutate smart campaign settings method over gRPC. + + Updates Smart campaign settings for campaigns. + + Returns: + Callable[[~.MutateSmartCampaignSettingsRequest], + ~.MutateSmartCampaignSettingsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_smart_campaign_settings" not in self._stubs: + self._stubs["mutate_smart_campaign_settings"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SmartCampaignSettingService/MutateSmartCampaignSettings", + request_serializer=smart_campaign_setting_service.MutateSmartCampaignSettingsRequest.serialize, + response_deserializer=smart_campaign_setting_service.MutateSmartCampaignSettingsResponse.deserialize, + ) + ) + return self._stubs["mutate_smart_campaign_settings"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("SmartCampaignSettingServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..47f1f392f --- /dev/null +++ b/google/ads/googleads/v23/services/services/smart_campaign_setting_service/transports/grpc_asyncio.py @@ -0,0 +1,448 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + smart_campaign_setting_service, +) +from .base import SmartCampaignSettingServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.SmartCampaignSettingService", + "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.ads.googleads.v23.services.SmartCampaignSettingService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class SmartCampaignSettingServiceGrpcAsyncIOTransport( + SmartCampaignSettingServiceTransport +): + """gRPC AsyncIO backend transport for SmartCampaignSettingService. + + Service to manage Smart campaign settings. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def get_smart_campaign_status( + self, + ) -> Callable[ + [smart_campaign_setting_service.GetSmartCampaignStatusRequest], + Awaitable[ + smart_campaign_setting_service.GetSmartCampaignStatusResponse + ], + ]: + r"""Return a callable for the get smart campaign status method over gRPC. + + Returns the status of the requested Smart campaign. + + Returns: + Callable[[~.GetSmartCampaignStatusRequest], + Awaitable[~.GetSmartCampaignStatusResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_smart_campaign_status" not in self._stubs: + self._stubs["get_smart_campaign_status"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SmartCampaignSettingService/GetSmartCampaignStatus", + request_serializer=smart_campaign_setting_service.GetSmartCampaignStatusRequest.serialize, + response_deserializer=smart_campaign_setting_service.GetSmartCampaignStatusResponse.deserialize, + ) + ) + return self._stubs["get_smart_campaign_status"] + + @property + def mutate_smart_campaign_settings( + self, + ) -> Callable[ + [smart_campaign_setting_service.MutateSmartCampaignSettingsRequest], + Awaitable[ + smart_campaign_setting_service.MutateSmartCampaignSettingsResponse + ], + ]: + r"""Return a callable for the mutate smart campaign settings method over gRPC. + + Updates Smart campaign settings for campaigns. + + Returns: + Callable[[~.MutateSmartCampaignSettingsRequest], + Awaitable[~.MutateSmartCampaignSettingsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_smart_campaign_settings" not in self._stubs: + self._stubs["mutate_smart_campaign_settings"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SmartCampaignSettingService/MutateSmartCampaignSettings", + request_serializer=smart_campaign_setting_service.MutateSmartCampaignSettingsRequest.serialize, + response_deserializer=smart_campaign_setting_service.MutateSmartCampaignSettingsResponse.deserialize, + ) + ) + return self._stubs["mutate_smart_campaign_settings"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.get_smart_campaign_status: self._wrap_method( + self.get_smart_campaign_status, + default_timeout=None, + client_info=client_info, + ), + self.mutate_smart_campaign_settings: self._wrap_method( + self.mutate_smart_campaign_settings, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("SmartCampaignSettingServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/__init__.py b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/smart_campaign_suggest_service/__init__.py rename to google/ads/googleads/v23/services/services/smart_campaign_suggest_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/async_client.py b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/async_client.py new file mode 100644 index 000000000..8624821ca --- /dev/null +++ b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/async_client.py @@ -0,0 +1,632 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + smart_campaign_suggest_service, +) +from .transports.base import ( + SmartCampaignSuggestServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import SmartCampaignSuggestServiceClient + +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 SmartCampaignSuggestServiceAsyncClient: + """Service to get suggestions for Smart Campaigns.""" + + _client: SmartCampaignSuggestServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = SmartCampaignSuggestServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + SmartCampaignSuggestServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + SmartCampaignSuggestServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = SmartCampaignSuggestServiceClient._DEFAULT_UNIVERSE + + campaign_path = staticmethod( + SmartCampaignSuggestServiceClient.campaign_path + ) + parse_campaign_path = staticmethod( + SmartCampaignSuggestServiceClient.parse_campaign_path + ) + keyword_theme_constant_path = staticmethod( + SmartCampaignSuggestServiceClient.keyword_theme_constant_path + ) + parse_keyword_theme_constant_path = staticmethod( + SmartCampaignSuggestServiceClient.parse_keyword_theme_constant_path + ) + common_billing_account_path = staticmethod( + SmartCampaignSuggestServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + SmartCampaignSuggestServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + SmartCampaignSuggestServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + SmartCampaignSuggestServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + SmartCampaignSuggestServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + SmartCampaignSuggestServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + SmartCampaignSuggestServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + SmartCampaignSuggestServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + SmartCampaignSuggestServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + SmartCampaignSuggestServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSuggestServiceAsyncClient: The constructed client. + """ + return SmartCampaignSuggestServiceClient.from_service_account_info.__func__(SmartCampaignSuggestServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSuggestServiceAsyncClient: The constructed client. + """ + return SmartCampaignSuggestServiceClient.from_service_account_file.__func__(SmartCampaignSuggestServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return SmartCampaignSuggestServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> SmartCampaignSuggestServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SmartCampaignSuggestServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = SmartCampaignSuggestServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + SmartCampaignSuggestServiceTransport, + Callable[..., SmartCampaignSuggestServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the smart campaign suggest service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,SmartCampaignSuggestServiceTransport,Callable[..., SmartCampaignSuggestServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the SmartCampaignSuggestServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = SmartCampaignSuggestServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.SmartCampaignSuggestServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.SmartCampaignSuggestService", + "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.ads.googleads.v23.services.SmartCampaignSuggestService", + "credentialsType": None, + } + ), + ) + + async def suggest_smart_campaign_budget_options( + self, + request: Optional[ + Union[ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse + ): + r"""Returns BudgetOption suggestions. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.SuggestSmartCampaignBudgetOptionsRequest, dict]]): + The request object. Request message for + [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestSmartCampaignBudgetOptionsResponse: + Response message for + [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. + Depending on whether the system could suggest the + options, either all of the options or none of them + might be returned. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest, + ): + request = smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.suggest_smart_campaign_budget_options + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def suggest_smart_campaign_ad( + self, + request: Optional[ + Union[ + smart_campaign_suggest_service.SuggestSmartCampaignAdRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + suggestion_info: Optional[ + smart_campaign_suggest_service.SmartCampaignSuggestionInfo + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> smart_campaign_suggest_service.SuggestSmartCampaignAdResponse: + r"""Suggests a Smart campaign ad compatible with the Ad + family of resources, based on data points such as + targeting and the business to advertise. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.SuggestSmartCampaignAdRequest, dict]]): + The request object. Request message for + [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + suggestion_info (:class:`google.ads.googleads.v23.services.types.SmartCampaignSuggestionInfo`): + Required. Inputs used to suggest a Smart campaign ad. + Required fields: final_url, language_code, + keyword_themes. Optional but recommended fields to + improve the quality of the suggestion: business_setting + and geo_target. + + This corresponds to the ``suggestion_info`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestSmartCampaignAdResponse: + Response message for + [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, suggestion_info] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + smart_campaign_suggest_service.SuggestSmartCampaignAdRequest, + ): + request = ( + smart_campaign_suggest_service.SuggestSmartCampaignAdRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if suggestion_info is not None: + request.suggestion_info = suggestion_info + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.suggest_smart_campaign_ad + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def suggest_keyword_themes( + self, + request: Optional[ + Union[ + smart_campaign_suggest_service.SuggestKeywordThemesRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + suggestion_info: Optional[ + smart_campaign_suggest_service.SmartCampaignSuggestionInfo + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> smart_campaign_suggest_service.SuggestKeywordThemesResponse: + r"""Suggests keyword themes to advertise on. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.SuggestKeywordThemesRequest, dict]]): + The request object. Request message for + [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestKeywordThemes]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + suggestion_info (:class:`google.ads.googleads.v23.services.types.SmartCampaignSuggestionInfo`): + Required. Information to get keyword theme suggestions. + Required fields: + + - suggestion_info.final_url + - suggestion_info.language_code + - suggestion_info.geo_target + + Recommended fields: + + - suggestion_info.business_setting + + This corresponds to the ``suggestion_info`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestKeywordThemesResponse: + Response message for + [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestKeywordThemes]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, suggestion_info] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, smart_campaign_suggest_service.SuggestKeywordThemesRequest + ): + request = ( + smart_campaign_suggest_service.SuggestKeywordThemesRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if suggestion_info is not None: + request.suggestion_info = suggestion_info + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.suggest_keyword_themes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "SmartCampaignSuggestServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("SmartCampaignSuggestServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/client.py b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/client.py new file mode 100644 index 000000000..df1bd759e --- /dev/null +++ b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/client.py @@ -0,0 +1,1118 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + smart_campaign_suggest_service, +) +from .transports.base import ( + SmartCampaignSuggestServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import SmartCampaignSuggestServiceGrpcTransport +from .transports.grpc_asyncio import ( + SmartCampaignSuggestServiceGrpcAsyncIOTransport, +) + + +class SmartCampaignSuggestServiceClientMeta(type): + """Metaclass for the SmartCampaignSuggestService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[SmartCampaignSuggestServiceTransport]] + _transport_registry["grpc"] = SmartCampaignSuggestServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + SmartCampaignSuggestServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[SmartCampaignSuggestServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class SmartCampaignSuggestServiceClient( + metaclass=SmartCampaignSuggestServiceClientMeta +): + """Service to get suggestions for Smart Campaigns.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSuggestServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + SmartCampaignSuggestServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> SmartCampaignSuggestServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SmartCampaignSuggestServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def campaign_path( + customer_id: str, + campaign_id: str, + ) -> str: + """Returns a fully-qualified campaign string.""" + return "customers/{customer_id}/campaigns/{campaign_id}".format( + customer_id=customer_id, + campaign_id=campaign_id, + ) + + @staticmethod + def parse_campaign_path(path: str) -> Dict[str, str]: + """Parses a campaign path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/campaigns/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def keyword_theme_constant_path( + express_category_id: str, + express_sub_category_id: str, + ) -> str: + """Returns a fully-qualified keyword_theme_constant string.""" + return "keywordThemeConstants/{express_category_id}~{express_sub_category_id}".format( + express_category_id=express_category_id, + express_sub_category_id=express_sub_category_id, + ) + + @staticmethod + def parse_keyword_theme_constant_path(path: str) -> Dict[str, str]: + """Parses a keyword_theme_constant path into its component segments.""" + m = re.match( + r"^keywordThemeConstants/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + SmartCampaignSuggestServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + SmartCampaignSuggestServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + SmartCampaignSuggestServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + SmartCampaignSuggestServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = SmartCampaignSuggestServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = SmartCampaignSuggestServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + SmartCampaignSuggestServiceTransport, + Callable[..., SmartCampaignSuggestServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the smart campaign suggest service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,SmartCampaignSuggestServiceTransport,Callable[..., SmartCampaignSuggestServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the SmartCampaignSuggestServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = SmartCampaignSuggestServiceClient._read_environment_variables() + self._client_cert_source = ( + SmartCampaignSuggestServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + SmartCampaignSuggestServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, SmartCampaignSuggestServiceTransport + ) + if transport_provided: + # transport is a SmartCampaignSuggestServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + SmartCampaignSuggestServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or SmartCampaignSuggestServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[SmartCampaignSuggestServiceTransport], + Callable[..., SmartCampaignSuggestServiceTransport], + ] = ( + SmartCampaignSuggestServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., SmartCampaignSuggestServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.SmartCampaignSuggestServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.SmartCampaignSuggestService", + "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.ads.googleads.v23.services.SmartCampaignSuggestService", + "credentialsType": None, + } + ), + ) + + def suggest_smart_campaign_budget_options( + self, + request: Optional[ + Union[ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse + ): + r"""Returns BudgetOption suggestions. + + Args: + request (Union[google.ads.googleads.v23.services.types.SuggestSmartCampaignBudgetOptionsRequest, dict]): + The request object. Request message for + [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestSmartCampaignBudgetOptionsResponse: + Response message for + [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. + Depending on whether the system could suggest the + options, either all of the options or none of them + might be returned. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest, + ): + request = smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.suggest_smart_campaign_budget_options + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def suggest_smart_campaign_ad( + self, + request: Optional[ + Union[ + smart_campaign_suggest_service.SuggestSmartCampaignAdRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + suggestion_info: Optional[ + smart_campaign_suggest_service.SmartCampaignSuggestionInfo + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> smart_campaign_suggest_service.SuggestSmartCampaignAdResponse: + r"""Suggests a Smart campaign ad compatible with the Ad + family of resources, based on data points such as + targeting and the business to advertise. + + Args: + request (Union[google.ads.googleads.v23.services.types.SuggestSmartCampaignAdRequest, dict]): + The request object. Request message for + [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + suggestion_info (google.ads.googleads.v23.services.types.SmartCampaignSuggestionInfo): + Required. Inputs used to suggest a Smart campaign ad. + Required fields: final_url, language_code, + keyword_themes. Optional but recommended fields to + improve the quality of the suggestion: business_setting + and geo_target. + + This corresponds to the ``suggestion_info`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestSmartCampaignAdResponse: + Response message for + [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, suggestion_info] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + smart_campaign_suggest_service.SuggestSmartCampaignAdRequest, + ): + request = ( + smart_campaign_suggest_service.SuggestSmartCampaignAdRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if suggestion_info is not None: + request.suggestion_info = suggestion_info + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.suggest_smart_campaign_ad + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def suggest_keyword_themes( + self, + request: Optional[ + Union[ + smart_campaign_suggest_service.SuggestKeywordThemesRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + suggestion_info: Optional[ + smart_campaign_suggest_service.SmartCampaignSuggestionInfo + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> smart_campaign_suggest_service.SuggestKeywordThemesResponse: + r"""Suggests keyword themes to advertise on. + + Args: + request (Union[google.ads.googleads.v23.services.types.SuggestKeywordThemesRequest, dict]): + The request object. Request message for + [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestKeywordThemes]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + suggestion_info (google.ads.googleads.v23.services.types.SmartCampaignSuggestionInfo): + Required. Information to get keyword theme suggestions. + Required fields: + + - suggestion_info.final_url + - suggestion_info.language_code + - suggestion_info.geo_target + + Recommended fields: + + - suggestion_info.business_setting + + This corresponds to the ``suggestion_info`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestKeywordThemesResponse: + Response message for + [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestKeywordThemes]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, suggestion_info] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, smart_campaign_suggest_service.SuggestKeywordThemesRequest + ): + request = ( + smart_campaign_suggest_service.SuggestKeywordThemesRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if suggestion_info is not None: + request.suggestion_info = suggestion_info + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.suggest_keyword_themes + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "SmartCampaignSuggestServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("SmartCampaignSuggestServiceClient",) diff --git a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/README.rst b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/README.rst rename to google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/__init__.py b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/smart_campaign_suggest_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/base.py b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/base.py new file mode 100644 index 000000000..e08faa5e8 --- /dev/null +++ b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/base.py @@ -0,0 +1,217 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + smart_campaign_suggest_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class SmartCampaignSuggestServiceTransport(abc.ABC): + """Abstract transport class for SmartCampaignSuggestService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.suggest_smart_campaign_budget_options: gapic_v1.method.wrap_method( + self.suggest_smart_campaign_budget_options, + default_timeout=None, + client_info=client_info, + ), + self.suggest_smart_campaign_ad: gapic_v1.method.wrap_method( + self.suggest_smart_campaign_ad, + default_timeout=None, + client_info=client_info, + ), + self.suggest_keyword_themes: gapic_v1.method.wrap_method( + self.suggest_keyword_themes, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def suggest_smart_campaign_budget_options( + self, + ) -> Callable[ + [ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest + ], + Union[ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse, + Awaitable[ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def suggest_smart_campaign_ad( + self, + ) -> Callable[ + [smart_campaign_suggest_service.SuggestSmartCampaignAdRequest], + Union[ + smart_campaign_suggest_service.SuggestSmartCampaignAdResponse, + Awaitable[ + smart_campaign_suggest_service.SuggestSmartCampaignAdResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def suggest_keyword_themes( + self, + ) -> Callable[ + [smart_campaign_suggest_service.SuggestKeywordThemesRequest], + Union[ + smart_campaign_suggest_service.SuggestKeywordThemesResponse, + Awaitable[ + smart_campaign_suggest_service.SuggestKeywordThemesResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("SmartCampaignSuggestServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/grpc.py b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/grpc.py new file mode 100644 index 000000000..a3cf17c39 --- /dev/null +++ b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/grpc.py @@ -0,0 +1,454 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + smart_campaign_suggest_service, +) +from .base import SmartCampaignSuggestServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.SmartCampaignSuggestService", + "rpcName": str(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.ads.googleads.v23.services.SmartCampaignSuggestService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class SmartCampaignSuggestServiceGrpcTransport( + SmartCampaignSuggestServiceTransport +): + """gRPC backend transport for SmartCampaignSuggestService. + + Service to get suggestions for Smart Campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def suggest_smart_campaign_budget_options( + self, + ) -> Callable[ + [ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest + ], + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse, + ]: + r"""Return a callable for the suggest smart campaign budget + options method over gRPC. + + Returns BudgetOption suggestions. + + Returns: + Callable[[~.SuggestSmartCampaignBudgetOptionsRequest], + ~.SuggestSmartCampaignBudgetOptionsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_smart_campaign_budget_options" not in self._stubs: + self._stubs["suggest_smart_campaign_budget_options"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SmartCampaignSuggestService/SuggestSmartCampaignBudgetOptions", + request_serializer=smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest.serialize, + response_deserializer=smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse.deserialize, + ) + ) + return self._stubs["suggest_smart_campaign_budget_options"] + + @property + def suggest_smart_campaign_ad( + self, + ) -> Callable[ + [smart_campaign_suggest_service.SuggestSmartCampaignAdRequest], + smart_campaign_suggest_service.SuggestSmartCampaignAdResponse, + ]: + r"""Return a callable for the suggest smart campaign ad method over gRPC. + + Suggests a Smart campaign ad compatible with the Ad + family of resources, based on data points such as + targeting and the business to advertise. + + Returns: + Callable[[~.SuggestSmartCampaignAdRequest], + ~.SuggestSmartCampaignAdResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_smart_campaign_ad" not in self._stubs: + self._stubs["suggest_smart_campaign_ad"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SmartCampaignSuggestService/SuggestSmartCampaignAd", + request_serializer=smart_campaign_suggest_service.SuggestSmartCampaignAdRequest.serialize, + response_deserializer=smart_campaign_suggest_service.SuggestSmartCampaignAdResponse.deserialize, + ) + ) + return self._stubs["suggest_smart_campaign_ad"] + + @property + def suggest_keyword_themes( + self, + ) -> Callable[ + [smart_campaign_suggest_service.SuggestKeywordThemesRequest], + smart_campaign_suggest_service.SuggestKeywordThemesResponse, + ]: + r"""Return a callable for the suggest keyword themes method over gRPC. + + Suggests keyword themes to advertise on. + + Returns: + Callable[[~.SuggestKeywordThemesRequest], + ~.SuggestKeywordThemesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_keyword_themes" not in self._stubs: + self._stubs["suggest_keyword_themes"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SmartCampaignSuggestService/SuggestKeywordThemes", + request_serializer=smart_campaign_suggest_service.SuggestKeywordThemesRequest.serialize, + response_deserializer=smart_campaign_suggest_service.SuggestKeywordThemesResponse.deserialize, + ) + ) + return self._stubs["suggest_keyword_themes"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("SmartCampaignSuggestServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..ea47a10d0 --- /dev/null +++ b/google/ads/googleads/v23/services/services/smart_campaign_suggest_service/transports/grpc_asyncio.py @@ -0,0 +1,489 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + smart_campaign_suggest_service, +) +from .base import SmartCampaignSuggestServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.SmartCampaignSuggestService", + "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.ads.googleads.v23.services.SmartCampaignSuggestService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class SmartCampaignSuggestServiceGrpcAsyncIOTransport( + SmartCampaignSuggestServiceTransport +): + """gRPC AsyncIO backend transport for SmartCampaignSuggestService. + + Service to get suggestions for Smart Campaigns. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def suggest_smart_campaign_budget_options( + self, + ) -> Callable[ + [ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest + ], + Awaitable[ + smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse + ], + ]: + r"""Return a callable for the suggest smart campaign budget + options method over gRPC. + + Returns BudgetOption suggestions. + + Returns: + Callable[[~.SuggestSmartCampaignBudgetOptionsRequest], + Awaitable[~.SuggestSmartCampaignBudgetOptionsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_smart_campaign_budget_options" not in self._stubs: + self._stubs["suggest_smart_campaign_budget_options"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SmartCampaignSuggestService/SuggestSmartCampaignBudgetOptions", + request_serializer=smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsRequest.serialize, + response_deserializer=smart_campaign_suggest_service.SuggestSmartCampaignBudgetOptionsResponse.deserialize, + ) + ) + return self._stubs["suggest_smart_campaign_budget_options"] + + @property + def suggest_smart_campaign_ad( + self, + ) -> Callable[ + [smart_campaign_suggest_service.SuggestSmartCampaignAdRequest], + Awaitable[ + smart_campaign_suggest_service.SuggestSmartCampaignAdResponse + ], + ]: + r"""Return a callable for the suggest smart campaign ad method over gRPC. + + Suggests a Smart campaign ad compatible with the Ad + family of resources, based on data points such as + targeting and the business to advertise. + + Returns: + Callable[[~.SuggestSmartCampaignAdRequest], + Awaitable[~.SuggestSmartCampaignAdResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_smart_campaign_ad" not in self._stubs: + self._stubs["suggest_smart_campaign_ad"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SmartCampaignSuggestService/SuggestSmartCampaignAd", + request_serializer=smart_campaign_suggest_service.SuggestSmartCampaignAdRequest.serialize, + response_deserializer=smart_campaign_suggest_service.SuggestSmartCampaignAdResponse.deserialize, + ) + ) + return self._stubs["suggest_smart_campaign_ad"] + + @property + def suggest_keyword_themes( + self, + ) -> Callable[ + [smart_campaign_suggest_service.SuggestKeywordThemesRequest], + Awaitable[smart_campaign_suggest_service.SuggestKeywordThemesResponse], + ]: + r"""Return a callable for the suggest keyword themes method over gRPC. + + Suggests keyword themes to advertise on. + + Returns: + Callable[[~.SuggestKeywordThemesRequest], + Awaitable[~.SuggestKeywordThemesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_keyword_themes" not in self._stubs: + self._stubs["suggest_keyword_themes"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.SmartCampaignSuggestService/SuggestKeywordThemes", + request_serializer=smart_campaign_suggest_service.SuggestKeywordThemesRequest.serialize, + response_deserializer=smart_campaign_suggest_service.SuggestKeywordThemesResponse.deserialize, + ) + ) + return self._stubs["suggest_keyword_themes"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.suggest_smart_campaign_budget_options: self._wrap_method( + self.suggest_smart_campaign_budget_options, + default_timeout=None, + client_info=client_info, + ), + self.suggest_smart_campaign_ad: self._wrap_method( + self.suggest_smart_campaign_ad, + default_timeout=None, + client_info=client_info, + ), + self.suggest_keyword_themes: self._wrap_method( + self.suggest_keyword_themes, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("SmartCampaignSuggestServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/__init__.py b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/__init__.py rename to google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/async_client.py b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/async_client.py new file mode 100644 index 000000000..5b9c67c03 --- /dev/null +++ b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/async_client.py @@ -0,0 +1,408 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + third_party_app_analytics_link_service, +) +from .transports.base import ( + ThirdPartyAppAnalyticsLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import ThirdPartyAppAnalyticsLinkServiceClient + +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 ThirdPartyAppAnalyticsLinkServiceAsyncClient: + """This service allows management of links between Google Ads + and third party app analytics. + """ + + _client: ThirdPartyAppAnalyticsLinkServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = ThirdPartyAppAnalyticsLinkServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + ThirdPartyAppAnalyticsLinkServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + ThirdPartyAppAnalyticsLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = ( + ThirdPartyAppAnalyticsLinkServiceClient._DEFAULT_UNIVERSE + ) + + third_party_app_analytics_link_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.third_party_app_analytics_link_path + ) + parse_third_party_app_analytics_link_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.parse_third_party_app_analytics_link_path + ) + common_billing_account_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + ThirdPartyAppAnalyticsLinkServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ThirdPartyAppAnalyticsLinkServiceAsyncClient: The constructed client. + """ + return ThirdPartyAppAnalyticsLinkServiceClient.from_service_account_info.__func__(ThirdPartyAppAnalyticsLinkServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ThirdPartyAppAnalyticsLinkServiceAsyncClient: The constructed client. + """ + return ThirdPartyAppAnalyticsLinkServiceClient.from_service_account_file.__func__(ThirdPartyAppAnalyticsLinkServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return ThirdPartyAppAnalyticsLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ThirdPartyAppAnalyticsLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ThirdPartyAppAnalyticsLinkServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = ( + ThirdPartyAppAnalyticsLinkServiceClient.get_transport_class + ) + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ThirdPartyAppAnalyticsLinkServiceTransport, + Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the third party app analytics link service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ThirdPartyAppAnalyticsLinkServiceTransport,Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ThirdPartyAppAnalyticsLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = ThirdPartyAppAnalyticsLinkServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService", + "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.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService", + "credentialsType": None, + } + ), + ) + + async def regenerate_shareable_link_id( + self, + request: Optional[ + Union[ + third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse + ): + r"""Regenerate ThirdPartyAppAnalyticsLink.shareable_link_id that + should be provided to the third party when setting up app + analytics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.RegenerateShareableLinkIdRequest, dict]]): + The request object. Request message for + [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.RegenerateShareableLinkIdResponse: + Response message for + [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest, + ): + request = third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.regenerate_shareable_link_id + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__( + self, + ) -> "ThirdPartyAppAnalyticsLinkServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("ThirdPartyAppAnalyticsLinkServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/client.py b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/client.py new file mode 100644 index 000000000..c39b014f1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/client.py @@ -0,0 +1,882 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + third_party_app_analytics_link_service, +) +from .transports.base import ( + ThirdPartyAppAnalyticsLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import ThirdPartyAppAnalyticsLinkServiceGrpcTransport +from .transports.grpc_asyncio import ( + ThirdPartyAppAnalyticsLinkServiceGrpcAsyncIOTransport, +) + + +class ThirdPartyAppAnalyticsLinkServiceClientMeta(type): + """Metaclass for the ThirdPartyAppAnalyticsLinkService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[ThirdPartyAppAnalyticsLinkServiceTransport]] + _transport_registry["grpc"] = ThirdPartyAppAnalyticsLinkServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + ThirdPartyAppAnalyticsLinkServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[ThirdPartyAppAnalyticsLinkServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class ThirdPartyAppAnalyticsLinkServiceClient( + metaclass=ThirdPartyAppAnalyticsLinkServiceClientMeta +): + """This service allows management of links between Google Ads + and third party app analytics. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ThirdPartyAppAnalyticsLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + ThirdPartyAppAnalyticsLinkServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> ThirdPartyAppAnalyticsLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ThirdPartyAppAnalyticsLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def third_party_app_analytics_link_path( + customer_id: str, + customer_link_id: str, + ) -> str: + """Returns a fully-qualified third_party_app_analytics_link string.""" + return "customers/{customer_id}/thirdPartyAppAnalyticsLinks/{customer_link_id}".format( + customer_id=customer_id, + customer_link_id=customer_link_id, + ) + + @staticmethod + def parse_third_party_app_analytics_link_path(path: str) -> Dict[str, str]: + """Parses a third_party_app_analytics_link path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/thirdPartyAppAnalyticsLinks/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + ThirdPartyAppAnalyticsLinkServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + ThirdPartyAppAnalyticsLinkServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + ThirdPartyAppAnalyticsLinkServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + ThirdPartyAppAnalyticsLinkServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = ThirdPartyAppAnalyticsLinkServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = ( + ThirdPartyAppAnalyticsLinkServiceClient._DEFAULT_UNIVERSE + ) + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + ThirdPartyAppAnalyticsLinkServiceTransport, + Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the third party app analytics link service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,ThirdPartyAppAnalyticsLinkServiceTransport,Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the ThirdPartyAppAnalyticsLinkServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = ( + ThirdPartyAppAnalyticsLinkServiceClient._read_environment_variables() + ) + self._client_cert_source = ( + ThirdPartyAppAnalyticsLinkServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + ThirdPartyAppAnalyticsLinkServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, ThirdPartyAppAnalyticsLinkServiceTransport + ) + if transport_provided: + # transport is a ThirdPartyAppAnalyticsLinkServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + ThirdPartyAppAnalyticsLinkServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or ThirdPartyAppAnalyticsLinkServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[ThirdPartyAppAnalyticsLinkServiceTransport], + Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport], + ] = ( + ThirdPartyAppAnalyticsLinkServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., ThirdPartyAppAnalyticsLinkServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService", + "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.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService", + "credentialsType": None, + } + ), + ) + + def regenerate_shareable_link_id( + self, + request: Optional[ + Union[ + third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest, + dict, + ] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> ( + third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse + ): + r"""Regenerate ThirdPartyAppAnalyticsLink.shareable_link_id that + should be provided to the third party when setting up app + analytics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.RegenerateShareableLinkIdRequest, dict]): + The request object. Request message for + [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.RegenerateShareableLinkIdResponse: + Response message for + [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest, + ): + request = third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest( + request + ) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.regenerate_shareable_link_id + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("resource_name", request.resource_name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ThirdPartyAppAnalyticsLinkServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("ThirdPartyAppAnalyticsLinkServiceClient",) diff --git a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/README.rst b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/README.rst rename to google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/__init__.py b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/third_party_app_analytics_link_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/base.py b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/base.py new file mode 100644 index 000000000..bc7c9766d --- /dev/null +++ b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/base.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + third_party_app_analytics_link_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class ThirdPartyAppAnalyticsLinkServiceTransport(abc.ABC): + """Abstract transport class for ThirdPartyAppAnalyticsLinkService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.regenerate_shareable_link_id: gapic_v1.method.wrap_method( + self.regenerate_shareable_link_id, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def regenerate_shareable_link_id( + self, + ) -> Callable[ + [ + third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest + ], + Union[ + third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse, + Awaitable[ + third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("ThirdPartyAppAnalyticsLinkServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/grpc.py b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/grpc.py new file mode 100644 index 000000000..6c3e6bda5 --- /dev/null +++ b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/grpc.py @@ -0,0 +1,399 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + third_party_app_analytics_link_service, +) +from .base import ( + ThirdPartyAppAnalyticsLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService", + "rpcName": str(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.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ThirdPartyAppAnalyticsLinkServiceGrpcTransport( + ThirdPartyAppAnalyticsLinkServiceTransport +): + """gRPC backend transport for ThirdPartyAppAnalyticsLinkService. + + This service allows management of links between Google Ads + and third party app analytics. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def regenerate_shareable_link_id( + self, + ) -> Callable[ + [ + third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest + ], + third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse, + ]: + r"""Return a callable for the regenerate shareable link id method over gRPC. + + Regenerate ThirdPartyAppAnalyticsLink.shareable_link_id that + should be provided to the third party when setting up app + analytics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.RegenerateShareableLinkIdRequest], + ~.RegenerateShareableLinkIdResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "regenerate_shareable_link_id" not in self._stubs: + self._stubs["regenerate_shareable_link_id"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService/RegenerateShareableLinkId", + request_serializer=third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest.serialize, + response_deserializer=third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse.deserialize, + ) + ) + return self._stubs["regenerate_shareable_link_id"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("ThirdPartyAppAnalyticsLinkServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..8f83c298f --- /dev/null +++ b/google/ads/googleads/v23/services/services/third_party_app_analytics_link_service/transports/grpc_asyncio.py @@ -0,0 +1,422 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + third_party_app_analytics_link_service, +) +from .base import ( + ThirdPartyAppAnalyticsLinkServiceTransport, + DEFAULT_CLIENT_INFO, +) + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService", + "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.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class ThirdPartyAppAnalyticsLinkServiceGrpcAsyncIOTransport( + ThirdPartyAppAnalyticsLinkServiceTransport +): + """gRPC AsyncIO backend transport for ThirdPartyAppAnalyticsLinkService. + + This service allows management of links between Google Ads + and third party app analytics. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def regenerate_shareable_link_id( + self, + ) -> Callable[ + [ + third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest + ], + Awaitable[ + third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse + ], + ]: + r"""Return a callable for the regenerate shareable link id method over gRPC. + + Regenerate ThirdPartyAppAnalyticsLink.shareable_link_id that + should be provided to the third party when setting up app + analytics. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `HeaderError <>`__ + `InternalError <>`__ `QuotaError <>`__ `RequestError <>`__ + + Returns: + Callable[[~.RegenerateShareableLinkIdRequest], + Awaitable[~.RegenerateShareableLinkIdResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "regenerate_shareable_link_id" not in self._stubs: + self._stubs["regenerate_shareable_link_id"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService/RegenerateShareableLinkId", + request_serializer=third_party_app_analytics_link_service.RegenerateShareableLinkIdRequest.serialize, + response_deserializer=third_party_app_analytics_link_service.RegenerateShareableLinkIdResponse.deserialize, + ) + ) + return self._stubs["regenerate_shareable_link_id"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.regenerate_shareable_link_id: self._wrap_method( + self.regenerate_shareable_link_id, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("ThirdPartyAppAnalyticsLinkServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/__init__.py b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/travel_asset_suggestion_service/__init__.py rename to google/ads/googleads/v23/services/services/travel_asset_suggestion_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/async_client.py b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/async_client.py new file mode 100644 index 000000000..a69faae55 --- /dev/null +++ b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/async_client.py @@ -0,0 +1,426 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + travel_asset_suggestion_service, +) +from .transports.base import ( + TravelAssetSuggestionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import TravelAssetSuggestionServiceClient + +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 TravelAssetSuggestionServiceAsyncClient: + """Service to retrieve Travel asset suggestions.""" + + _client: TravelAssetSuggestionServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = TravelAssetSuggestionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + TravelAssetSuggestionServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + TravelAssetSuggestionServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = TravelAssetSuggestionServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod( + TravelAssetSuggestionServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + TravelAssetSuggestionServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + TravelAssetSuggestionServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + TravelAssetSuggestionServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + TravelAssetSuggestionServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + TravelAssetSuggestionServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + TravelAssetSuggestionServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + TravelAssetSuggestionServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + TravelAssetSuggestionServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + TravelAssetSuggestionServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + TravelAssetSuggestionServiceAsyncClient: The constructed client. + """ + return TravelAssetSuggestionServiceClient.from_service_account_info.__func__(TravelAssetSuggestionServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + TravelAssetSuggestionServiceAsyncClient: The constructed client. + """ + return TravelAssetSuggestionServiceClient.from_service_account_file.__func__(TravelAssetSuggestionServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return TravelAssetSuggestionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> TravelAssetSuggestionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + TravelAssetSuggestionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = TravelAssetSuggestionServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + TravelAssetSuggestionServiceTransport, + Callable[..., TravelAssetSuggestionServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the travel asset suggestion service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,TravelAssetSuggestionServiceTransport,Callable[..., TravelAssetSuggestionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the TravelAssetSuggestionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = TravelAssetSuggestionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.TravelAssetSuggestionServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.TravelAssetSuggestionService", + "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.ads.googleads.v23.services.TravelAssetSuggestionService", + "credentialsType": None, + } + ), + ) + + async def suggest_travel_assets( + self, + request: Optional[ + Union[ + travel_asset_suggestion_service.SuggestTravelAssetsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + language_option: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> travel_asset_suggestion_service.SuggestTravelAssetsResponse: + r"""Returns Travel Asset suggestions. Asset + suggestions are returned on a best-effort basis. There + are no guarantees that all possible asset types will be + returned for any given hotel property. + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.SuggestTravelAssetsRequest, dict]]): + The request object. Request message for + [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v23.services.TravelAssetSuggestionService.SuggestTravelAssets]. + customer_id (:class:`str`): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + language_option (:class:`str`): + Required. The language specifications + in BCP 47 format (for example, en-US, + zh-CN, etc.) for the asset suggestions. + Text will be in this language. Usually + matches one of the campaign target + languages. + + This corresponds to the ``language_option`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestTravelAssetsResponse: + Response message for + [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v23.services.TravelAssetSuggestionService.SuggestTravelAssets]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, language_option] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, travel_asset_suggestion_service.SuggestTravelAssetsRequest + ): + request = ( + travel_asset_suggestion_service.SuggestTravelAssetsRequest( + request + ) + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if language_option is not None: + request.language_option = language_option + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.suggest_travel_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "TravelAssetSuggestionServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("TravelAssetSuggestionServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/client.py b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/client.py new file mode 100644 index 000000000..2b85fe5d2 --- /dev/null +++ b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/client.py @@ -0,0 +1,887 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + travel_asset_suggestion_service, +) +from .transports.base import ( + TravelAssetSuggestionServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import TravelAssetSuggestionServiceGrpcTransport +from .transports.grpc_asyncio import ( + TravelAssetSuggestionServiceGrpcAsyncIOTransport, +) + + +class TravelAssetSuggestionServiceClientMeta(type): + """Metaclass for the TravelAssetSuggestionService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[TravelAssetSuggestionServiceTransport]] + _transport_registry["grpc"] = TravelAssetSuggestionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + TravelAssetSuggestionServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[TravelAssetSuggestionServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class TravelAssetSuggestionServiceClient( + metaclass=TravelAssetSuggestionServiceClientMeta +): + """Service to retrieve Travel asset suggestions.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + TravelAssetSuggestionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + TravelAssetSuggestionServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> TravelAssetSuggestionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + TravelAssetSuggestionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + TravelAssetSuggestionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + TravelAssetSuggestionServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + TravelAssetSuggestionServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + TravelAssetSuggestionServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = TravelAssetSuggestionServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = TravelAssetSuggestionServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + TravelAssetSuggestionServiceTransport, + Callable[..., TravelAssetSuggestionServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the travel asset suggestion service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,TravelAssetSuggestionServiceTransport,Callable[..., TravelAssetSuggestionServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the TravelAssetSuggestionServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = TravelAssetSuggestionServiceClient._read_environment_variables() + self._client_cert_source = ( + TravelAssetSuggestionServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + TravelAssetSuggestionServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, TravelAssetSuggestionServiceTransport + ) + if transport_provided: + # transport is a TravelAssetSuggestionServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + TravelAssetSuggestionServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or TravelAssetSuggestionServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[TravelAssetSuggestionServiceTransport], + Callable[..., TravelAssetSuggestionServiceTransport], + ] = ( + TravelAssetSuggestionServiceClient.get_transport_class( + transport + ) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., TravelAssetSuggestionServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.TravelAssetSuggestionServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.TravelAssetSuggestionService", + "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.ads.googleads.v23.services.TravelAssetSuggestionService", + "credentialsType": None, + } + ), + ) + + def suggest_travel_assets( + self, + request: Optional[ + Union[ + travel_asset_suggestion_service.SuggestTravelAssetsRequest, dict + ] + ] = None, + *, + customer_id: Optional[str] = None, + language_option: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> travel_asset_suggestion_service.SuggestTravelAssetsResponse: + r"""Returns Travel Asset suggestions. Asset + suggestions are returned on a best-effort basis. There + are no guarantees that all possible asset types will be + returned for any given hotel property. + + Args: + request (Union[google.ads.googleads.v23.services.types.SuggestTravelAssetsRequest, dict]): + The request object. Request message for + [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v23.services.TravelAssetSuggestionService.SuggestTravelAssets]. + customer_id (str): + Required. The ID of the customer. + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + language_option (str): + Required. The language specifications + in BCP 47 format (for example, en-US, + zh-CN, etc.) for the asset suggestions. + Text will be in this language. Usually + matches one of the campaign target + languages. + + This corresponds to the ``language_option`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.SuggestTravelAssetsResponse: + Response message for + [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v23.services.TravelAssetSuggestionService.SuggestTravelAssets]. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, language_option] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, travel_asset_suggestion_service.SuggestTravelAssetsRequest + ): + request = ( + travel_asset_suggestion_service.SuggestTravelAssetsRequest( + request + ) + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if language_option is not None: + request.language_option = language_option + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.suggest_travel_assets + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "TravelAssetSuggestionServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("TravelAssetSuggestionServiceClient",) diff --git a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/README.rst b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/README.rst rename to google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/__init__.py b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/travel_asset_suggestion_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/base.py b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/base.py new file mode 100644 index 000000000..90a36b83e --- /dev/null +++ b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + travel_asset_suggestion_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class TravelAssetSuggestionServiceTransport(abc.ABC): + """Abstract transport class for TravelAssetSuggestionService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.suggest_travel_assets: gapic_v1.method.wrap_method( + self.suggest_travel_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def suggest_travel_assets( + self, + ) -> Callable[ + [travel_asset_suggestion_service.SuggestTravelAssetsRequest], + Union[ + travel_asset_suggestion_service.SuggestTravelAssetsResponse, + Awaitable[ + travel_asset_suggestion_service.SuggestTravelAssetsResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("TravelAssetSuggestionServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/grpc.py b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/grpc.py new file mode 100644 index 000000000..fb6afddb9 --- /dev/null +++ b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/grpc.py @@ -0,0 +1,390 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + travel_asset_suggestion_service, +) +from .base import TravelAssetSuggestionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.TravelAssetSuggestionService", + "rpcName": str(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.ads.googleads.v23.services.TravelAssetSuggestionService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class TravelAssetSuggestionServiceGrpcTransport( + TravelAssetSuggestionServiceTransport +): + """gRPC backend transport for TravelAssetSuggestionService. + + Service to retrieve Travel asset suggestions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def suggest_travel_assets( + self, + ) -> Callable[ + [travel_asset_suggestion_service.SuggestTravelAssetsRequest], + travel_asset_suggestion_service.SuggestTravelAssetsResponse, + ]: + r"""Return a callable for the suggest travel assets method over gRPC. + + Returns Travel Asset suggestions. Asset + suggestions are returned on a best-effort basis. There + are no guarantees that all possible asset types will be + returned for any given hotel property. + + Returns: + Callable[[~.SuggestTravelAssetsRequest], + ~.SuggestTravelAssetsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_travel_assets" not in self._stubs: + self._stubs["suggest_travel_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.TravelAssetSuggestionService/SuggestTravelAssets", + request_serializer=travel_asset_suggestion_service.SuggestTravelAssetsRequest.serialize, + response_deserializer=travel_asset_suggestion_service.SuggestTravelAssetsResponse.deserialize, + ) + ) + return self._stubs["suggest_travel_assets"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("TravelAssetSuggestionServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..749b9c75f --- /dev/null +++ b/google/ads/googleads/v23/services/services/travel_asset_suggestion_service/transports/grpc_asyncio.py @@ -0,0 +1,411 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + travel_asset_suggestion_service, +) +from .base import TravelAssetSuggestionServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.TravelAssetSuggestionService", + "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.ads.googleads.v23.services.TravelAssetSuggestionService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class TravelAssetSuggestionServiceGrpcAsyncIOTransport( + TravelAssetSuggestionServiceTransport +): + """gRPC AsyncIO backend transport for TravelAssetSuggestionService. + + Service to retrieve Travel asset suggestions. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def suggest_travel_assets( + self, + ) -> Callable[ + [travel_asset_suggestion_service.SuggestTravelAssetsRequest], + Awaitable[travel_asset_suggestion_service.SuggestTravelAssetsResponse], + ]: + r"""Return a callable for the suggest travel assets method over gRPC. + + Returns Travel Asset suggestions. Asset + suggestions are returned on a best-effort basis. There + are no guarantees that all possible asset types will be + returned for any given hotel property. + + Returns: + Callable[[~.SuggestTravelAssetsRequest], + Awaitable[~.SuggestTravelAssetsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "suggest_travel_assets" not in self._stubs: + self._stubs["suggest_travel_assets"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.TravelAssetSuggestionService/SuggestTravelAssets", + request_serializer=travel_asset_suggestion_service.SuggestTravelAssetsRequest.serialize, + response_deserializer=travel_asset_suggestion_service.SuggestTravelAssetsResponse.deserialize, + ) + ) + return self._stubs["suggest_travel_assets"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.suggest_travel_assets: self._wrap_method( + self.suggest_travel_assets, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("TravelAssetSuggestionServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/user_data_service/__init__.py b/google/ads/googleads/v23/services/services/user_data_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/user_data_service/__init__.py rename to google/ads/googleads/v23/services/services/user_data_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/user_data_service/async_client.py b/google/ads/googleads/v23/services/services/user_data_service/async_client.py new file mode 100644 index 000000000..9483324e6 --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_data_service/async_client.py @@ -0,0 +1,386 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import user_data_service +from .transports.base import UserDataServiceTransport, DEFAULT_CLIENT_INFO +from .client import UserDataServiceClient + +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 UserDataServiceAsyncClient: + """Service to manage user data uploads. + Any uploads made to a Customer Match list through this service + will be eligible for matching as per the customer matching + process. See + https://support.google.com/google-ads/answer/7474263. However, + the uploads made through this service will not be visible under + the 'Segment members' section for the Customer Match List in the + Google Ads UI. + """ + + _client: UserDataServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = UserDataServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = UserDataServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + UserDataServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = UserDataServiceClient._DEFAULT_UNIVERSE + + common_billing_account_path = staticmethod( + UserDataServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + UserDataServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(UserDataServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + UserDataServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + UserDataServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + UserDataServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + UserDataServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + UserDataServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + UserDataServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + UserDataServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserDataServiceAsyncClient: The constructed client. + """ + return UserDataServiceClient.from_service_account_info.__func__(UserDataServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserDataServiceAsyncClient: The constructed client. + """ + return UserDataServiceClient.from_service_account_file.__func__(UserDataServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return UserDataServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> UserDataServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserDataServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = UserDataServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + UserDataServiceTransport, + Callable[..., UserDataServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user data service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,UserDataServiceTransport,Callable[..., UserDataServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the UserDataServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = UserDataServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.UserDataServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.UserDataService", + "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.ads.googleads.v23.services.UserDataService", + "credentialsType": None, + } + ), + ) + + async def upload_user_data( + self, + request: Optional[ + Union[user_data_service.UploadUserDataRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> user_data_service.UploadUserDataResponse: + r"""Uploads the given user data. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UserDataError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.UploadUserDataRequest, dict]]): + The request object. Request message for + [UserDataService.UploadUserData][google.ads.googleads.v23.services.UserDataService.UploadUserData] + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UploadUserDataResponse: + Response message for + [UserDataService.UploadUserData][google.ads.googleads.v23.services.UserDataService.UploadUserData] + Uploads made through this service will not be visible + under the 'Segment members' section for the Customer + Match List in the Google Ads UI. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, user_data_service.UploadUserDataRequest): + request = user_data_service.UploadUserDataRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.upload_user_data + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "UserDataServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("UserDataServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/user_data_service/client.py b/google/ads/googleads/v23/services/services/user_data_service/client.py new file mode 100644 index 000000000..daa6dbb8a --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_data_service/client.py @@ -0,0 +1,827 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import Dict, Callable, Optional, Sequence, Tuple, Type, Union, cast +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import user_data_service +from .transports.base import UserDataServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import UserDataServiceGrpcTransport +from .transports.grpc_asyncio import UserDataServiceGrpcAsyncIOTransport + + +class UserDataServiceClientMeta(type): + """Metaclass for the UserDataService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[UserDataServiceTransport]] + _transport_registry["grpc"] = UserDataServiceGrpcTransport + _transport_registry["grpc_asyncio"] = UserDataServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[UserDataServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class UserDataServiceClient(metaclass=UserDataServiceClientMeta): + """Service to manage user data uploads. + Any uploads made to a Customer Match list through this service + will be eligible for matching as per the customer matching + process. See + https://support.google.com/google-ads/answer/7474263. However, + the uploads made through this service will not be visible under + the 'Segment members' section for the Customer Match List in the + Google Ads UI. + """ + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserDataServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserDataServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> UserDataServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserDataServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = UserDataServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = UserDataServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = UserDataServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = UserDataServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + UserDataServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = UserDataServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + UserDataServiceTransport, + Callable[..., UserDataServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user data service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,UserDataServiceTransport,Callable[..., UserDataServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the UserDataServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = UserDataServiceClient._read_environment_variables() + self._client_cert_source = ( + UserDataServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = UserDataServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, UserDataServiceTransport) + if transport_provided: + # transport is a UserDataServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(UserDataServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or UserDataServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[UserDataServiceTransport], + Callable[..., UserDataServiceTransport], + ] = ( + UserDataServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., UserDataServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.UserDataServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.UserDataService", + "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.ads.googleads.v23.services.UserDataService", + "credentialsType": None, + } + ), + ) + + def upload_user_data( + self, + request: Optional[ + Union[user_data_service.UploadUserDataRequest, dict] + ] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> user_data_service.UploadUserDataResponse: + r"""Uploads the given user data. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UserDataError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.UploadUserDataRequest, dict]): + The request object. Request message for + [UserDataService.UploadUserData][google.ads.googleads.v23.services.UserDataService.UploadUserData] + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.UploadUserDataResponse: + Response message for + [UserDataService.UploadUserData][google.ads.googleads.v23.services.UserDataService.UploadUserData] + Uploads made through this service will not be visible + under the 'Segment members' section for the Customer + Match List in the Google Ads UI. + + """ + # Create or coerce a protobuf request object. + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, user_data_service.UploadUserDataRequest): + request = user_data_service.UploadUserDataRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.upload_user_data] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "UserDataServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("UserDataServiceClient",) diff --git a/google/ads/googleads/v19/services/services/user_data_service/transports/README.rst b/google/ads/googleads/v23/services/services/user_data_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/user_data_service/transports/README.rst rename to google/ads/googleads/v23/services/services/user_data_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/user_data_service/transports/__init__.py b/google/ads/googleads/v23/services/services/user_data_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/user_data_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/user_data_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/user_data_service/transports/base.py b/google/ads/googleads/v23/services/services/user_data_service/transports/base.py new file mode 100644 index 000000000..0abb91d6f --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_data_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import user_data_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class UserDataServiceTransport(abc.ABC): + """Abstract transport class for UserDataService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.upload_user_data: gapic_v1.method.wrap_method( + self.upload_user_data, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def upload_user_data( + self, + ) -> Callable[ + [user_data_service.UploadUserDataRequest], + Union[ + user_data_service.UploadUserDataResponse, + Awaitable[user_data_service.UploadUserDataResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("UserDataServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/user_data_service/transports/grpc.py b/google/ads/googleads/v23/services/services/user_data_service/transports/grpc.py new file mode 100644 index 000000000..622de22d7 --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_data_service/transports/grpc.py @@ -0,0 +1,394 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import user_data_service +from .base import UserDataServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.UserDataService", + "rpcName": str(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.ads.googleads.v23.services.UserDataService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class UserDataServiceGrpcTransport(UserDataServiceTransport): + """gRPC backend transport for UserDataService. + + Service to manage user data uploads. + Any uploads made to a Customer Match list through this service + will be eligible for matching as per the customer matching + process. See + https://support.google.com/google-ads/answer/7474263. However, + the uploads made through this service will not be visible under + the 'Segment members' section for the Customer Match List in the + Google Ads UI. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def upload_user_data( + self, + ) -> Callable[ + [user_data_service.UploadUserDataRequest], + user_data_service.UploadUserDataResponse, + ]: + r"""Return a callable for the upload user data method over gRPC. + + Uploads the given user data. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UserDataError <>`__ + + Returns: + Callable[[~.UploadUserDataRequest], + ~.UploadUserDataResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_user_data" not in self._stubs: + self._stubs["upload_user_data"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.UserDataService/UploadUserData", + request_serializer=user_data_service.UploadUserDataRequest.serialize, + response_deserializer=user_data_service.UploadUserDataResponse.deserialize, + ) + return self._stubs["upload_user_data"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("UserDataServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/user_data_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/user_data_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..a4dee2fed --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_data_service/transports/grpc_asyncio.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import user_data_service +from .base import UserDataServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.UserDataService", + "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.ads.googleads.v23.services.UserDataService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class UserDataServiceGrpcAsyncIOTransport(UserDataServiceTransport): + """gRPC AsyncIO backend transport for UserDataService. + + Service to manage user data uploads. + Any uploads made to a Customer Match list through this service + will be eligible for matching as per the customer matching + process. See + https://support.google.com/google-ads/answer/7474263. However, + the uploads made through this service will not be visible under + the 'Segment members' section for the Customer Match List in the + Google Ads UI. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def upload_user_data( + self, + ) -> Callable[ + [user_data_service.UploadUserDataRequest], + Awaitable[user_data_service.UploadUserDataResponse], + ]: + r"""Return a callable for the upload user data method over gRPC. + + Uploads the given user data. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `FieldError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `OfflineUserDataJobError <>`__ + `QuotaError <>`__ `RequestError <>`__ `UserDataError <>`__ + + Returns: + Callable[[~.UploadUserDataRequest], + Awaitable[~.UploadUserDataResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "upload_user_data" not in self._stubs: + self._stubs["upload_user_data"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.UserDataService/UploadUserData", + request_serializer=user_data_service.UploadUserDataRequest.serialize, + response_deserializer=user_data_service.UploadUserDataResponse.deserialize, + ) + return self._stubs["upload_user_data"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.upload_user_data: self._wrap_method( + self.upload_user_data, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("UserDataServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/user_list_customer_type_service/__init__.py b/google/ads/googleads/v23/services/services/user_list_customer_type_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/user_list_customer_type_service/__init__.py rename to google/ads/googleads/v23/services/services/user_list_customer_type_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/user_list_customer_type_service/async_client.py b/google/ads/googleads/v23/services/services/user_list_customer_type_service/async_client.py new file mode 100644 index 000000000..d576b23bb --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_list_customer_type_service/async_client.py @@ -0,0 +1,445 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import ( + user_list_customer_type_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + UserListCustomerTypeServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .client import UserListCustomerTypeServiceClient + +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 UserListCustomerTypeServiceAsyncClient: + """Service to manage user list customer types.""" + + _client: UserListCustomerTypeServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = UserListCustomerTypeServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ( + UserListCustomerTypeServiceClient.DEFAULT_MTLS_ENDPOINT + ) + _DEFAULT_ENDPOINT_TEMPLATE = ( + UserListCustomerTypeServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = UserListCustomerTypeServiceClient._DEFAULT_UNIVERSE + + user_list_path = staticmethod( + UserListCustomerTypeServiceClient.user_list_path + ) + parse_user_list_path = staticmethod( + UserListCustomerTypeServiceClient.parse_user_list_path + ) + user_list_customer_type_path = staticmethod( + UserListCustomerTypeServiceClient.user_list_customer_type_path + ) + parse_user_list_customer_type_path = staticmethod( + UserListCustomerTypeServiceClient.parse_user_list_customer_type_path + ) + common_billing_account_path = staticmethod( + UserListCustomerTypeServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + UserListCustomerTypeServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod( + UserListCustomerTypeServiceClient.common_folder_path + ) + parse_common_folder_path = staticmethod( + UserListCustomerTypeServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + UserListCustomerTypeServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + UserListCustomerTypeServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + UserListCustomerTypeServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + UserListCustomerTypeServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + UserListCustomerTypeServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + UserListCustomerTypeServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserListCustomerTypeServiceAsyncClient: The constructed client. + """ + return UserListCustomerTypeServiceClient.from_service_account_info.__func__(UserListCustomerTypeServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserListCustomerTypeServiceAsyncClient: The constructed client. + """ + return UserListCustomerTypeServiceClient.from_service_account_file.__func__(UserListCustomerTypeServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return UserListCustomerTypeServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> UserListCustomerTypeServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserListCustomerTypeServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = UserListCustomerTypeServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + UserListCustomerTypeServiceTransport, + Callable[..., UserListCustomerTypeServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user list customer type service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,UserListCustomerTypeServiceTransport,Callable[..., UserListCustomerTypeServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the UserListCustomerTypeServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = UserListCustomerTypeServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.UserListCustomerTypeServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.UserListCustomerTypeService", + "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.ads.googleads.v23.services.UserListCustomerTypeService", + "credentialsType": None, + } + ), + ) + + async def mutate_user_list_customer_types( + self, + request: Optional[ + Union[ + user_list_customer_type_service.MutateUserListCustomerTypesRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + user_list_customer_type_service.UserListCustomerTypeOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> user_list_customer_type_service.MutateUserListCustomerTypesResponse: + r"""Attach or remove user list customer types. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `UserListCustomerTypeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateUserListCustomerTypesRequest, dict]]): + The request object. Request message for + [UserListCustomerTypeService.MutateUserListCustomerTypes][google.ads.googleads.v23.services.UserListCustomerTypeService.MutateUserListCustomerTypes]. + customer_id (:class:`str`): + Required. The ID of the customer + whose user list customer types are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.UserListCustomerTypeOperation]`): + Required. The list of operations to + perform on the user list customer types. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateUserListCustomerTypesResponse: + Response message for a user list + customer type mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + user_list_customer_type_service.MutateUserListCustomerTypesRequest, + ): + request = user_list_customer_type_service.MutateUserListCustomerTypesRequest( + request + ) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_user_list_customer_types + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "UserListCustomerTypeServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("UserListCustomerTypeServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/user_list_customer_type_service/client.py b/google/ads/googleads/v23/services/services/user_list_customer_type_service/client.py new file mode 100644 index 000000000..e582e2206 --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_list_customer_type_service/client.py @@ -0,0 +1,944 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import ( + user_list_customer_type_service, +) +from google.rpc import status_pb2 # type: ignore +from .transports.base import ( + UserListCustomerTypeServiceTransport, + DEFAULT_CLIENT_INFO, +) +from .transports.grpc import UserListCustomerTypeServiceGrpcTransport +from .transports.grpc_asyncio import ( + UserListCustomerTypeServiceGrpcAsyncIOTransport, +) + + +class UserListCustomerTypeServiceClientMeta(type): + """Metaclass for the UserListCustomerTypeService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[UserListCustomerTypeServiceTransport]] + _transport_registry["grpc"] = UserListCustomerTypeServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ( + UserListCustomerTypeServiceGrpcAsyncIOTransport + ) + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[UserListCustomerTypeServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class UserListCustomerTypeServiceClient( + metaclass=UserListCustomerTypeServiceClientMeta +): + """Service to manage user list customer types.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserListCustomerTypeServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserListCustomerTypeServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> UserListCustomerTypeServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserListCustomerTypeServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def user_list_path( + customer_id: str, + user_list_id: str, + ) -> str: + """Returns a fully-qualified user_list string.""" + return "customers/{customer_id}/userLists/{user_list_id}".format( + customer_id=customer_id, + user_list_id=user_list_id, + ) + + @staticmethod + def parse_user_list_path(path: str) -> Dict[str, str]: + """Parses a user_list path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userLists/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def user_list_customer_type_path( + customer_id: str, + user_list_id: str, + semantic_label: str, + ) -> str: + """Returns a fully-qualified user_list_customer_type string.""" + return "customers/{customer_id}/userListCustomerTypes/{user_list_id}~{semantic_label}".format( + customer_id=customer_id, + user_list_id=user_list_id, + semantic_label=semantic_label, + ) + + @staticmethod + def parse_user_list_customer_type_path(path: str) -> Dict[str, str]: + """Parses a user_list_customer_type path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userListCustomerTypes/(?P.+?)~(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = ( + UserListCustomerTypeServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = ( + UserListCustomerTypeServiceClient._use_client_cert_effective() + ) + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = ( + UserListCustomerTypeServiceClient._DEFAULT_UNIVERSE + ) + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = ( + UserListCustomerTypeServiceClient.DEFAULT_MTLS_ENDPOINT + ) + else: + api_endpoint = UserListCustomerTypeServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = UserListCustomerTypeServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + UserListCustomerTypeServiceTransport, + Callable[..., UserListCustomerTypeServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user list customer type service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,UserListCustomerTypeServiceTransport,Callable[..., UserListCustomerTypeServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the UserListCustomerTypeServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = UserListCustomerTypeServiceClient._read_environment_variables() + self._client_cert_source = ( + UserListCustomerTypeServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = ( + UserListCustomerTypeServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance( + transport, UserListCustomerTypeServiceTransport + ) + if transport_provided: + # transport is a UserListCustomerTypeServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast( + UserListCustomerTypeServiceTransport, transport + ) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or UserListCustomerTypeServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[UserListCustomerTypeServiceTransport], + Callable[..., UserListCustomerTypeServiceTransport], + ] = ( + UserListCustomerTypeServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast( + Callable[..., UserListCustomerTypeServiceTransport], + transport, + ) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.UserListCustomerTypeServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.UserListCustomerTypeService", + "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.ads.googleads.v23.services.UserListCustomerTypeService", + "credentialsType": None, + } + ), + ) + + def mutate_user_list_customer_types( + self, + request: Optional[ + Union[ + user_list_customer_type_service.MutateUserListCustomerTypesRequest, + dict, + ] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[ + user_list_customer_type_service.UserListCustomerTypeOperation + ] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> user_list_customer_type_service.MutateUserListCustomerTypesResponse: + r"""Attach or remove user list customer types. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `UserListCustomerTypeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateUserListCustomerTypesRequest, dict]): + The request object. Request message for + [UserListCustomerTypeService.MutateUserListCustomerTypes][google.ads.googleads.v23.services.UserListCustomerTypeService.MutateUserListCustomerTypes]. + customer_id (str): + Required. The ID of the customer + whose user list customer types are being + modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.UserListCustomerTypeOperation]): + Required. The list of operations to + perform on the user list customer types. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateUserListCustomerTypesResponse: + Response message for a user list + customer type mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance( + request, + user_list_customer_type_service.MutateUserListCustomerTypesRequest, + ): + request = user_list_customer_type_service.MutateUserListCustomerTypesRequest( + request + ) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_user_list_customer_types + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "UserListCustomerTypeServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("UserListCustomerTypeServiceClient",) diff --git a/google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/README.rst b/google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/README.rst rename to google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/__init__.py b/google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/user_list_customer_type_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/base.py b/google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/base.py new file mode 100644 index 000000000..418d67f37 --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/base.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import ( + user_list_customer_type_service, +) + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class UserListCustomerTypeServiceTransport(abc.ABC): + """Abstract transport class for UserListCustomerTypeService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_user_list_customer_types: gapic_v1.method.wrap_method( + self.mutate_user_list_customer_types, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_user_list_customer_types( + self, + ) -> Callable[ + [user_list_customer_type_service.MutateUserListCustomerTypesRequest], + Union[ + user_list_customer_type_service.MutateUserListCustomerTypesResponse, + Awaitable[ + user_list_customer_type_service.MutateUserListCustomerTypesResponse + ], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("UserListCustomerTypeServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/grpc.py b/google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/grpc.py new file mode 100644 index 000000000..5baf0af13 --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/grpc.py @@ -0,0 +1,394 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import ( + user_list_customer_type_service, +) +from .base import UserListCustomerTypeServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.UserListCustomerTypeService", + "rpcName": str(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.ads.googleads.v23.services.UserListCustomerTypeService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class UserListCustomerTypeServiceGrpcTransport( + UserListCustomerTypeServiceTransport +): + """gRPC backend transport for UserListCustomerTypeService. + + Service to manage user list customer types. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_user_list_customer_types( + self, + ) -> Callable[ + [user_list_customer_type_service.MutateUserListCustomerTypesRequest], + user_list_customer_type_service.MutateUserListCustomerTypesResponse, + ]: + r"""Return a callable for the mutate user list customer + types method over gRPC. + + Attach or remove user list customer types. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `UserListCustomerTypeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateUserListCustomerTypesRequest], + ~.MutateUserListCustomerTypesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_user_list_customer_types" not in self._stubs: + self._stubs["mutate_user_list_customer_types"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.UserListCustomerTypeService/MutateUserListCustomerTypes", + request_serializer=user_list_customer_type_service.MutateUserListCustomerTypesRequest.serialize, + response_deserializer=user_list_customer_type_service.MutateUserListCustomerTypesResponse.deserialize, + ) + ) + return self._stubs["mutate_user_list_customer_types"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("UserListCustomerTypeServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..2c4e64708 --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_list_customer_type_service/transports/grpc_asyncio.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import ( + user_list_customer_type_service, +) +from .base import UserListCustomerTypeServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.UserListCustomerTypeService", + "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.ads.googleads.v23.services.UserListCustomerTypeService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class UserListCustomerTypeServiceGrpcAsyncIOTransport( + UserListCustomerTypeServiceTransport +): + """gRPC AsyncIO backend transport for UserListCustomerTypeService. + + Service to manage user list customer types. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_user_list_customer_types( + self, + ) -> Callable[ + [user_list_customer_type_service.MutateUserListCustomerTypesRequest], + Awaitable[ + user_list_customer_type_service.MutateUserListCustomerTypesResponse + ], + ]: + r"""Return a callable for the mutate user list customer + types method over gRPC. + + Attach or remove user list customer types. Operation statuses + are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `UserListCustomerTypeError <>`__ + `HeaderError <>`__ `InternalError <>`__ `QuotaError <>`__ + `RequestError <>`__ + + Returns: + Callable[[~.MutateUserListCustomerTypesRequest], + Awaitable[~.MutateUserListCustomerTypesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_user_list_customer_types" not in self._stubs: + self._stubs["mutate_user_list_customer_types"] = ( + self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.UserListCustomerTypeService/MutateUserListCustomerTypes", + request_serializer=user_list_customer_type_service.MutateUserListCustomerTypesRequest.serialize, + response_deserializer=user_list_customer_type_service.MutateUserListCustomerTypesResponse.deserialize, + ) + ) + return self._stubs["mutate_user_list_customer_types"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_user_list_customer_types: self._wrap_method( + self.mutate_user_list_customer_types, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("UserListCustomerTypeServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v19/services/services/user_list_service/__init__.py b/google/ads/googleads/v23/services/services/user_list_service/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/user_list_service/__init__.py rename to google/ads/googleads/v23/services/services/user_list_service/__init__.py diff --git a/google/ads/googleads/v23/services/services/user_list_service/async_client.py b/google/ads/googleads/v23/services/services/user_list_service/async_client.py new file mode 100644 index 000000000..575ee5abc --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_list_service/async_client.py @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +from typing import Callable, MutableSequence, Optional, Sequence, Tuple, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core.client_options import ClientOptions +from google.api_core import gapic_v1 +from google.api_core import retry_async as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + + +try: + OptionalRetry = Union[ + retries.AsyncRetry, gapic_v1.method._MethodDefault, None + ] +except AttributeError: # pragma: NO COVER + OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore + +from google.ads.googleads.v23.services.types import user_list_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import UserListServiceTransport, DEFAULT_CLIENT_INFO +from .client import UserListServiceClient + +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 UserListServiceAsyncClient: + """Service to manage user lists.""" + + _client: UserListServiceClient + + # Copy defaults from the synchronous client for use here. + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = UserListServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = UserListServiceClient.DEFAULT_MTLS_ENDPOINT + _DEFAULT_ENDPOINT_TEMPLATE = ( + UserListServiceClient._DEFAULT_ENDPOINT_TEMPLATE + ) + _DEFAULT_UNIVERSE = UserListServiceClient._DEFAULT_UNIVERSE + + user_list_path = staticmethod(UserListServiceClient.user_list_path) + parse_user_list_path = staticmethod( + UserListServiceClient.parse_user_list_path + ) + common_billing_account_path = staticmethod( + UserListServiceClient.common_billing_account_path + ) + parse_common_billing_account_path = staticmethod( + UserListServiceClient.parse_common_billing_account_path + ) + common_folder_path = staticmethod(UserListServiceClient.common_folder_path) + parse_common_folder_path = staticmethod( + UserListServiceClient.parse_common_folder_path + ) + common_organization_path = staticmethod( + UserListServiceClient.common_organization_path + ) + parse_common_organization_path = staticmethod( + UserListServiceClient.parse_common_organization_path + ) + common_project_path = staticmethod( + UserListServiceClient.common_project_path + ) + parse_common_project_path = staticmethod( + UserListServiceClient.parse_common_project_path + ) + common_location_path = staticmethod( + UserListServiceClient.common_location_path + ) + parse_common_location_path = staticmethod( + UserListServiceClient.parse_common_location_path + ) + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserListServiceAsyncClient: The constructed client. + """ + return UserListServiceClient.from_service_account_info.__func__(UserListServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserListServiceAsyncClient: The constructed client. + """ + return UserListServiceClient.from_service_account_file.__func__(UserListServiceAsyncClient, filename, *args, **kwargs) # type: ignore + + from_service_account_json = from_service_account_file + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[ClientOptions] = None + ): + """Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + return UserListServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> UserListServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserListServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._client._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used + by the client instance. + """ + return self._client._universe_domain + + get_transport_class = UserListServiceClient.get_transport_class + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + UserListServiceTransport, + Callable[..., UserListServiceTransport], + ] + ] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user list service async client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,UserListServiceTransport,Callable[..., UserListServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport to use. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the UserListServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client = UserListServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + ) + + if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ): # pragma: NO COVER + _LOGGER.debug( + "Created client `google.ads.googleads.v23.services.UserListServiceAsyncClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.UserListService", + "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.ads.googleads.v23.services.UserListService", + "credentialsType": None, + } + ), + ) + + async def mutate_user_lists( + self, + request: Optional[ + Union[user_list_service.MutateUserListsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[user_list_service.UserListOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> user_list_service.MutateUserListsResponse: + r"""Creates or updates user lists. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UserListError <>`__ + + Args: + request (Optional[Union[google.ads.googleads.v23.services.types.MutateUserListsRequest, dict]]): + The request object. Request message for + [UserListService.MutateUserLists][google.ads.googleads.v23.services.UserListService.MutateUserLists]. + customer_id (:class:`str`): + Required. The ID of the customer + whose user lists are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (:class:`MutableSequence[google.ads.googleads.v23.services.types.UserListOperation]`): + Required. The list of operations to + perform on individual user lists. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + 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, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateUserListsResponse: + Response message for user list + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, user_list_service.MutateUserListsRequest): + request = user_list_service.MutateUserListsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations: + request.operations.extend(operations) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._client._transport._wrapped_methods[ + self._client._transport.mutate_user_lists + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def __aenter__(self) -> "UserListServiceAsyncClient": + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +__all__ = ("UserListServiceAsyncClient",) diff --git a/google/ads/googleads/v23/services/services/user_list_service/client.py b/google/ads/googleads/v23/services/services/user_list_service/client.py new file mode 100644 index 000000000..c406cd197 --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_list_service/client.py @@ -0,0 +1,889 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from collections import OrderedDict +from http import HTTPStatus +import json +import logging as std_logging +import os +import re +from typing import ( + Dict, + Callable, + MutableSequence, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) +import warnings + +from google.ads.googleads.v23 import gapic_version as package_version + +from google.api_core import client_options as client_options_lib +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.api_core import retry as retries +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +try: + OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None] +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.ads.googleads.v23.services.types import user_list_service +from google.rpc import status_pb2 # type: ignore +from .transports.base import UserListServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import UserListServiceGrpcTransport +from .transports.grpc_asyncio import UserListServiceGrpcAsyncIOTransport + + +class UserListServiceClientMeta(type): + """Metaclass for the UserListService client. + + This provides class-level methods for building and retrieving + support objects (e.g. transport) without polluting the client instance + objects. + """ + + _transport_registry = ( + OrderedDict() + ) # type: Dict[str, Type[UserListServiceTransport]] + _transport_registry["grpc"] = UserListServiceGrpcTransport + _transport_registry["grpc_asyncio"] = UserListServiceGrpcAsyncIOTransport + + def get_transport_class( + cls, + label: Optional[str] = None, + ) -> Type[UserListServiceTransport]: + """Returns an appropriate transport class. + + Args: + label: The name of the desired transport. If none is + provided, then the first transport in the registry is used. + + Returns: + The transport class to use. + """ + # If a specific transport is requested, return that one. + if label: + return cls._transport_registry[label] + + # No transport is requested; return the default (that is, the first one + # in the dictionary). + return next(iter(cls._transport_registry.values())) + + +class UserListServiceClient(metaclass=UserListServiceClientMeta): + """Service to manage user lists.""" + + @staticmethod + def _get_default_mtls_endpoint(api_endpoint): + """Converts api endpoint to mTLS endpoint. + + Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to + "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively. + Args: + api_endpoint (Optional[str]): the api endpoint to convert. + Returns: + str: converted mTLS api endpoint. + """ + if not api_endpoint: + return api_endpoint + + mtls_endpoint_re = re.compile( + r"(?P[^.]+)(?P\.mtls)?(?P\.sandbox)?(?P\.googleapis\.com)?" + ) + + m = mtls_endpoint_re.match(api_endpoint) + name, mtls, sandbox, googledomain = m.groups() + if mtls or not googledomain: + return api_endpoint + + if sandbox: + return api_endpoint.replace( + "sandbox.googleapis.com", "mtls.sandbox.googleapis.com" + ) + + return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com") + + # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead. + DEFAULT_ENDPOINT = "googleads.googleapis.com" + DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore + DEFAULT_ENDPOINT + ) + + _DEFAULT_ENDPOINT_TEMPLATE = "googleads.{UNIVERSE_DOMAIN}" + _DEFAULT_UNIVERSE = "googleapis.com" + + @staticmethod + def _use_client_cert_effective(): + """Returns whether client certificate should be used for mTLS if the + google-auth version supports should_use_client_cert automatic mTLS enablement. + + Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var. + + Returns: + bool: whether client certificate should be used for mTLS + Raises: + ValueError: (If using a version of google-auth without should_use_client_cert and + GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.) + """ + # check if google-auth version supports should_use_client_cert for automatic mTLS enablement + if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER + return mtls.should_use_client_cert() + else: # pragma: NO COVER + # if unsupported, fallback to reading from env var + use_client_cert_str = os.getenv( + "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false" + ).lower() + if use_client_cert_str not in ("true", "false"): + raise ValueError( + "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be" + " either `true` or `false`" + ) + return use_client_cert_str == "true" + + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials + info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserListServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_info( + info + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + UserListServiceClient: The constructed client. + """ + credentials = service_account.Credentials.from_service_account_file( + filename + ) + kwargs["credentials"] = credentials + return cls(*args, **kwargs) + + from_service_account_json = from_service_account_file + + @property + def transport(self) -> UserListServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserListServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def user_list_path( + customer_id: str, + user_list_id: str, + ) -> str: + """Returns a fully-qualified user_list string.""" + return "customers/{customer_id}/userLists/{user_list_id}".format( + customer_id=customer_id, + user_list_id=user_list_id, + ) + + @staticmethod + def parse_user_list_path(path: str) -> Dict[str, str]: + """Parses a user_list path into its component segments.""" + m = re.match( + r"^customers/(?P.+?)/userLists/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def common_billing_account_path( + billing_account: str, + ) -> str: + """Returns a fully-qualified billing_account string.""" + return "billingAccounts/{billing_account}".format( + billing_account=billing_account, + ) + + @staticmethod + def parse_common_billing_account_path(path: str) -> Dict[str, str]: + """Parse a billing_account path into its component segments.""" + m = re.match(r"^billingAccounts/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_folder_path( + folder: str, + ) -> str: + """Returns a fully-qualified folder string.""" + return "folders/{folder}".format( + folder=folder, + ) + + @staticmethod + def parse_common_folder_path(path: str) -> Dict[str, str]: + """Parse a folder path into its component segments.""" + m = re.match(r"^folders/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_organization_path( + organization: str, + ) -> str: + """Returns a fully-qualified organization string.""" + return "organizations/{organization}".format( + organization=organization, + ) + + @staticmethod + def parse_common_organization_path(path: str) -> Dict[str, str]: + """Parse a organization path into its component segments.""" + m = re.match(r"^organizations/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_project_path( + project: str, + ) -> str: + """Returns a fully-qualified project string.""" + return "projects/{project}".format( + project=project, + ) + + @staticmethod + def parse_common_project_path(path: str) -> Dict[str, str]: + """Parse a project path into its component segments.""" + m = re.match(r"^projects/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def common_location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_common_location_path(path: str) -> Dict[str, str]: + """Parse a location path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)$", path + ) + return m.groupdict() if m else {} + + @classmethod + def get_mtls_endpoint_and_cert_source( + cls, client_options: Optional[client_options_lib.ClientOptions] = None + ): + """Deprecated. Return the API endpoint and client cert source for mutual TLS. + + The client cert source is determined in the following order: + (1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the + client cert source is None. + (2) if `client_options.client_cert_source` is provided, use the provided one; if the + default client cert source exists, use the default one; otherwise the client cert + source is None. + + The API endpoint is determined in the following order: + (1) if `client_options.api_endpoint` if provided, use the provided one. + (2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the + default mTLS endpoint; if the environment variable is "never", use the default API + endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise + use the default API endpoint. + + More details can be found at https://google.aip.dev/auth/4114. + + Args: + client_options (google.api_core.client_options.ClientOptions): Custom options for the + client. Only the `api_endpoint` and `client_cert_source` properties may be used + in this method. + + Returns: + Tuple[str, Callable[[], Tuple[bytes, bytes]]]: returns the API endpoint and the + client cert source to use. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If any errors happen. + """ + + warnings.warn( + "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.", + DeprecationWarning, + ) + if client_options is None: + client_options = client_options_lib.ClientOptions() + use_client_cert = UserListServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + + # Figure out the client cert source to use. + client_cert_source = None + if use_client_cert: + if client_options.client_cert_source: + client_cert_source = client_options.client_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + + # Figure out which api endpoint to use. + if client_options.api_endpoint is not None: + api_endpoint = client_options.api_endpoint + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + api_endpoint = cls.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = cls.DEFAULT_ENDPOINT + + return api_endpoint, client_cert_source + + @staticmethod + def _read_environment_variables(): + """Returns the environment variables used by the client. + + Returns: + Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE, + GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables. + + Raises: + ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not + any of ["true", "false"]. + google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT + is not any of ["auto", "never", "always"]. + """ + use_client_cert = UserListServiceClient._use_client_cert_effective() + use_mtls_endpoint = os.getenv( + "GOOGLE_API_USE_MTLS_ENDPOINT", "auto" + ).lower() + universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN") + if use_mtls_endpoint not in ("auto", "never", "always"): + raise MutualTLSChannelError( + "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`" + ) + return use_client_cert, use_mtls_endpoint, universe_domain_env + + @staticmethod + def _get_client_cert_source(provided_cert_source, use_cert_flag): + """Return the client cert source to be used by the client. + + Args: + provided_cert_source (bytes): The client certificate source provided. + use_cert_flag (bool): A flag indicating whether to use the client certificate. + + Returns: + bytes or None: The client cert source to be used by the client. + """ + client_cert_source = None + if use_cert_flag: + if provided_cert_source: + client_cert_source = provided_cert_source + elif mtls.has_default_client_cert_source(): + client_cert_source = mtls.default_client_cert_source() + return client_cert_source + + @staticmethod + def _get_api_endpoint( + api_override, client_cert_source, universe_domain, use_mtls_endpoint + ): + """Return the API endpoint used by the client. + + Args: + api_override (str): The API endpoint override. If specified, this is always + the return value of this function and the other arguments are not used. + client_cert_source (bytes): The client certificate source used by the client. + universe_domain (str): The universe domain used by the client. + use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters. + Possible values are "always", "auto", or "never". + + Returns: + str: The API endpoint to be used by the client. + """ + if api_override is not None: + api_endpoint = api_override + elif use_mtls_endpoint == "always" or ( + use_mtls_endpoint == "auto" and client_cert_source + ): + _default_universe = UserListServiceClient._DEFAULT_UNIVERSE + if universe_domain != _default_universe: + raise MutualTLSChannelError( + f"mTLS is not supported in any universe other than {_default_universe}." + ) + api_endpoint = UserListServiceClient.DEFAULT_MTLS_ENDPOINT + else: + api_endpoint = ( + UserListServiceClient._DEFAULT_ENDPOINT_TEMPLATE.format( + UNIVERSE_DOMAIN=universe_domain + ) + ) + return api_endpoint + + @staticmethod + def _get_universe_domain( + client_universe_domain: Optional[str], + universe_domain_env: Optional[str], + ) -> str: + """Return the universe domain used by the client. + + Args: + client_universe_domain (Optional[str]): The universe domain configured via the client options. + universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable. + + Returns: + str: The universe domain to be used by the client. + + Raises: + ValueError: If the universe domain is an empty string. + """ + universe_domain = UserListServiceClient._DEFAULT_UNIVERSE + if client_universe_domain is not None: + universe_domain = client_universe_domain + elif universe_domain_env is not None: + universe_domain = universe_domain_env + if len(universe_domain.strip()) == 0: + raise ValueError("Universe Domain cannot be an empty string.") + return universe_domain + + def _validate_universe_domain(self): + """Validates client's and credentials' universe domains are consistent. + + Returns: + bool: True iff the configured universe domain is valid. + + Raises: + ValueError: If the configured universe domain is not valid. + """ + + # NOTE (b/349488459): universe validation is disabled until further notice. + return True + + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + + @property + def api_endpoint(self): + """Return the API endpoint used by the client instance. + + Returns: + str: The API endpoint used by the client instance. + """ + return self._api_endpoint + + @property + def universe_domain(self) -> str: + """Return the universe domain used by the client instance. + + Returns: + str: The universe domain used by the client instance. + """ + return self._universe_domain + + def __init__( + self, + *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Optional[ + Union[ + str, + UserListServiceTransport, + Callable[..., UserListServiceTransport], + ] + ] = None, + client_options: Optional[ + Union[client_options_lib.ClientOptions, dict] + ] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user list service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Optional[Union[str,UserListServiceTransport,Callable[..., UserListServiceTransport]]]): + The transport to use, or a Callable that constructs and returns a new transport. + If a Callable is given, it will be called with the same set of initialization + arguments as used in the UserListServiceTransport constructor. + If set to None, a transport is chosen automatically. + client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]): + Custom options for the client. + + 1. The ``api_endpoint`` property can be used to override the + default endpoint provided by the client when ``transport`` is + not explicitly provided. Only if this property is not set and + ``transport`` was not explicitly provided, the endpoint is + determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment + variable, which have one of the following values: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint) and "auto" (auto-switch to the + default mTLS endpoint if client certificate is present; this is + the default value). + + 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable + is "true", then the ``client_cert_source`` property can be used + to provide a client certificate for mTLS transport. If + not provided, the default SSL client certificate will be used if + present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not + set, no client certificate will be used. + + 3. The ``universe_domain`` property can be used to override the + default "googleapis.com" universe. Note that the ``api_endpoint`` + property still takes precedence; and ``universe_domain`` is + currently not supported for mTLS. + + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + """ + self._client_options = client_options + if isinstance(self._client_options, dict): + self._client_options = client_options_lib.from_dict( + self._client_options + ) + if self._client_options is None: + self._client_options = client_options_lib.ClientOptions() + self._client_options = cast( + client_options_lib.ClientOptions, self._client_options + ) + + universe_domain_opt = getattr( + self._client_options, "universe_domain", None + ) + + ( + self._use_client_cert, + self._use_mtls_endpoint, + self._universe_domain_env, + ) = UserListServiceClient._read_environment_variables() + self._client_cert_source = ( + UserListServiceClient._get_client_cert_source( + self._client_options.client_cert_source, self._use_client_cert + ) + ) + self._universe_domain = UserListServiceClient._get_universe_domain( + universe_domain_opt, self._universe_domain_env + ) + self._api_endpoint = None # updated below, depending on `transport` + + # 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( + "client_options.api_key and credentials are mutually exclusive" + ) + + # Save or instantiate the transport. + # Ordinarily, we provide the transport, but allowing a custom transport + # instance provides an extensibility point for unusual situations. + transport_provided = isinstance(transport, UserListServiceTransport) + if transport_provided: + # transport is a UserListServiceTransport instance. + if ( + credentials + or self._client_options.credentials_file + or api_key_value + ): + raise ValueError( + "When providing a transport instance, " + "provide its credentials directly." + ) + if self._client_options.scopes: + raise ValueError( + "When providing a transport instance, provide its scopes " + "directly." + ) + self._transport = cast(UserListServiceTransport, transport) + self._api_endpoint = self._transport.host + + self._api_endpoint = ( + self._api_endpoint + or UserListServiceClient._get_api_endpoint( + self._client_options.api_endpoint, + self._client_cert_source, + self._universe_domain, + self._use_mtls_endpoint, + ) + ) + + if not transport_provided: + import google.auth._default # type: ignore + + if api_key_value and hasattr( + google.auth._default, "get_api_key_credentials" + ): + credentials = google.auth._default.get_api_key_credentials( + api_key_value + ) + + transport_init: Union[ + Type[UserListServiceTransport], + Callable[..., UserListServiceTransport], + ] = ( + UserListServiceClient.get_transport_class(transport) + if isinstance(transport, str) or transport is None + else cast(Callable[..., UserListServiceTransport], transport) + ) + # initialize with the provided callable or the passed in class + self._transport = transport_init( + credentials=credentials, + credentials_file=self._client_options.credentials_file, + host=self._api_endpoint, + scopes=self._client_options.scopes, + client_cert_source_for_mtls=self._client_cert_source, + quota_project_id=self._client_options.quota_project_id, + client_info=client_info, + 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 `google.ads.googleads.v23.services.UserListServiceClient`.", + extra=( + { + "serviceName": "google.ads.googleads.v23.services.UserListService", + "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.ads.googleads.v23.services.UserListService", + "credentialsType": None, + } + ), + ) + + def mutate_user_lists( + self, + request: Optional[ + Union[user_list_service.MutateUserListsRequest, dict] + ] = None, + *, + customer_id: Optional[str] = None, + operations: Optional[ + MutableSequence[user_list_service.UserListOperation] + ] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, Union[str, bytes]]] = (), + ) -> user_list_service.MutateUserListsResponse: + r"""Creates or updates user lists. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UserListError <>`__ + + Args: + request (Union[google.ads.googleads.v23.services.types.MutateUserListsRequest, dict]): + The request object. Request message for + [UserListService.MutateUserLists][google.ads.googleads.v23.services.UserListService.MutateUserLists]. + customer_id (str): + Required. The ID of the customer + whose user lists are being modified. + + This corresponds to the ``customer_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + operations (MutableSequence[google.ads.googleads.v23.services.types.UserListOperation]): + Required. The list of operations to + perform on individual user lists. + + This corresponds to the ``operations`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be + sent along with the request as metadata. Normally, each 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.ads.googleads.v23.services.types.MutateUserListsResponse: + Response message for user list + mutate. + + """ + # Create or coerce a protobuf request object. + # - Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + flattened_params = [customer_id, operations] + has_flattened_params = ( + len([param for param in flattened_params if param is not None]) > 0 + ) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # - Use the request object if provided (there's no risk of modifying the input as + # there are no flattened fields), or create one. + if not isinstance(request, user_list_service.MutateUserListsRequest): + request = user_list_service.MutateUserListsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if customer_id is not None: + request.customer_id = customer_id + if operations is not None: + request.operations = operations + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[ + self._transport.mutate_user_lists + ] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("customer_id", request.customer_id),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "UserListServiceClient": + return self + + def __exit__(self, type, value, traceback): + """Releases underlying transport's resources. + + .. warning:: + ONLY use as a context manager if the transport is NOT shared + with other clients! Exiting the with block will CLOSE the transport + and may cause errors in other clients! + """ + self.transport.close() + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + +__all__ = ("UserListServiceClient",) diff --git a/google/ads/googleads/v19/services/services/user_list_service/transports/README.rst b/google/ads/googleads/v23/services/services/user_list_service/transports/README.rst similarity index 100% rename from google/ads/googleads/v19/services/services/user_list_service/transports/README.rst rename to google/ads/googleads/v23/services/services/user_list_service/transports/README.rst diff --git a/google/ads/googleads/v19/services/services/user_list_service/transports/__init__.py b/google/ads/googleads/v23/services/services/user_list_service/transports/__init__.py similarity index 100% rename from google/ads/googleads/v19/services/services/user_list_service/transports/__init__.py rename to google/ads/googleads/v23/services/services/user_list_service/transports/__init__.py diff --git a/google/ads/googleads/v23/services/services/user_list_service/transports/base.py b/google/ads/googleads/v23/services/services/user_list_service/transports/base.py new file mode 100644 index 000000000..3e2bccac1 --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_list_service/transports/base.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import abc +from typing import Awaitable, Callable, Optional, Sequence, Union + +from google.ads.googleads.v23 import gapic_version as package_version + +import google.auth # type: ignore +import google.api_core +from google.api_core import exceptions as core_exceptions +from google.api_core import gapic_v1 +from google.auth import credentials as ga_credentials # type: ignore +from google.oauth2 import service_account # type: ignore +import google.protobuf + +from google.ads.googleads.v23.services.types import user_list_service + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( + gapic_version=package_version.__version__ +) + +if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER + DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__ + + +class UserListServiceTransport(abc.ABC): + """Abstract transport class for UserListService.""" + + AUTH_SCOPES = ("https://www.googleapis.com/auth/adwords",) + + DEFAULT_HOST: str = "googleads.googleapis.com" + + def __init__( + self, + *, + host: str = DEFAULT_HOST, + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + **kwargs, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A list of scopes. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + """ + + scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES} + + # Save the scopes. + self._scopes = scopes + if not hasattr(self, "_ignore_credentials"): + self._ignore_credentials: bool = False + + # If no credentials are provided, then determine the appropriate + # defaults. + if credentials and credentials_file: + raise core_exceptions.DuplicateCredentialArgs( + "'credentials_file' and 'credentials' are mutually exclusive" + ) + + if credentials_file is not None: + credentials, _ = google.auth.load_credentials_from_file( + credentials_file, + **scopes_kwargs, + quota_project_id=quota_project_id, + ) + elif credentials is None and not self._ignore_credentials: + credentials, _ = google.auth.default( + **scopes_kwargs, quota_project_id=quota_project_id + ) + # Don't apply audience if the credentials file passed from user. + if hasattr(credentials, "with_gdch_audience"): + credentials = credentials.with_gdch_audience( + api_audience if api_audience else host + ) + + # If the credentials are service account credentials, then always try to use self signed JWT. + if ( + always_use_jwt_access + and isinstance(credentials, service_account.Credentials) + and hasattr( + service_account.Credentials, "with_always_use_jwt_access" + ) + ): + credentials = credentials.with_always_use_jwt_access(True) + + # Save the credentials. + self._credentials = credentials + + # Save the hostname. Default to port 443 (HTTPS) if none is specified. + if ":" not in host: + host += ":443" + self._host = host + + @property + def host(self): + return self._host + + def _prep_wrapped_messages(self, client_info): + # Precompute the wrapped methods. + self._wrapped_methods = { + self.mutate_user_lists: gapic_v1.method.wrap_method( + self.mutate_user_lists, + default_timeout=None, + client_info=client_info, + ), + } + + def close(self): + """Closes resources associated with the transport. + + .. warning:: + Only call this method if the transport is NOT shared + with other clients - this may cause errors in other clients! + """ + raise NotImplementedError() + + @property + def mutate_user_lists( + self, + ) -> Callable[ + [user_list_service.MutateUserListsRequest], + Union[ + user_list_service.MutateUserListsResponse, + Awaitable[user_list_service.MutateUserListsResponse], + ], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ("UserListServiceTransport",) diff --git a/google/ads/googleads/v23/services/services/user_list_service/transports/grpc.py b/google/ads/googleads/v23/services/services/user_list_service/transports/grpc.py new file mode 100644 index 000000000..6431c66da --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_list_service/transports/grpc.py @@ -0,0 +1,391 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import logging as std_logging +import pickle +import warnings +from typing import Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import grpc_helpers +from google.api_core import gapic_v1 +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.ads.googleads.v23.services.types import user_list_service +from .base import UserListServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _LoggingClientInterceptor( + grpc.UnaryUnaryClientInterceptor +): # pragma: NO COVER + def intercept_unary_unary(self, continuation, client_call_details, request): + logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( + std_logging.DEBUG + ) + if logging_enabled: # pragma: NO COVER + request_metadata = client_call_details.metadata + if isinstance(request, proto.Message): + request_payload = type(request).to_json(request) + elif isinstance(request, google.protobuf.message.Message): + request_payload = MessageToJson(request) + else: + request_payload = ( + f"{type(request).__name__}: {pickle.dumps(request)}" + ) + + request_metadata = { + key: ( + value.decode("utf-8") if isinstance(value, bytes) else value + ) + for key, value in request_metadata + } + grpc_request = { + "payload": request_payload, + "requestMethod": "grpc", + "metadata": dict(request_metadata), + } + _LOGGER.debug( + f"Sending request for {client_call_details.method}", + extra={ + "serviceName": "google.ads.googleads.v23.services.UserListService", + "rpcName": str(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.ads.googleads.v23.services.UserListService", + "rpcName": client_call_details.method, + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class UserListServiceGrpcTransport(UserListServiceTransport): + """gRPC backend transport for UserListService. + + Service to manage user lists. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _stubs: Dict[str, Callable] + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[grpc.Channel, Callable[..., grpc.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional(Sequence[str])): A list of scopes. This argument is + ignored if a ``channel`` instance is provided. + channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, grpc.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> grpc.Channel: + """Create and return a gRPC channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is mutually exclusive with credentials. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + grpc.Channel: A gRPC channel object. + + Raises: + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + + return grpc_helpers.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + @property + def grpc_channel(self) -> grpc.Channel: + """Return the channel designed to connect to this service.""" + return self._grpc_channel + + @property + def mutate_user_lists( + self, + ) -> Callable[ + [user_list_service.MutateUserListsRequest], + user_list_service.MutateUserListsResponse, + ]: + r"""Return a callable for the mutate user lists method over gRPC. + + Creates or updates user lists. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UserListError <>`__ + + Returns: + Callable[[~.MutateUserListsRequest], + ~.MutateUserListsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_user_lists" not in self._stubs: + self._stubs["mutate_user_lists"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.UserListService/MutateUserLists", + request_serializer=user_list_service.MutateUserListsRequest.serialize, + response_deserializer=user_list_service.MutateUserListsResponse.deserialize, + ) + return self._stubs["mutate_user_lists"] + + def close(self): + self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ("UserListServiceGrpcTransport",) diff --git a/google/ads/googleads/v23/services/services/user_list_service/transports/grpc_asyncio.py b/google/ads/googleads/v23/services/services/user_list_service/transports/grpc_asyncio.py new file mode 100644 index 000000000..906b50c92 --- /dev/null +++ b/google/ads/googleads/v23/services/services/user_list_service/transports/grpc_asyncio.py @@ -0,0 +1,412 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import inspect +import pickle +import logging as std_logging +import warnings +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union + +from google.api_core import gapic_v1 +from google.api_core import grpc_helpers_async +from google.auth import credentials as ga_credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore +from google.protobuf.json_format import MessageToJson +import google.protobuf.message + +import grpc # type: ignore +import proto # type: ignore +from grpc.experimental import aio # type: ignore + +from google.ads.googleads.v23.services.types import user_list_service +from .base import UserListServiceTransport, DEFAULT_CLIENT_INFO + +try: + from google.api_core import client_logging # type: ignore + + CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER +except ImportError: # pragma: NO COVER + CLIENT_LOGGING_SUPPORTED = False + +_LOGGER = std_logging.getLogger(__name__) + + +class _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.ads.googleads.v23.services.UserListService", + "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.ads.googleads.v23.services.UserListService", + "rpcName": str(client_call_details.method), + "response": grpc_response, + "metadata": grpc_response["metadata"], + }, + ) + return response + + +class UserListServiceGrpcAsyncIOTransport(UserListServiceTransport): + """gRPC AsyncIO backend transport for UserListService. + + Service to manage user lists. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + quota_project_id: Optional[str] = None, + **kwargs, + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + host (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be + removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + + return grpc_helpers_async.create_channel( + host, + credentials=credentials, + credentials_file=credentials_file, + quota_project_id=quota_project_id, + default_scopes=cls.AUTH_SCOPES, + scopes=scopes, + default_host=cls.DEFAULT_HOST, + **kwargs, + ) + + def __init__( + self, + *, + host: str = "googleads.googleapis.com", + credentials: Optional[ga_credentials.Credentials] = None, + credentials_file: Optional[str] = None, + scopes: Optional[Sequence[str]] = None, + channel: Optional[ + Union[aio.Channel, Callable[..., aio.Channel]] + ] = None, + api_mtls_endpoint: Optional[str] = None, + client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, + ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, + client_cert_source_for_mtls: Optional[ + Callable[[], Tuple[bytes, bytes]] + ] = None, + quota_project_id: Optional[str] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + always_use_jwt_access: Optional[bool] = False, + api_audience: Optional[str] = None, + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): + The hostname to connect to (default: 'googleads.googleapis.com'). + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if a ``channel`` instance is provided. + credentials_file (Optional[str]): Deprecated. A file with credentials that can + be loaded with :func:`google.auth.load_credentials_from_file`. + This argument is ignored if a ``channel`` instance is provided. + This argument will be removed in the next major version of this library. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): + A ``Channel`` instance through which to make calls, or a Callable + that constructs and returns one. If set to None, ``self.create_channel`` + is used to create the channel. If a Callable is given, it will be called + with the same arguments as used in ``self.create_channel``. + api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. + If provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or application default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): + Deprecated. A callback to provide client SSL certificate bytes and + private key bytes, both in PEM format. It is ignored if + ``api_mtls_endpoint`` is None. + ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials + for the grpc channel. It is ignored if a ``channel`` instance is provided. + client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): + A callback to provide client certificate bytes and private key bytes, + both in PEM format. It is used to configure a mutual TLS channel. It is + ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. + quota_project_id (Optional[str]): An optional project to use for billing + and quota. + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing + your own client library. + always_use_jwt_access (Optional[bool]): Whether self signed JWT should + be used for service account credentials. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` + and ``credentials_file`` are passed. + """ + self._grpc_channel = None + self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + + if api_mtls_endpoint: + warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) + if client_cert_source: + warnings.warn( + "client_cert_source is deprecated", DeprecationWarning + ) + + if isinstance(channel, aio.Channel): + # Ignore credentials if a channel was passed. + credentials = None + self._ignore_credentials = True + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + self._ssl_channel_credentials = None + else: + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + else: + self._ssl_channel_credentials = ( + SslCredentials().ssl_credentials + ) + + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = ( + grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + ) + + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + always_use_jwt_access=always_use_jwt_access, + api_audience=api_audience, + ) + + if not self._grpc_channel: + # initialize with the provided callable or the default channel + channel_init = channel or type(self).create_channel + self._grpc_channel = channel_init( + self._host, + # use the credentials which are saved + credentials=self._credentials, + # Set ``credentials_file`` to ``None`` here as + # the credentials that we saved earlier should be used. + credentials_file=None, + scopes=self._scopes, + ssl_credentials=self._ssl_channel_credentials, + quota_project_id=quota_project_id, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + 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 + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Return the channel from cache. + return self._grpc_channel + + @property + def mutate_user_lists( + self, + ) -> Callable[ + [user_list_service.MutateUserListsRequest], + Awaitable[user_list_service.MutateUserListsResponse], + ]: + r"""Return a callable for the mutate user lists method over gRPC. + + Creates or updates user lists. Operation statuses are returned. + + List of thrown errors: `AuthenticationError <>`__ + `AuthorizationError <>`__ `CollectionSizeError <>`__ + `DatabaseError <>`__ `DistinctError <>`__ `FieldError <>`__ + `FieldMaskError <>`__ `HeaderError <>`__ `InternalError <>`__ + `MutateError <>`__ `NewResourceCreationError <>`__ + `NotAllowlistedError <>`__ `NotEmptyError <>`__ + `OperationAccessDeniedError <>`__ `QuotaError <>`__ + `RangeError <>`__ `RequestError <>`__ `StringFormatError <>`__ + `StringLengthError <>`__ `UserListError <>`__ + + Returns: + Callable[[~.MutateUserListsRequest], + Awaitable[~.MutateUserListsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "mutate_user_lists" not in self._stubs: + self._stubs["mutate_user_lists"] = self._logged_channel.unary_unary( + "/google.ads.googleads.v23.services.UserListService/MutateUserLists", + request_serializer=user_list_service.MutateUserListsRequest.serialize, + response_deserializer=user_list_service.MutateUserListsResponse.deserialize, + ) + return self._stubs["mutate_user_lists"] + + def _prep_wrapped_messages(self, client_info): + """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" + self._wrapped_methods = { + self.mutate_user_lists: self._wrap_method( + self.mutate_user_lists, + default_timeout=None, + client_info=client_info, + ), + } + + def _wrap_method(self, func, *args, **kwargs): + if self._wrap_with_kind: # pragma: NO COVER + kwargs["kind"] = self.kind + return gapic_v1.method_async.wrap_method(func, *args, **kwargs) + + def close(self): + return self._logged_channel.close() + + @property + def kind(self) -> str: + return "grpc_asyncio" + + +__all__ = ("UserListServiceGrpcAsyncIOTransport",) diff --git a/google/ads/googleads/v23/services/types/__init__.py b/google/ads/googleads/v23/services/types/__init__.py new file mode 100644 index 000000000..0bea55c09 --- /dev/null +++ b/google/ads/googleads/v23/services/types/__init__.py @@ -0,0 +1,1464 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from .account_budget_proposal_service import ( + AccountBudgetProposalOperation, + MutateAccountBudgetProposalRequest, + MutateAccountBudgetProposalResponse, + MutateAccountBudgetProposalResult, +) +from .account_link_service import ( + AccountLinkOperation, + CreateAccountLinkRequest, + CreateAccountLinkResponse, + MutateAccountLinkRequest, + MutateAccountLinkResponse, + MutateAccountLinkResult, +) +from .ad_group_ad_label_service import ( + AdGroupAdLabelOperation, + MutateAdGroupAdLabelResult, + MutateAdGroupAdLabelsRequest, + MutateAdGroupAdLabelsResponse, +) +from .ad_group_ad_service import ( + AdGroupAdOperation, + AssetsWithFieldType, + MutateAdGroupAdResult, + MutateAdGroupAdsRequest, + MutateAdGroupAdsResponse, + RemoveAutomaticallyCreatedAssetsRequest, +) +from .ad_group_asset_service import ( + AdGroupAssetOperation, + MutateAdGroupAssetResult, + MutateAdGroupAssetsRequest, + MutateAdGroupAssetsResponse, +) +from .ad_group_asset_set_service import ( + AdGroupAssetSetOperation, + MutateAdGroupAssetSetResult, + MutateAdGroupAssetSetsRequest, + MutateAdGroupAssetSetsResponse, +) +from .ad_group_bid_modifier_service import ( + AdGroupBidModifierOperation, + MutateAdGroupBidModifierResult, + MutateAdGroupBidModifiersRequest, + MutateAdGroupBidModifiersResponse, +) +from .ad_group_criterion_customizer_service import ( + AdGroupCriterionCustomizerOperation, + MutateAdGroupCriterionCustomizerResult, + MutateAdGroupCriterionCustomizersRequest, + MutateAdGroupCriterionCustomizersResponse, +) +from .ad_group_criterion_label_service import ( + AdGroupCriterionLabelOperation, + MutateAdGroupCriterionLabelResult, + MutateAdGroupCriterionLabelsRequest, + MutateAdGroupCriterionLabelsResponse, +) +from .ad_group_criterion_service import ( + AdGroupCriterionOperation, + MutateAdGroupCriteriaRequest, + MutateAdGroupCriteriaResponse, + MutateAdGroupCriterionResult, +) +from .ad_group_customizer_service import ( + AdGroupCustomizerOperation, + MutateAdGroupCustomizerResult, + MutateAdGroupCustomizersRequest, + MutateAdGroupCustomizersResponse, +) +from .ad_group_label_service import ( + AdGroupLabelOperation, + MutateAdGroupLabelResult, + MutateAdGroupLabelsRequest, + MutateAdGroupLabelsResponse, +) +from .ad_group_service import ( + AdGroupOperation, + MutateAdGroupResult, + MutateAdGroupsRequest, + MutateAdGroupsResponse, +) +from .ad_parameter_service import ( + AdParameterOperation, + MutateAdParameterResult, + MutateAdParametersRequest, + MutateAdParametersResponse, +) +from .ad_service import ( + AdOperation, + MutateAdResult, + MutateAdsRequest, + MutateAdsResponse, +) +from .asset_generation_service import ( + AssetGenerationExistingContext, + FinalUrlImageGenerationInput, + FreeformImageGenerationInput, + GeneratedImage, + GeneratedText, + GenerateImagesRequest, + GenerateImagesResponse, + GenerateTextRequest, + GenerateTextResponse, + ProductRecontextGenerationImageInput, + SourceImage, +) +from .asset_group_asset_service import ( + AssetGroupAssetOperation, + MutateAssetGroupAssetResult, + MutateAssetGroupAssetsRequest, + MutateAssetGroupAssetsResponse, +) +from .asset_group_listing_group_filter_service import ( + AssetGroupListingGroupFilterOperation, + MutateAssetGroupListingGroupFilterResult, + MutateAssetGroupListingGroupFiltersRequest, + MutateAssetGroupListingGroupFiltersResponse, +) +from .asset_group_service import ( + AssetGroupOperation, + MutateAssetGroupResult, + MutateAssetGroupsRequest, + MutateAssetGroupsResponse, +) +from .asset_group_signal_service import ( + AssetGroupSignalOperation, + MutateAssetGroupSignalResult, + MutateAssetGroupSignalsRequest, + MutateAssetGroupSignalsResponse, +) +from .asset_service import ( + AssetOperation, + MutateAssetResult, + MutateAssetsRequest, + MutateAssetsResponse, +) +from .asset_set_asset_service import ( + AssetSetAssetOperation, + MutateAssetSetAssetResult, + MutateAssetSetAssetsRequest, + MutateAssetSetAssetsResponse, +) +from .asset_set_service import ( + AssetSetOperation, + MutateAssetSetResult, + MutateAssetSetsRequest, + MutateAssetSetsResponse, +) +from .audience_insights_service import ( + AudienceCompositionAttribute, + AudienceCompositionAttributeCluster, + AudienceCompositionMetrics, + AudienceCompositionSection, + AudienceInsightsDimensions, + AudienceOverlapItem, + DimensionOverlapResult, + GenerateAudienceCompositionInsightsRequest, + GenerateAudienceCompositionInsightsResponse, + GenerateAudienceDefinitionRequest, + GenerateAudienceDefinitionResponse, + GenerateAudienceOverlapInsightsRequest, + GenerateAudienceOverlapInsightsResponse, + GenerateInsightsFinderReportRequest, + GenerateInsightsFinderReportResponse, + GenerateSuggestedTargetingInsightsRequest, + GenerateSuggestedTargetingInsightsResponse, + GenerateTargetingSuggestionMetricsRequest, + GenerateTargetingSuggestionMetricsResponse, + InsightsAudience, + InsightsAudienceAttributeGroup, + InsightsAudienceDefinition, + InsightsAudienceDescription, + ListAudienceInsightsAttributesRequest, + ListAudienceInsightsAttributesResponse, + ListInsightsEligibleDatesRequest, + ListInsightsEligibleDatesResponse, + TargetingSuggestionMetrics, +) +from .audience_service import ( + AudienceOperation, + MutateAudienceResult, + MutateAudiencesRequest, + MutateAudiencesResponse, +) +from .automatically_created_asset_removal_service import ( + RemoveCampaignAutomaticallyCreatedAssetOperation, + RemoveCampaignAutomaticallyCreatedAssetRequest, + RemoveCampaignAutomaticallyCreatedAssetResponse, +) +from .batch_job_service import ( + AddBatchJobOperationsRequest, + AddBatchJobOperationsResponse, + BatchJobOperation, + BatchJobResult, + ListBatchJobResultsRequest, + ListBatchJobResultsResponse, + MutateBatchJobRequest, + MutateBatchJobResponse, + MutateBatchJobResult, + RunBatchJobRequest, +) +from .benchmarks_service import ( + BenchmarksLocation, + BenchmarksProductMetadata, + BenchmarksSource, + BenchmarksSourceMetadata, + GenerateBenchmarksMetricsRequest, + GenerateBenchmarksMetricsResponse, + IndustryVerticalInfo, + ListBenchmarksAvailableDatesRequest, + ListBenchmarksAvailableDatesResponse, + ListBenchmarksLocationsRequest, + ListBenchmarksLocationsResponse, + ListBenchmarksProductsRequest, + ListBenchmarksProductsResponse, + ListBenchmarksSourcesRequest, + ListBenchmarksSourcesResponse, + Metrics, + ProductFilter, + RateMetrics, +) +from .bidding_data_exclusion_service import ( + BiddingDataExclusionOperation, + MutateBiddingDataExclusionsRequest, + MutateBiddingDataExclusionsResponse, + MutateBiddingDataExclusionsResult, +) +from .bidding_seasonality_adjustment_service import ( + BiddingSeasonalityAdjustmentOperation, + MutateBiddingSeasonalityAdjustmentsRequest, + MutateBiddingSeasonalityAdjustmentsResponse, + MutateBiddingSeasonalityAdjustmentsResult, +) +from .bidding_strategy_service import ( + BiddingStrategyOperation, + MutateBiddingStrategiesRequest, + MutateBiddingStrategiesResponse, + MutateBiddingStrategyResult, +) +from .billing_setup_service import ( + BillingSetupOperation, + MutateBillingSetupRequest, + MutateBillingSetupResponse, + MutateBillingSetupResult, +) +from .brand_suggestion_service import ( + BrandSuggestion, + SuggestBrandsRequest, + SuggestBrandsResponse, +) +from .campaign_asset_service import ( + CampaignAssetOperation, + MutateCampaignAssetResult, + MutateCampaignAssetsRequest, + MutateCampaignAssetsResponse, +) +from .campaign_asset_set_service import ( + CampaignAssetSetOperation, + MutateCampaignAssetSetResult, + MutateCampaignAssetSetsRequest, + MutateCampaignAssetSetsResponse, +) +from .campaign_bid_modifier_service import ( + CampaignBidModifierOperation, + MutateCampaignBidModifierResult, + MutateCampaignBidModifiersRequest, + MutateCampaignBidModifiersResponse, +) +from .campaign_budget_service import ( + CampaignBudgetOperation, + MutateCampaignBudgetResult, + MutateCampaignBudgetsRequest, + MutateCampaignBudgetsResponse, +) +from .campaign_conversion_goal_service import ( + CampaignConversionGoalOperation, + MutateCampaignConversionGoalResult, + MutateCampaignConversionGoalsRequest, + MutateCampaignConversionGoalsResponse, +) +from .campaign_criterion_service import ( + CampaignCriterionOperation, + MutateCampaignCriteriaRequest, + MutateCampaignCriteriaResponse, + MutateCampaignCriterionResult, +) +from .campaign_customizer_service import ( + CampaignCustomizerOperation, + MutateCampaignCustomizerResult, + MutateCampaignCustomizersRequest, + MutateCampaignCustomizersResponse, +) +from .campaign_draft_service import ( + CampaignDraftOperation, + ListCampaignDraftAsyncErrorsRequest, + ListCampaignDraftAsyncErrorsResponse, + MutateCampaignDraftResult, + MutateCampaignDraftsRequest, + MutateCampaignDraftsResponse, + PromoteCampaignDraftRequest, +) +from .campaign_goal_config_service import ( + CampaignGoalConfigOperation, + MutateCampaignGoalConfigResult, + MutateCampaignGoalConfigsRequest, + MutateCampaignGoalConfigsResponse, +) +from .campaign_group_service import ( + CampaignGroupOperation, + MutateCampaignGroupResult, + MutateCampaignGroupsRequest, + MutateCampaignGroupsResponse, +) +from .campaign_label_service import ( + CampaignLabelOperation, + MutateCampaignLabelResult, + MutateCampaignLabelsRequest, + MutateCampaignLabelsResponse, +) +from .campaign_lifecycle_goal_service import ( + CampaignLifecycleGoalOperation, + ConfigureCampaignLifecycleGoalsRequest, + ConfigureCampaignLifecycleGoalsResponse, + ConfigureCampaignLifecycleGoalsResult, +) +from .campaign_service import ( + BrandCampaignAssets, + CampaignOperation, + EnablementResult, + EnableOperation, + EnablePMaxBrandGuidelinesRequest, + EnablePMaxBrandGuidelinesResponse, + MutateCampaignResult, + MutateCampaignsRequest, + MutateCampaignsResponse, +) +from .campaign_shared_set_service import ( + CampaignSharedSetOperation, + MutateCampaignSharedSetResult, + MutateCampaignSharedSetsRequest, + MutateCampaignSharedSetsResponse, +) +from .content_creator_insights_service import ( + GenerateCreatorInsightsRequest, + GenerateCreatorInsightsResponse, + GenerateTrendingInsightsRequest, + GenerateTrendingInsightsResponse, + LanguageDistribution, + SearchAudience, + SearchTopics, + TrendInsight, + TrendInsightMetrics, + YouTubeChannelInsights, + YouTubeCreatorInsights, + YouTubeMetrics, +) +from .conversion_action_service import ( + ConversionActionOperation, + MutateConversionActionResult, + MutateConversionActionsRequest, + MutateConversionActionsResponse, +) +from .conversion_adjustment_upload_service import ( + ConversionAdjustment, + ConversionAdjustmentResult, + GclidDateTimePair, + RestatementValue, + UploadConversionAdjustmentsRequest, + UploadConversionAdjustmentsResponse, +) +from .conversion_custom_variable_service import ( + ConversionCustomVariableOperation, + MutateConversionCustomVariableResult, + MutateConversionCustomVariablesRequest, + MutateConversionCustomVariablesResponse, +) +from .conversion_goal_campaign_config_service import ( + ConversionGoalCampaignConfigOperation, + MutateConversionGoalCampaignConfigResult, + MutateConversionGoalCampaignConfigsRequest, + MutateConversionGoalCampaignConfigsResponse, +) +from .conversion_upload_service import ( + CallConversion, + CallConversionResult, + CartData, + ClickConversion, + ClickConversionResult, + CustomVariable, + ExternalAttributionData, + SessionAttributeKeyValuePair, + SessionAttributesKeyValuePairs, + UploadCallConversionsRequest, + UploadCallConversionsResponse, + UploadClickConversionsRequest, + UploadClickConversionsResponse, +) +from .conversion_value_rule_service import ( + ConversionValueRuleOperation, + MutateConversionValueRuleResult, + MutateConversionValueRulesRequest, + MutateConversionValueRulesResponse, +) +from .conversion_value_rule_set_service import ( + ConversionValueRuleSetOperation, + MutateConversionValueRuleSetResult, + MutateConversionValueRuleSetsRequest, + MutateConversionValueRuleSetsResponse, +) +from .custom_audience_service import ( + CustomAudienceOperation, + MutateCustomAudienceResult, + MutateCustomAudiencesRequest, + MutateCustomAudiencesResponse, +) +from .custom_conversion_goal_service import ( + CustomConversionGoalOperation, + MutateCustomConversionGoalResult, + MutateCustomConversionGoalsRequest, + MutateCustomConversionGoalsResponse, +) +from .custom_interest_service import ( + CustomInterestOperation, + MutateCustomInterestResult, + MutateCustomInterestsRequest, + MutateCustomInterestsResponse, +) +from .customer_asset_service import ( + CustomerAssetOperation, + MutateCustomerAssetResult, + MutateCustomerAssetsRequest, + MutateCustomerAssetsResponse, +) +from .customer_asset_set_service import ( + CustomerAssetSetOperation, + MutateCustomerAssetSetResult, + MutateCustomerAssetSetsRequest, + MutateCustomerAssetSetsResponse, +) +from .customer_client_link_service import ( + CustomerClientLinkOperation, + MutateCustomerClientLinkRequest, + MutateCustomerClientLinkResponse, + MutateCustomerClientLinkResult, +) +from .customer_conversion_goal_service import ( + CustomerConversionGoalOperation, + MutateCustomerConversionGoalResult, + MutateCustomerConversionGoalsRequest, + MutateCustomerConversionGoalsResponse, +) +from .customer_customizer_service import ( + CustomerCustomizerOperation, + MutateCustomerCustomizerResult, + MutateCustomerCustomizersRequest, + MutateCustomerCustomizersResponse, +) +from .customer_label_service import ( + CustomerLabelOperation, + MutateCustomerLabelResult, + MutateCustomerLabelsRequest, + MutateCustomerLabelsResponse, +) +from .customer_lifecycle_goal_service import ( + ConfigureCustomerLifecycleGoalsRequest, + ConfigureCustomerLifecycleGoalsResponse, + ConfigureCustomerLifecycleGoalsResult, + CustomerLifecycleGoalOperation, +) +from .customer_manager_link_service import ( + CustomerManagerLinkOperation, + MoveManagerLinkRequest, + MoveManagerLinkResponse, + MutateCustomerManagerLinkRequest, + MutateCustomerManagerLinkResponse, + MutateCustomerManagerLinkResult, +) +from .customer_negative_criterion_service import ( + CustomerNegativeCriterionOperation, + MutateCustomerNegativeCriteriaRequest, + MutateCustomerNegativeCriteriaResponse, + MutateCustomerNegativeCriteriaResult, +) +from .customer_service import ( + CreateCustomerClientRequest, + CreateCustomerClientResponse, + CustomerOperation, + ListAccessibleCustomersRequest, + ListAccessibleCustomersResponse, + MutateCustomerRequest, + MutateCustomerResponse, + MutateCustomerResult, +) +from .customer_sk_ad_network_conversion_value_schema_service import ( + CustomerSkAdNetworkConversionValueSchemaOperation, + MutateCustomerSkAdNetworkConversionValueSchemaRequest, + MutateCustomerSkAdNetworkConversionValueSchemaResponse, + MutateCustomerSkAdNetworkConversionValueSchemaResult, +) +from .customer_user_access_invitation_service import ( + CustomerUserAccessInvitationOperation, + MutateCustomerUserAccessInvitationRequest, + MutateCustomerUserAccessInvitationResponse, + MutateCustomerUserAccessInvitationResult, +) +from .customer_user_access_service import ( + CustomerUserAccessOperation, + MutateCustomerUserAccessRequest, + MutateCustomerUserAccessResponse, + MutateCustomerUserAccessResult, +) +from .customizer_attribute_service import ( + CustomizerAttributeOperation, + MutateCustomizerAttributeResult, + MutateCustomizerAttributesRequest, + MutateCustomizerAttributesResponse, +) +from .data_link_service import ( + CreateDataLinkRequest, + CreateDataLinkResponse, + RemoveDataLinkRequest, + RemoveDataLinkResponse, + UpdateDataLinkRequest, + UpdateDataLinkResponse, +) +from .experiment_arm_service import ( + ExperimentArmOperation, + MutateExperimentArmResult, + MutateExperimentArmsRequest, + MutateExperimentArmsResponse, +) +from .experiment_service import ( + CampaignBudgetMapping, + EndExperimentRequest, + ExperimentOperation, + GraduateExperimentRequest, + ListExperimentAsyncErrorsRequest, + ListExperimentAsyncErrorsResponse, + MutateExperimentResult, + MutateExperimentsRequest, + MutateExperimentsResponse, + PromoteExperimentMetadata, + PromoteExperimentRequest, + ScheduleExperimentMetadata, + ScheduleExperimentRequest, +) +from .geo_target_constant_service import ( + GeoTargetConstantSuggestion, + SuggestGeoTargetConstantsRequest, + SuggestGeoTargetConstantsResponse, +) +from .goal_service import ( + GoalOperation, + MutateGoalResult, + MutateGoalsRequest, + MutateGoalsResponse, +) +from .google_ads_field_service import ( + GetGoogleAdsFieldRequest, + SearchGoogleAdsFieldsRequest, + SearchGoogleAdsFieldsResponse, +) +from .google_ads_service import ( + GoogleAdsRow, + MetricAttributes, + MutateGoogleAdsRequest, + MutateGoogleAdsResponse, + MutateOperation, + MutateOperationResponse, + SearchGoogleAdsRequest, + SearchGoogleAdsResponse, + SearchGoogleAdsStreamRequest, + SearchGoogleAdsStreamResponse, + SearchSettings, +) +from .identity_verification_service import ( + GetIdentityVerificationRequest, + GetIdentityVerificationResponse, + IdentityVerification, + IdentityVerificationProgress, + IdentityVerificationRequirement, + StartIdentityVerificationRequest, +) +from .incentive_service import ( + ApplyIncentiveRequest, + ApplyIncentiveResponse, + CyoIncentives, + FetchIncentiveRequest, + FetchIncentiveResponse, + Incentive, + IncentiveOffer, +) +from .invoice_service import ( + ListInvoicesRequest, + ListInvoicesResponse, +) +from .keyword_plan_ad_group_keyword_service import ( + KeywordPlanAdGroupKeywordOperation, + MutateKeywordPlanAdGroupKeywordResult, + MutateKeywordPlanAdGroupKeywordsRequest, + MutateKeywordPlanAdGroupKeywordsResponse, +) +from .keyword_plan_ad_group_service import ( + KeywordPlanAdGroupOperation, + MutateKeywordPlanAdGroupResult, + MutateKeywordPlanAdGroupsRequest, + MutateKeywordPlanAdGroupsResponse, +) +from .keyword_plan_campaign_keyword_service import ( + KeywordPlanCampaignKeywordOperation, + MutateKeywordPlanCampaignKeywordResult, + MutateKeywordPlanCampaignKeywordsRequest, + MutateKeywordPlanCampaignKeywordsResponse, +) +from .keyword_plan_campaign_service import ( + KeywordPlanCampaignOperation, + MutateKeywordPlanCampaignResult, + MutateKeywordPlanCampaignsRequest, + MutateKeywordPlanCampaignsResponse, +) +from .keyword_plan_idea_service import ( + AdGroupKeywordSuggestion, + BiddableKeyword, + CampaignToForecast, + CriterionBidModifier, + ForecastAdGroup, + GenerateAdGroupThemesRequest, + GenerateAdGroupThemesResponse, + GenerateKeywordForecastMetricsRequest, + GenerateKeywordForecastMetricsResponse, + GenerateKeywordHistoricalMetricsRequest, + GenerateKeywordHistoricalMetricsResponse, + GenerateKeywordHistoricalMetricsResult, + GenerateKeywordIdeaResponse, + GenerateKeywordIdeaResult, + GenerateKeywordIdeasRequest, + KeywordAndUrlSeed, + KeywordForecastMetrics, + KeywordSeed, + ManualCpcBiddingStrategy, + MaximizeClicksBiddingStrategy, + MaximizeConversionsBiddingStrategy, + SiteSeed, + UnusableAdGroup, + UrlSeed, +) +from .keyword_plan_service import ( + KeywordPlanOperation, + MutateKeywordPlansRequest, + MutateKeywordPlansResponse, + MutateKeywordPlansResult, +) +from .keyword_theme_constant_service import ( + SuggestKeywordThemeConstantsRequest, + SuggestKeywordThemeConstantsResponse, +) +from .label_service import ( + LabelOperation, + MutateLabelResult, + MutateLabelsRequest, + MutateLabelsResponse, +) +from .local_services_lead_service import ( + AppendLeadConversationRequest, + AppendLeadConversationResponse, + Conversation, + ConversationOrError, + ProvideLeadFeedbackRequest, + ProvideLeadFeedbackResponse, + SurveyDissatisfied, + SurveySatisfied, +) +from .offline_user_data_job_service import ( + AddOfflineUserDataJobOperationsRequest, + AddOfflineUserDataJobOperationsResponse, + CreateOfflineUserDataJobRequest, + CreateOfflineUserDataJobResponse, + OfflineUserDataJobOperation, + RunOfflineUserDataJobRequest, +) +from .payments_account_service import ( + ListPaymentsAccountsRequest, + ListPaymentsAccountsResponse, +) +from .product_link_invitation_service import ( + CreateProductLinkInvitationRequest, + CreateProductLinkInvitationResponse, + RemoveProductLinkInvitationRequest, + RemoveProductLinkInvitationResponse, + UpdateProductLinkInvitationRequest, + UpdateProductLinkInvitationResponse, +) +from .product_link_service import ( + CreateProductLinkRequest, + CreateProductLinkResponse, + RemoveProductLinkRequest, + RemoveProductLinkResponse, +) +from .reach_plan_service import ( + AdvancedProductTargeting, + AudienceTargeting, + CampaignDuration, + ConversionRateSuggestion, + EffectiveFrequencyBreakdown, + EffectiveFrequencyLimit, + Forecast, + ForecastMetricOptions, + FrequencyCap, + GenerateConversionRatesRequest, + GenerateConversionRatesResponse, + GenerateReachForecastRequest, + GenerateReachForecastResponse, + ListPlannableLocationsRequest, + ListPlannableLocationsResponse, + ListPlannableProductsRequest, + ListPlannableProductsResponse, + ListPlannableUserInterestsRequest, + ListPlannableUserInterestsResponse, + ListPlannableUserListsRequest, + ListPlannableUserListsResponse, + OnTargetAudienceMetrics, + PlannableLocation, + PlannableTargeting, + PlannableUserInterest, + PlannableUserList, + PlannableUserListMetadata, + PlannedProduct, + PlannedProductForecast, + PlannedProductReachForecast, + ProductMetadata, + ReachCurve, + ReachForecast, + SurfaceTargeting, + SurfaceTargetingCombinations, + TargetFrequencySettings, + Targeting, + YouTubeSelectLineUp, + YouTubeSelectSettings, +) +from .recommendation_service import ( + ApplyRecommendationOperation, + ApplyRecommendationRequest, + ApplyRecommendationResponse, + ApplyRecommendationResult, + DismissRecommendationRequest, + DismissRecommendationResponse, + GenerateRecommendationsRequest, + GenerateRecommendationsResponse, +) +from .recommendation_subscription_service import ( + MutateRecommendationSubscriptionRequest, + MutateRecommendationSubscriptionResponse, + MutateRecommendationSubscriptionResult, + RecommendationSubscriptionOperation, +) +from .remarketing_action_service import ( + MutateRemarketingActionResult, + MutateRemarketingActionsRequest, + MutateRemarketingActionsResponse, + RemarketingActionOperation, +) +from .shareable_preview_service import ( + AssetGroupIdentifier, + GenerateShareablePreviewsRequest, + GenerateShareablePreviewsResponse, + ShareablePreview, + ShareablePreviewOrError, + ShareablePreviewResult, +) +from .shared_criterion_service import ( + MutateSharedCriteriaRequest, + MutateSharedCriteriaResponse, + MutateSharedCriterionResult, + SharedCriterionOperation, +) +from .shared_set_service import ( + MutateSharedSetResult, + MutateSharedSetsRequest, + MutateSharedSetsResponse, + SharedSetOperation, +) +from .smart_campaign_setting_service import ( + GetSmartCampaignStatusRequest, + GetSmartCampaignStatusResponse, + MutateSmartCampaignSettingResult, + MutateSmartCampaignSettingsRequest, + MutateSmartCampaignSettingsResponse, + SmartCampaignEligibleDetails, + SmartCampaignEndedDetails, + SmartCampaignNotEligibleDetails, + SmartCampaignPausedDetails, + SmartCampaignRemovedDetails, + SmartCampaignSettingOperation, +) +from .smart_campaign_suggest_service import ( + SmartCampaignSuggestionInfo, + SuggestKeywordThemesRequest, + SuggestKeywordThemesResponse, + SuggestSmartCampaignAdRequest, + SuggestSmartCampaignAdResponse, + SuggestSmartCampaignBudgetOptionsRequest, + SuggestSmartCampaignBudgetOptionsResponse, +) +from .third_party_app_analytics_link_service import ( + RegenerateShareableLinkIdRequest, + RegenerateShareableLinkIdResponse, +) +from .travel_asset_suggestion_service import ( + HotelAssetSuggestion, + HotelImageAsset, + HotelTextAsset, + SuggestTravelAssetsRequest, + SuggestTravelAssetsResponse, +) +from .user_data_service import ( + UploadUserDataRequest, + UploadUserDataResponse, + UserDataOperation, +) +from .user_list_customer_type_service import ( + MutateUserListCustomerTypeResult, + MutateUserListCustomerTypesRequest, + MutateUserListCustomerTypesResponse, + UserListCustomerTypeOperation, +) +from .user_list_service import ( + MutateUserListResult, + MutateUserListsRequest, + MutateUserListsResponse, + UserListOperation, +) + +__all__ = ( + "AccountBudgetProposalOperation", + "MutateAccountBudgetProposalRequest", + "MutateAccountBudgetProposalResponse", + "MutateAccountBudgetProposalResult", + "AccountLinkOperation", + "CreateAccountLinkRequest", + "CreateAccountLinkResponse", + "MutateAccountLinkRequest", + "MutateAccountLinkResponse", + "MutateAccountLinkResult", + "AdGroupAdLabelOperation", + "MutateAdGroupAdLabelResult", + "MutateAdGroupAdLabelsRequest", + "MutateAdGroupAdLabelsResponse", + "AdGroupAdOperation", + "AssetsWithFieldType", + "MutateAdGroupAdResult", + "MutateAdGroupAdsRequest", + "MutateAdGroupAdsResponse", + "RemoveAutomaticallyCreatedAssetsRequest", + "AdGroupAssetOperation", + "MutateAdGroupAssetResult", + "MutateAdGroupAssetsRequest", + "MutateAdGroupAssetsResponse", + "AdGroupAssetSetOperation", + "MutateAdGroupAssetSetResult", + "MutateAdGroupAssetSetsRequest", + "MutateAdGroupAssetSetsResponse", + "AdGroupBidModifierOperation", + "MutateAdGroupBidModifierResult", + "MutateAdGroupBidModifiersRequest", + "MutateAdGroupBidModifiersResponse", + "AdGroupCriterionCustomizerOperation", + "MutateAdGroupCriterionCustomizerResult", + "MutateAdGroupCriterionCustomizersRequest", + "MutateAdGroupCriterionCustomizersResponse", + "AdGroupCriterionLabelOperation", + "MutateAdGroupCriterionLabelResult", + "MutateAdGroupCriterionLabelsRequest", + "MutateAdGroupCriterionLabelsResponse", + "AdGroupCriterionOperation", + "MutateAdGroupCriteriaRequest", + "MutateAdGroupCriteriaResponse", + "MutateAdGroupCriterionResult", + "AdGroupCustomizerOperation", + "MutateAdGroupCustomizerResult", + "MutateAdGroupCustomizersRequest", + "MutateAdGroupCustomizersResponse", + "AdGroupLabelOperation", + "MutateAdGroupLabelResult", + "MutateAdGroupLabelsRequest", + "MutateAdGroupLabelsResponse", + "AdGroupOperation", + "MutateAdGroupResult", + "MutateAdGroupsRequest", + "MutateAdGroupsResponse", + "AdParameterOperation", + "MutateAdParameterResult", + "MutateAdParametersRequest", + "MutateAdParametersResponse", + "AdOperation", + "MutateAdResult", + "MutateAdsRequest", + "MutateAdsResponse", + "AssetGenerationExistingContext", + "FinalUrlImageGenerationInput", + "FreeformImageGenerationInput", + "GeneratedImage", + "GeneratedText", + "GenerateImagesRequest", + "GenerateImagesResponse", + "GenerateTextRequest", + "GenerateTextResponse", + "ProductRecontextGenerationImageInput", + "SourceImage", + "AssetGroupAssetOperation", + "MutateAssetGroupAssetResult", + "MutateAssetGroupAssetsRequest", + "MutateAssetGroupAssetsResponse", + "AssetGroupListingGroupFilterOperation", + "MutateAssetGroupListingGroupFilterResult", + "MutateAssetGroupListingGroupFiltersRequest", + "MutateAssetGroupListingGroupFiltersResponse", + "AssetGroupOperation", + "MutateAssetGroupResult", + "MutateAssetGroupsRequest", + "MutateAssetGroupsResponse", + "AssetGroupSignalOperation", + "MutateAssetGroupSignalResult", + "MutateAssetGroupSignalsRequest", + "MutateAssetGroupSignalsResponse", + "AssetOperation", + "MutateAssetResult", + "MutateAssetsRequest", + "MutateAssetsResponse", + "AssetSetAssetOperation", + "MutateAssetSetAssetResult", + "MutateAssetSetAssetsRequest", + "MutateAssetSetAssetsResponse", + "AssetSetOperation", + "MutateAssetSetResult", + "MutateAssetSetsRequest", + "MutateAssetSetsResponse", + "AudienceCompositionAttribute", + "AudienceCompositionAttributeCluster", + "AudienceCompositionMetrics", + "AudienceCompositionSection", + "AudienceInsightsDimensions", + "AudienceOverlapItem", + "DimensionOverlapResult", + "GenerateAudienceCompositionInsightsRequest", + "GenerateAudienceCompositionInsightsResponse", + "GenerateAudienceDefinitionRequest", + "GenerateAudienceDefinitionResponse", + "GenerateAudienceOverlapInsightsRequest", + "GenerateAudienceOverlapInsightsResponse", + "GenerateInsightsFinderReportRequest", + "GenerateInsightsFinderReportResponse", + "GenerateSuggestedTargetingInsightsRequest", + "GenerateSuggestedTargetingInsightsResponse", + "GenerateTargetingSuggestionMetricsRequest", + "GenerateTargetingSuggestionMetricsResponse", + "InsightsAudience", + "InsightsAudienceAttributeGroup", + "InsightsAudienceDefinition", + "InsightsAudienceDescription", + "ListAudienceInsightsAttributesRequest", + "ListAudienceInsightsAttributesResponse", + "ListInsightsEligibleDatesRequest", + "ListInsightsEligibleDatesResponse", + "TargetingSuggestionMetrics", + "AudienceOperation", + "MutateAudienceResult", + "MutateAudiencesRequest", + "MutateAudiencesResponse", + "RemoveCampaignAutomaticallyCreatedAssetOperation", + "RemoveCampaignAutomaticallyCreatedAssetRequest", + "RemoveCampaignAutomaticallyCreatedAssetResponse", + "AddBatchJobOperationsRequest", + "AddBatchJobOperationsResponse", + "BatchJobOperation", + "BatchJobResult", + "ListBatchJobResultsRequest", + "ListBatchJobResultsResponse", + "MutateBatchJobRequest", + "MutateBatchJobResponse", + "MutateBatchJobResult", + "RunBatchJobRequest", + "BenchmarksLocation", + "BenchmarksProductMetadata", + "BenchmarksSource", + "BenchmarksSourceMetadata", + "GenerateBenchmarksMetricsRequest", + "GenerateBenchmarksMetricsResponse", + "IndustryVerticalInfo", + "ListBenchmarksAvailableDatesRequest", + "ListBenchmarksAvailableDatesResponse", + "ListBenchmarksLocationsRequest", + "ListBenchmarksLocationsResponse", + "ListBenchmarksProductsRequest", + "ListBenchmarksProductsResponse", + "ListBenchmarksSourcesRequest", + "ListBenchmarksSourcesResponse", + "Metrics", + "ProductFilter", + "RateMetrics", + "BiddingDataExclusionOperation", + "MutateBiddingDataExclusionsRequest", + "MutateBiddingDataExclusionsResponse", + "MutateBiddingDataExclusionsResult", + "BiddingSeasonalityAdjustmentOperation", + "MutateBiddingSeasonalityAdjustmentsRequest", + "MutateBiddingSeasonalityAdjustmentsResponse", + "MutateBiddingSeasonalityAdjustmentsResult", + "BiddingStrategyOperation", + "MutateBiddingStrategiesRequest", + "MutateBiddingStrategiesResponse", + "MutateBiddingStrategyResult", + "BillingSetupOperation", + "MutateBillingSetupRequest", + "MutateBillingSetupResponse", + "MutateBillingSetupResult", + "BrandSuggestion", + "SuggestBrandsRequest", + "SuggestBrandsResponse", + "CampaignAssetOperation", + "MutateCampaignAssetResult", + "MutateCampaignAssetsRequest", + "MutateCampaignAssetsResponse", + "CampaignAssetSetOperation", + "MutateCampaignAssetSetResult", + "MutateCampaignAssetSetsRequest", + "MutateCampaignAssetSetsResponse", + "CampaignBidModifierOperation", + "MutateCampaignBidModifierResult", + "MutateCampaignBidModifiersRequest", + "MutateCampaignBidModifiersResponse", + "CampaignBudgetOperation", + "MutateCampaignBudgetResult", + "MutateCampaignBudgetsRequest", + "MutateCampaignBudgetsResponse", + "CampaignConversionGoalOperation", + "MutateCampaignConversionGoalResult", + "MutateCampaignConversionGoalsRequest", + "MutateCampaignConversionGoalsResponse", + "CampaignCriterionOperation", + "MutateCampaignCriteriaRequest", + "MutateCampaignCriteriaResponse", + "MutateCampaignCriterionResult", + "CampaignCustomizerOperation", + "MutateCampaignCustomizerResult", + "MutateCampaignCustomizersRequest", + "MutateCampaignCustomizersResponse", + "CampaignDraftOperation", + "ListCampaignDraftAsyncErrorsRequest", + "ListCampaignDraftAsyncErrorsResponse", + "MutateCampaignDraftResult", + "MutateCampaignDraftsRequest", + "MutateCampaignDraftsResponse", + "PromoteCampaignDraftRequest", + "CampaignGoalConfigOperation", + "MutateCampaignGoalConfigResult", + "MutateCampaignGoalConfigsRequest", + "MutateCampaignGoalConfigsResponse", + "CampaignGroupOperation", + "MutateCampaignGroupResult", + "MutateCampaignGroupsRequest", + "MutateCampaignGroupsResponse", + "CampaignLabelOperation", + "MutateCampaignLabelResult", + "MutateCampaignLabelsRequest", + "MutateCampaignLabelsResponse", + "CampaignLifecycleGoalOperation", + "ConfigureCampaignLifecycleGoalsRequest", + "ConfigureCampaignLifecycleGoalsResponse", + "ConfigureCampaignLifecycleGoalsResult", + "BrandCampaignAssets", + "CampaignOperation", + "EnablementResult", + "EnableOperation", + "EnablePMaxBrandGuidelinesRequest", + "EnablePMaxBrandGuidelinesResponse", + "MutateCampaignResult", + "MutateCampaignsRequest", + "MutateCampaignsResponse", + "CampaignSharedSetOperation", + "MutateCampaignSharedSetResult", + "MutateCampaignSharedSetsRequest", + "MutateCampaignSharedSetsResponse", + "GenerateCreatorInsightsRequest", + "GenerateCreatorInsightsResponse", + "GenerateTrendingInsightsRequest", + "GenerateTrendingInsightsResponse", + "LanguageDistribution", + "SearchAudience", + "SearchTopics", + "TrendInsight", + "TrendInsightMetrics", + "YouTubeChannelInsights", + "YouTubeCreatorInsights", + "YouTubeMetrics", + "ConversionActionOperation", + "MutateConversionActionResult", + "MutateConversionActionsRequest", + "MutateConversionActionsResponse", + "ConversionAdjustment", + "ConversionAdjustmentResult", + "GclidDateTimePair", + "RestatementValue", + "UploadConversionAdjustmentsRequest", + "UploadConversionAdjustmentsResponse", + "ConversionCustomVariableOperation", + "MutateConversionCustomVariableResult", + "MutateConversionCustomVariablesRequest", + "MutateConversionCustomVariablesResponse", + "ConversionGoalCampaignConfigOperation", + "MutateConversionGoalCampaignConfigResult", + "MutateConversionGoalCampaignConfigsRequest", + "MutateConversionGoalCampaignConfigsResponse", + "CallConversion", + "CallConversionResult", + "CartData", + "ClickConversion", + "ClickConversionResult", + "CustomVariable", + "ExternalAttributionData", + "SessionAttributeKeyValuePair", + "SessionAttributesKeyValuePairs", + "UploadCallConversionsRequest", + "UploadCallConversionsResponse", + "UploadClickConversionsRequest", + "UploadClickConversionsResponse", + "ConversionValueRuleOperation", + "MutateConversionValueRuleResult", + "MutateConversionValueRulesRequest", + "MutateConversionValueRulesResponse", + "ConversionValueRuleSetOperation", + "MutateConversionValueRuleSetResult", + "MutateConversionValueRuleSetsRequest", + "MutateConversionValueRuleSetsResponse", + "CustomAudienceOperation", + "MutateCustomAudienceResult", + "MutateCustomAudiencesRequest", + "MutateCustomAudiencesResponse", + "CustomConversionGoalOperation", + "MutateCustomConversionGoalResult", + "MutateCustomConversionGoalsRequest", + "MutateCustomConversionGoalsResponse", + "CustomInterestOperation", + "MutateCustomInterestResult", + "MutateCustomInterestsRequest", + "MutateCustomInterestsResponse", + "CustomerAssetOperation", + "MutateCustomerAssetResult", + "MutateCustomerAssetsRequest", + "MutateCustomerAssetsResponse", + "CustomerAssetSetOperation", + "MutateCustomerAssetSetResult", + "MutateCustomerAssetSetsRequest", + "MutateCustomerAssetSetsResponse", + "CustomerClientLinkOperation", + "MutateCustomerClientLinkRequest", + "MutateCustomerClientLinkResponse", + "MutateCustomerClientLinkResult", + "CustomerConversionGoalOperation", + "MutateCustomerConversionGoalResult", + "MutateCustomerConversionGoalsRequest", + "MutateCustomerConversionGoalsResponse", + "CustomerCustomizerOperation", + "MutateCustomerCustomizerResult", + "MutateCustomerCustomizersRequest", + "MutateCustomerCustomizersResponse", + "CustomerLabelOperation", + "MutateCustomerLabelResult", + "MutateCustomerLabelsRequest", + "MutateCustomerLabelsResponse", + "ConfigureCustomerLifecycleGoalsRequest", + "ConfigureCustomerLifecycleGoalsResponse", + "ConfigureCustomerLifecycleGoalsResult", + "CustomerLifecycleGoalOperation", + "CustomerManagerLinkOperation", + "MoveManagerLinkRequest", + "MoveManagerLinkResponse", + "MutateCustomerManagerLinkRequest", + "MutateCustomerManagerLinkResponse", + "MutateCustomerManagerLinkResult", + "CustomerNegativeCriterionOperation", + "MutateCustomerNegativeCriteriaRequest", + "MutateCustomerNegativeCriteriaResponse", + "MutateCustomerNegativeCriteriaResult", + "CreateCustomerClientRequest", + "CreateCustomerClientResponse", + "CustomerOperation", + "ListAccessibleCustomersRequest", + "ListAccessibleCustomersResponse", + "MutateCustomerRequest", + "MutateCustomerResponse", + "MutateCustomerResult", + "CustomerSkAdNetworkConversionValueSchemaOperation", + "MutateCustomerSkAdNetworkConversionValueSchemaRequest", + "MutateCustomerSkAdNetworkConversionValueSchemaResponse", + "MutateCustomerSkAdNetworkConversionValueSchemaResult", + "CustomerUserAccessInvitationOperation", + "MutateCustomerUserAccessInvitationRequest", + "MutateCustomerUserAccessInvitationResponse", + "MutateCustomerUserAccessInvitationResult", + "CustomerUserAccessOperation", + "MutateCustomerUserAccessRequest", + "MutateCustomerUserAccessResponse", + "MutateCustomerUserAccessResult", + "CustomizerAttributeOperation", + "MutateCustomizerAttributeResult", + "MutateCustomizerAttributesRequest", + "MutateCustomizerAttributesResponse", + "CreateDataLinkRequest", + "CreateDataLinkResponse", + "RemoveDataLinkRequest", + "RemoveDataLinkResponse", + "UpdateDataLinkRequest", + "UpdateDataLinkResponse", + "ExperimentArmOperation", + "MutateExperimentArmResult", + "MutateExperimentArmsRequest", + "MutateExperimentArmsResponse", + "CampaignBudgetMapping", + "EndExperimentRequest", + "ExperimentOperation", + "GraduateExperimentRequest", + "ListExperimentAsyncErrorsRequest", + "ListExperimentAsyncErrorsResponse", + "MutateExperimentResult", + "MutateExperimentsRequest", + "MutateExperimentsResponse", + "PromoteExperimentMetadata", + "PromoteExperimentRequest", + "ScheduleExperimentMetadata", + "ScheduleExperimentRequest", + "GeoTargetConstantSuggestion", + "SuggestGeoTargetConstantsRequest", + "SuggestGeoTargetConstantsResponse", + "GoalOperation", + "MutateGoalResult", + "MutateGoalsRequest", + "MutateGoalsResponse", + "GetGoogleAdsFieldRequest", + "SearchGoogleAdsFieldsRequest", + "SearchGoogleAdsFieldsResponse", + "GoogleAdsRow", + "MetricAttributes", + "MutateGoogleAdsRequest", + "MutateGoogleAdsResponse", + "MutateOperation", + "MutateOperationResponse", + "SearchGoogleAdsRequest", + "SearchGoogleAdsResponse", + "SearchGoogleAdsStreamRequest", + "SearchGoogleAdsStreamResponse", + "SearchSettings", + "GetIdentityVerificationRequest", + "GetIdentityVerificationResponse", + "IdentityVerification", + "IdentityVerificationProgress", + "IdentityVerificationRequirement", + "StartIdentityVerificationRequest", + "ApplyIncentiveRequest", + "ApplyIncentiveResponse", + "CyoIncentives", + "FetchIncentiveRequest", + "FetchIncentiveResponse", + "Incentive", + "IncentiveOffer", + "ListInvoicesRequest", + "ListInvoicesResponse", + "KeywordPlanAdGroupKeywordOperation", + "MutateKeywordPlanAdGroupKeywordResult", + "MutateKeywordPlanAdGroupKeywordsRequest", + "MutateKeywordPlanAdGroupKeywordsResponse", + "KeywordPlanAdGroupOperation", + "MutateKeywordPlanAdGroupResult", + "MutateKeywordPlanAdGroupsRequest", + "MutateKeywordPlanAdGroupsResponse", + "KeywordPlanCampaignKeywordOperation", + "MutateKeywordPlanCampaignKeywordResult", + "MutateKeywordPlanCampaignKeywordsRequest", + "MutateKeywordPlanCampaignKeywordsResponse", + "KeywordPlanCampaignOperation", + "MutateKeywordPlanCampaignResult", + "MutateKeywordPlanCampaignsRequest", + "MutateKeywordPlanCampaignsResponse", + "AdGroupKeywordSuggestion", + "BiddableKeyword", + "CampaignToForecast", + "CriterionBidModifier", + "ForecastAdGroup", + "GenerateAdGroupThemesRequest", + "GenerateAdGroupThemesResponse", + "GenerateKeywordForecastMetricsRequest", + "GenerateKeywordForecastMetricsResponse", + "GenerateKeywordHistoricalMetricsRequest", + "GenerateKeywordHistoricalMetricsResponse", + "GenerateKeywordHistoricalMetricsResult", + "GenerateKeywordIdeaResponse", + "GenerateKeywordIdeaResult", + "GenerateKeywordIdeasRequest", + "KeywordAndUrlSeed", + "KeywordForecastMetrics", + "KeywordSeed", + "ManualCpcBiddingStrategy", + "MaximizeClicksBiddingStrategy", + "MaximizeConversionsBiddingStrategy", + "SiteSeed", + "UnusableAdGroup", + "UrlSeed", + "KeywordPlanOperation", + "MutateKeywordPlansRequest", + "MutateKeywordPlansResponse", + "MutateKeywordPlansResult", + "SuggestKeywordThemeConstantsRequest", + "SuggestKeywordThemeConstantsResponse", + "LabelOperation", + "MutateLabelResult", + "MutateLabelsRequest", + "MutateLabelsResponse", + "AppendLeadConversationRequest", + "AppendLeadConversationResponse", + "Conversation", + "ConversationOrError", + "ProvideLeadFeedbackRequest", + "ProvideLeadFeedbackResponse", + "SurveyDissatisfied", + "SurveySatisfied", + "AddOfflineUserDataJobOperationsRequest", + "AddOfflineUserDataJobOperationsResponse", + "CreateOfflineUserDataJobRequest", + "CreateOfflineUserDataJobResponse", + "OfflineUserDataJobOperation", + "RunOfflineUserDataJobRequest", + "ListPaymentsAccountsRequest", + "ListPaymentsAccountsResponse", + "CreateProductLinkInvitationRequest", + "CreateProductLinkInvitationResponse", + "RemoveProductLinkInvitationRequest", + "RemoveProductLinkInvitationResponse", + "UpdateProductLinkInvitationRequest", + "UpdateProductLinkInvitationResponse", + "CreateProductLinkRequest", + "CreateProductLinkResponse", + "RemoveProductLinkRequest", + "RemoveProductLinkResponse", + "AdvancedProductTargeting", + "AudienceTargeting", + "CampaignDuration", + "ConversionRateSuggestion", + "EffectiveFrequencyBreakdown", + "EffectiveFrequencyLimit", + "Forecast", + "ForecastMetricOptions", + "FrequencyCap", + "GenerateConversionRatesRequest", + "GenerateConversionRatesResponse", + "GenerateReachForecastRequest", + "GenerateReachForecastResponse", + "ListPlannableLocationsRequest", + "ListPlannableLocationsResponse", + "ListPlannableProductsRequest", + "ListPlannableProductsResponse", + "ListPlannableUserInterestsRequest", + "ListPlannableUserInterestsResponse", + "ListPlannableUserListsRequest", + "ListPlannableUserListsResponse", + "OnTargetAudienceMetrics", + "PlannableLocation", + "PlannableTargeting", + "PlannableUserInterest", + "PlannableUserList", + "PlannableUserListMetadata", + "PlannedProduct", + "PlannedProductForecast", + "PlannedProductReachForecast", + "ProductMetadata", + "ReachCurve", + "ReachForecast", + "SurfaceTargeting", + "SurfaceTargetingCombinations", + "TargetFrequencySettings", + "Targeting", + "YouTubeSelectLineUp", + "YouTubeSelectSettings", + "ApplyRecommendationOperation", + "ApplyRecommendationRequest", + "ApplyRecommendationResponse", + "ApplyRecommendationResult", + "DismissRecommendationRequest", + "DismissRecommendationResponse", + "GenerateRecommendationsRequest", + "GenerateRecommendationsResponse", + "MutateRecommendationSubscriptionRequest", + "MutateRecommendationSubscriptionResponse", + "MutateRecommendationSubscriptionResult", + "RecommendationSubscriptionOperation", + "MutateRemarketingActionResult", + "MutateRemarketingActionsRequest", + "MutateRemarketingActionsResponse", + "RemarketingActionOperation", + "AssetGroupIdentifier", + "GenerateShareablePreviewsRequest", + "GenerateShareablePreviewsResponse", + "ShareablePreview", + "ShareablePreviewOrError", + "ShareablePreviewResult", + "MutateSharedCriteriaRequest", + "MutateSharedCriteriaResponse", + "MutateSharedCriterionResult", + "SharedCriterionOperation", + "MutateSharedSetResult", + "MutateSharedSetsRequest", + "MutateSharedSetsResponse", + "SharedSetOperation", + "GetSmartCampaignStatusRequest", + "GetSmartCampaignStatusResponse", + "MutateSmartCampaignSettingResult", + "MutateSmartCampaignSettingsRequest", + "MutateSmartCampaignSettingsResponse", + "SmartCampaignEligibleDetails", + "SmartCampaignEndedDetails", + "SmartCampaignNotEligibleDetails", + "SmartCampaignPausedDetails", + "SmartCampaignRemovedDetails", + "SmartCampaignSettingOperation", + "SmartCampaignSuggestionInfo", + "SuggestKeywordThemesRequest", + "SuggestKeywordThemesResponse", + "SuggestSmartCampaignAdRequest", + "SuggestSmartCampaignAdResponse", + "SuggestSmartCampaignBudgetOptionsRequest", + "SuggestSmartCampaignBudgetOptionsResponse", + "RegenerateShareableLinkIdRequest", + "RegenerateShareableLinkIdResponse", + "HotelAssetSuggestion", + "HotelImageAsset", + "HotelTextAsset", + "SuggestTravelAssetsRequest", + "SuggestTravelAssetsResponse", + "UploadUserDataRequest", + "UploadUserDataResponse", + "UserDataOperation", + "MutateUserListCustomerTypeResult", + "MutateUserListCustomerTypesRequest", + "MutateUserListCustomerTypesResponse", + "UserListCustomerTypeOperation", + "MutateUserListResult", + "MutateUserListsRequest", + "MutateUserListsResponse", + "UserListOperation", +) diff --git a/google/ads/googleads/v19/services/types/account_budget_proposal_service.py b/google/ads/googleads/v23/services/types/account_budget_proposal_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/account_budget_proposal_service.py rename to google/ads/googleads/v23/services/types/account_budget_proposal_service.py index c178a8346..f65d1e2c7 100644 --- a/google/ads/googleads/v19/services/types/account_budget_proposal_service.py +++ b/google/ads/googleads/v23/services/types/account_budget_proposal_service.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import account_budget_proposal +from google.ads.googleads.v23.resources.types import account_budget_proposal from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAccountBudgetProposalRequest", "AccountBudgetProposalOperation", @@ -36,12 +36,12 @@ class MutateAccountBudgetProposalRequest(proto.Message): r"""Request message for - [AccountBudgetProposalService.MutateAccountBudgetProposal][google.ads.googleads.v19.services.AccountBudgetProposalService.MutateAccountBudgetProposal]. + [AccountBudgetProposalService.MutateAccountBudgetProposal][google.ads.googleads.v23.services.AccountBudgetProposalService.MutateAccountBudgetProposal]. Attributes: customer_id (str): Required. The ID of the customer. - operation (google.ads.googleads.v19.services.types.AccountBudgetProposalOperation): + operation (google.ads.googleads.v23.services.types.AccountBudgetProposalOperation): Required. The operation to perform on an individual account-level budget proposal. validate_only (bool): @@ -86,7 +86,7 @@ class AccountBudgetProposalOperation(proto.Message): Proposals that modify budgets have the 'update' proposal type. Specifying a mask for any other proposal type is considered an error. - create (google.ads.googleads.v19.resources.types.AccountBudgetProposal): + create (google.ads.googleads.v23.resources.types.AccountBudgetProposal): Create operation: A new proposal to create a new budget, edit an existing budget, end an actively running budget, or remove an approved @@ -127,7 +127,7 @@ class MutateAccountBudgetProposalResponse(proto.Message): r"""Response message for account-level budget mutate operations. Attributes: - result (google.ads.googleads.v19.services.types.MutateAccountBudgetProposalResult): + result (google.ads.googleads.v23.services.types.MutateAccountBudgetProposalResult): The result of the mutate. """ diff --git a/google/ads/googleads/v19/services/types/account_link_service.py b/google/ads/googleads/v23/services/types/account_link_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/account_link_service.py rename to google/ads/googleads/v23/services/types/account_link_service.py index fdd0d8c0a..a9c213a39 100644 --- a/google/ads/googleads/v19/services/types/account_link_service.py +++ b/google/ads/googleads/v23/services/types/account_link_service.py @@ -18,7 +18,7 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( account_link as gagr_account_link, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -26,8 +26,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "CreateAccountLinkRequest", "CreateAccountLinkResponse", @@ -41,13 +41,13 @@ class CreateAccountLinkRequest(proto.Message): r"""Request message for - [AccountLinkService.CreateAccountLink][google.ads.googleads.v19.services.AccountLinkService.CreateAccountLink]. + [AccountLinkService.CreateAccountLink][google.ads.googleads.v23.services.AccountLinkService.CreateAccountLink]. Attributes: customer_id (str): Required. The ID of the customer for which the account link is created. - account_link (google.ads.googleads.v19.resources.types.AccountLink): + account_link (google.ads.googleads.v23.resources.types.AccountLink): Required. The account link to be created. """ @@ -64,7 +64,7 @@ class CreateAccountLinkRequest(proto.Message): class CreateAccountLinkResponse(proto.Message): r"""Response message for - [AccountLinkService.CreateAccountLink][google.ads.googleads.v19.services.AccountLinkService.CreateAccountLink]. + [AccountLinkService.CreateAccountLink][google.ads.googleads.v23.services.AccountLinkService.CreateAccountLink]. Attributes: resource_name (str): @@ -80,13 +80,13 @@ class CreateAccountLinkResponse(proto.Message): class MutateAccountLinkRequest(proto.Message): r"""Request message for - [AccountLinkService.MutateAccountLink][google.ads.googleads.v19.services.AccountLinkService.MutateAccountLink]. + [AccountLinkService.MutateAccountLink][google.ads.googleads.v23.services.AccountLinkService.MutateAccountLink]. Attributes: customer_id (str): Required. The ID of the customer being modified. - operation (google.ads.googleads.v19.services.types.AccountLinkOperation): + operation (google.ads.googleads.v23.services.types.AccountLinkOperation): Required. The operation to perform on the link. partial_failure (bool): @@ -133,7 +133,7 @@ class AccountLinkOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - update (google.ads.googleads.v19.resources.types.AccountLink): + update (google.ads.googleads.v23.resources.types.AccountLink): Update operation: The account link is expected to have a valid resource name. @@ -169,7 +169,7 @@ class MutateAccountLinkResponse(proto.Message): r"""Response message for account link mutate. Attributes: - result (google.ads.googleads.v19.services.types.MutateAccountLinkResult): + result (google.ads.googleads.v23.services.types.MutateAccountLinkResult): Result for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial diff --git a/google/ads/googleads/v19/services/types/ad_group_ad_label_service.py b/google/ads/googleads/v23/services/types/ad_group_ad_label_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/ad_group_ad_label_service.py rename to google/ads/googleads/v23/services/types/ad_group_ad_label_service.py index 43ce8632d..875b07810 100644 --- a/google/ads/googleads/v19/services/types/ad_group_ad_label_service.py +++ b/google/ads/googleads/v23/services/types/ad_group_ad_label_service.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import ad_group_ad_label +from google.ads.googleads.v23.resources.types import ad_group_ad_label from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdGroupAdLabelsRequest", "AdGroupAdLabelOperation", @@ -37,13 +37,13 @@ class MutateAdGroupAdLabelsRequest(proto.Message): r"""Request message for - [AdGroupAdLabelService.MutateAdGroupAdLabels][google.ads.googleads.v19.services.AdGroupAdLabelService.MutateAdGroupAdLabels]. + [AdGroupAdLabelService.MutateAdGroupAdLabels][google.ads.googleads.v23.services.AdGroupAdLabelService.MutateAdGroupAdLabels]. Attributes: customer_id (str): Required. ID of the customer whose ad group ad labels are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupAdLabelOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupAdLabelOperation]): Required. The list of operations to perform on ad group ad labels. partial_failure (bool): @@ -89,7 +89,7 @@ class AdGroupAdLabelOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.AdGroupAdLabel): + create (google.ads.googleads.v23.resources.types.AdGroupAdLabel): Create operation: No resource name is expected for the new ad group ad label. @@ -126,7 +126,7 @@ class MutateAdGroupAdLabelsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdGroupAdLabelResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdGroupAdLabelResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/ad_group_ad_service.py b/google/ads/googleads/v23/services/types/ad_group_ad_service.py similarity index 88% rename from google/ads/googleads/v19/services/types/ad_group_ad_service.py rename to google/ads/googleads/v23/services/types/ad_group_ad_service.py index dbd4806be..cf182abe6 100644 --- a/google/ads/googleads/v19/services/types/ad_group_ad_service.py +++ b/google/ads/googleads/v23/services/types/ad_group_ad_service.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import policy -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import policy +from google.ads.googleads.v23.enums.types import ( asset_field_type as gage_asset_field_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_ad as gagr_ad_group_ad, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -34,8 +34,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdGroupAdsRequest", "AdGroupAdOperation", @@ -49,13 +49,13 @@ class MutateAdGroupAdsRequest(proto.Message): r"""Request message for - [AdGroupAdService.MutateAdGroupAds][google.ads.googleads.v19.services.AdGroupAdService.MutateAdGroupAds]. + [AdGroupAdService.MutateAdGroupAds][google.ads.googleads.v23.services.AdGroupAdService.MutateAdGroupAds]. Attributes: customer_id (str): Required. The ID of the customer whose ads are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupAdOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupAdOperation]): Required. The list of operations to perform on individual ads. partial_failure (bool): @@ -67,7 +67,7 @@ class MutateAdGroupAdsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -114,14 +114,14 @@ class AdGroupAdOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - policy_validation_parameter (google.ads.googleads.v19.common.types.PolicyValidationParameter): + policy_validation_parameter (google.ads.googleads.v23.common.types.PolicyValidationParameter): Configuration for how policies are validated. - create (google.ads.googleads.v19.resources.types.AdGroupAd): + create (google.ads.googleads.v23.resources.types.AdGroupAd): Create operation: No resource name is expected for the new ad. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.AdGroupAd): + update (google.ads.googleads.v23.resources.types.AdGroupAd): Update operation: The ad is expected to have a valid resource name. @@ -174,7 +174,7 @@ class MutateAdGroupAdsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdGroupAdResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdGroupAdResult]): All results for the mutate. """ @@ -197,7 +197,7 @@ class MutateAdGroupAdResult(proto.Message): resource_name (str): The resource name returned for successful operations. - ad_group_ad (google.ads.googleads.v19.resources.types.AdGroupAd): + ad_group_ad (google.ads.googleads.v23.resources.types.AdGroupAd): The mutated ad group ad with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". @@ -216,14 +216,14 @@ class MutateAdGroupAdResult(proto.Message): class RemoveAutomaticallyCreatedAssetsRequest(proto.Message): r"""Request message for - [AdGroupAdService.RemoveAutomaticallyCreatedAssetsRequest][]. + [AdGroupAdService.RemoveAutomaticallyCreatedAssets][google.ads.googleads.v23.services.AdGroupAdService.RemoveAutomaticallyCreatedAssets]. Attributes: ad_group_ad (str): Required. The resource name of the AdGroupAd from which to remove automatically created assets. - assets_with_field_type (MutableSequence[google.ads.googleads.v19.services.types.AssetsWithFieldType]): + assets_with_field_type (MutableSequence[google.ads.googleads.v23.services.types.AssetsWithFieldType]): Required. List of assets with field type to be removed from the AdGroupAd. """ @@ -248,7 +248,7 @@ class AssetsWithFieldType(proto.Message): asset (str): Required. The resource name of the asset to be removed. - asset_field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + asset_field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): Required. The asset field type. """ diff --git a/google/ads/googleads/v19/services/types/ad_group_asset_service.py b/google/ads/googleads/v23/services/types/ad_group_asset_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/ad_group_asset_service.py rename to google/ads/googleads/v23/services/types/ad_group_asset_service.py index e2e53a235..6af6f103e 100644 --- a/google/ads/googleads/v19/services/types/ad_group_asset_service.py +++ b/google/ads/googleads/v23/services/types/ad_group_asset_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_asset as gagr_ad_group_asset, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdGroupAssetsRequest", "AdGroupAssetOperation", @@ -43,13 +43,13 @@ class MutateAdGroupAssetsRequest(proto.Message): r"""Request message for - [AdGroupAssetService.MutateAdGroupAssets][google.ads.googleads.v19.services.AdGroupAssetService.MutateAdGroupAssets]. + [AdGroupAssetService.MutateAdGroupAssets][google.ads.googleads.v23.services.AdGroupAssetService.MutateAdGroupAssets]. Attributes: customer_id (str): Required. The ID of the customer whose ad group assets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupAssetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupAssetOperation]): Required. The list of operations to perform on individual ad group assets. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateAdGroupAssetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -108,12 +108,12 @@ class AdGroupAssetOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.AdGroupAsset): + create (google.ads.googleads.v23.resources.types.AdGroupAsset): Create operation: No resource name is expected for the new ad group asset. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.AdGroupAsset): + update (google.ads.googleads.v23.resources.types.AdGroupAsset): Update operation: The ad group asset is expected to have a valid resource name. @@ -161,7 +161,7 @@ class MutateAdGroupAssetsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdGroupAssetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdGroupAssetResult]): All results for the mutate. """ @@ -183,7 +183,7 @@ class MutateAdGroupAssetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - ad_group_asset (google.ads.googleads.v19.resources.types.AdGroupAsset): + ad_group_asset (google.ads.googleads.v23.resources.types.AdGroupAsset): The mutated ad group asset with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/ad_group_asset_set_service.py b/google/ads/googleads/v23/services/types/ad_group_asset_set_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/ad_group_asset_set_service.py rename to google/ads/googleads/v23/services/types/ad_group_asset_set_service.py index 144f2b471..06e46d591 100644 --- a/google/ads/googleads/v19/services/types/ad_group_asset_set_service.py +++ b/google/ads/googleads/v23/services/types/ad_group_asset_set_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_asset_set as gagr_ad_group_asset_set, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdGroupAssetSetsRequest", "AdGroupAssetSetOperation", @@ -42,13 +42,13 @@ class MutateAdGroupAssetSetsRequest(proto.Message): r"""Request message for - [AdGroupAssetSetService.MutateAdGroupAssetSets][google.ads.googleads.v19.services.AdGroupAssetSetService.MutateAdGroupAssetSets]. + [AdGroupAssetSetService.MutateAdGroupAssetSets][google.ads.googleads.v23.services.AdGroupAssetSetService.MutateAdGroupAssetSets]. Attributes: customer_id (str): Required. The ID of the customer whose ad group asset sets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupAssetSetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupAssetSetOperation]): Required. The list of operations to perform on individual ad group asset sets. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateAdGroupAssetSetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -105,7 +105,7 @@ class AdGroupAssetSetOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.AdGroupAssetSet): + create (google.ads.googleads.v23.resources.types.AdGroupAssetSet): Create operation: No resource name is expected for the new ad group asset set. @@ -135,7 +135,7 @@ class MutateAdGroupAssetSetsResponse(proto.Message): r"""Response message for an ad group asset set mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdGroupAssetSetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdGroupAssetSetResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -165,7 +165,7 @@ class MutateAdGroupAssetSetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - ad_group_asset_set (google.ads.googleads.v19.resources.types.AdGroupAssetSet): + ad_group_asset_set (google.ads.googleads.v23.resources.types.AdGroupAssetSet): The mutated ad group asset set with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/ad_group_bid_modifier_service.py b/google/ads/googleads/v23/services/types/ad_group_bid_modifier_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/ad_group_bid_modifier_service.py rename to google/ads/googleads/v23/services/types/ad_group_bid_modifier_service.py index 0f28bc176..740ab0ae0 100644 --- a/google/ads/googleads/v19/services/types/ad_group_bid_modifier_service.py +++ b/google/ads/googleads/v23/services/types/ad_group_bid_modifier_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_bid_modifier as gagr_ad_group_bid_modifier, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdGroupBidModifiersRequest", "AdGroupBidModifierOperation", @@ -43,13 +43,13 @@ class MutateAdGroupBidModifiersRequest(proto.Message): r"""Request message for - [AdGroupBidModifierService.MutateAdGroupBidModifiers][google.ads.googleads.v19.services.AdGroupBidModifierService.MutateAdGroupBidModifiers]. + [AdGroupBidModifierService.MutateAdGroupBidModifiers][google.ads.googleads.v23.services.AdGroupBidModifierService.MutateAdGroupBidModifiers]. Attributes: customer_id (str): Required. ID of the customer whose ad group bid modifiers are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupBidModifierOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupBidModifierOperation]): Required. The list of operations to perform on individual ad group bid modifiers. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateAdGroupBidModifiersRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class AdGroupBidModifierOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.AdGroupBidModifier): + create (google.ads.googleads.v23.resources.types.AdGroupBidModifier): Create operation: No resource name is expected for the new ad group bid modifier. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.AdGroupBidModifier): + update (google.ads.googleads.v23.resources.types.AdGroupBidModifier): Update operation: The ad group bid modifier is expected to have a valid resource name. @@ -163,7 +163,7 @@ class MutateAdGroupBidModifiersResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdGroupBidModifierResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdGroupBidModifierResult]): All results for the mutate. """ @@ -187,7 +187,7 @@ class MutateAdGroupBidModifierResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - ad_group_bid_modifier (google.ads.googleads.v19.resources.types.AdGroupBidModifier): + ad_group_bid_modifier (google.ads.googleads.v23.resources.types.AdGroupBidModifier): The mutated ad group bid modifier with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/ad_group_criterion_customizer_service.py b/google/ads/googleads/v23/services/types/ad_group_criterion_customizer_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/ad_group_criterion_customizer_service.py rename to google/ads/googleads/v23/services/types/ad_group_criterion_customizer_service.py index 47d12b662..a1f511f94 100644 --- a/google/ads/googleads/v19/services/types/ad_group_criterion_customizer_service.py +++ b/google/ads/googleads/v23/services/types/ad_group_criterion_customizer_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_criterion_customizer as gagr_ad_group_criterion_customizer, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdGroupCriterionCustomizersRequest", "AdGroupCriterionCustomizerOperation", @@ -42,13 +42,13 @@ class MutateAdGroupCriterionCustomizersRequest(proto.Message): r"""Request message for - [AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers][google.ads.googleads.v19.services.AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers]. + [AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers][google.ads.googleads.v23.services.AdGroupCriterionCustomizerService.MutateAdGroupCriterionCustomizers]. Attributes: customer_id (str): Required. The ID of the customer whose ad group criterion customizers are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupCriterionCustomizerOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupCriterionCustomizerOperation]): Required. The list of operations to perform on individual ad group criterion customizers. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateAdGroupCriterionCustomizersRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -106,7 +106,7 @@ class AdGroupCriterionCustomizerOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.AdGroupCriterionCustomizer): + create (google.ads.googleads.v23.resources.types.AdGroupCriterionCustomizer): Create operation: No resource name is expected for the new ad group criterion customizer. @@ -140,7 +140,7 @@ class MutateAdGroupCriterionCustomizersResponse(proto.Message): r"""Response message for an ad group criterion customizer mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdGroupCriterionCustomizerResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdGroupCriterionCustomizerResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -170,7 +170,7 @@ class MutateAdGroupCriterionCustomizerResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - ad_group_criterion_customizer (google.ads.googleads.v19.resources.types.AdGroupCriterionCustomizer): + ad_group_criterion_customizer (google.ads.googleads.v23.resources.types.AdGroupCriterionCustomizer): The mutated AdGroupCriterionCustomizer with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/ad_group_criterion_label_service.py b/google/ads/googleads/v23/services/types/ad_group_criterion_label_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/ad_group_criterion_label_service.py rename to google/ads/googleads/v23/services/types/ad_group_criterion_label_service.py index 24e407474..ba3bb38fb 100644 --- a/google/ads/googleads/v19/services/types/ad_group_criterion_label_service.py +++ b/google/ads/googleads/v23/services/types/ad_group_criterion_label_service.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import ad_group_criterion_label +from google.ads.googleads.v23.resources.types import ad_group_criterion_label from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdGroupCriterionLabelsRequest", "AdGroupCriterionLabelOperation", @@ -37,13 +37,13 @@ class MutateAdGroupCriterionLabelsRequest(proto.Message): r"""Request message for - [AdGroupCriterionLabelService.MutateAdGroupCriterionLabels][google.ads.googleads.v19.services.AdGroupCriterionLabelService.MutateAdGroupCriterionLabels]. + [AdGroupCriterionLabelService.MutateAdGroupCriterionLabels][google.ads.googleads.v23.services.AdGroupCriterionLabelService.MutateAdGroupCriterionLabels]. Attributes: customer_id (str): Required. ID of the customer whose ad group criterion labels are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupCriterionLabelOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupCriterionLabelOperation]): Required. The list of operations to perform on ad group criterion labels. partial_failure (bool): @@ -90,7 +90,7 @@ class AdGroupCriterionLabelOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.AdGroupCriterionLabel): + create (google.ads.googleads.v23.resources.types.AdGroupCriterionLabel): Create operation: No resource name is expected for the new ad group label. @@ -127,7 +127,7 @@ class MutateAdGroupCriterionLabelsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdGroupCriterionLabelResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdGroupCriterionLabelResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/ad_group_criterion_service.py b/google/ads/googleads/v23/services/types/ad_group_criterion_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/ad_group_criterion_service.py rename to google/ads/googleads/v23/services/types/ad_group_criterion_service.py index 3e22cfeb9..8b133e932 100644 --- a/google/ads/googleads/v19/services/types/ad_group_criterion_service.py +++ b/google/ads/googleads/v23/services/types/ad_group_criterion_service.py @@ -19,11 +19,11 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import policy -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import policy +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_criterion as gagr_ad_group_criterion, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -31,8 +31,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdGroupCriteriaRequest", "AdGroupCriterionOperation", @@ -44,13 +44,13 @@ class MutateAdGroupCriteriaRequest(proto.Message): r"""Request message for - [AdGroupCriterionService.MutateAdGroupCriteria][google.ads.googleads.v19.services.AdGroupCriterionService.MutateAdGroupCriteria]. + [AdGroupCriterionService.MutateAdGroupCriteria][google.ads.googleads.v23.services.AdGroupCriterionService.MutateAdGroupCriteria]. Attributes: customer_id (str): Required. ID of the customer whose criteria are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupCriterionOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupCriterionOperation]): Required. The list of operations to perform on individual criteria. partial_failure (bool): @@ -62,7 +62,7 @@ class MutateAdGroupCriteriaRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -111,7 +111,7 @@ class AdGroupCriterionOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - exempt_policy_violation_keys (MutableSequence[google.ads.googleads.v19.common.types.PolicyViolationKey]): + exempt_policy_violation_keys (MutableSequence[google.ads.googleads.v23.common.types.PolicyViolationKey]): The list of policy violation keys that should not cause a PolicyViolationError to be reported. Not all policy violations are exemptable, refer to the is_exemptible field @@ -121,12 +121,12 @@ class AdGroupCriterionOperation(proto.Message): not be eligible to serve. They may begin serving at a later time due to a change in policies, re-review of the resource, or a change in advertiser certificates. - create (google.ads.googleads.v19.resources.types.AdGroupCriterion): + create (google.ads.googleads.v23.resources.types.AdGroupCriterion): Create operation: No resource name is expected for the new criterion. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.AdGroupCriterion): + update (google.ads.googleads.v23.resources.types.AdGroupCriterion): Update operation: The criterion is expected to have a valid resource name. @@ -181,7 +181,7 @@ class MutateAdGroupCriteriaResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdGroupCriterionResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdGroupCriterionResult]): All results for the mutate. """ @@ -205,7 +205,7 @@ class MutateAdGroupCriterionResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - ad_group_criterion (google.ads.googleads.v19.resources.types.AdGroupCriterion): + ad_group_criterion (google.ads.googleads.v23.resources.types.AdGroupCriterion): The mutated ad group criterion with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/ad_group_customizer_service.py b/google/ads/googleads/v23/services/types/ad_group_customizer_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/ad_group_customizer_service.py rename to google/ads/googleads/v23/services/types/ad_group_customizer_service.py index 7578badcc..21baa7ae3 100644 --- a/google/ads/googleads/v19/services/types/ad_group_customizer_service.py +++ b/google/ads/googleads/v23/services/types/ad_group_customizer_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_customizer as gagr_ad_group_customizer, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdGroupCustomizersRequest", "AdGroupCustomizerOperation", @@ -42,13 +42,13 @@ class MutateAdGroupCustomizersRequest(proto.Message): r"""Request message for - [AdGroupCustomizerService.MutateAdGroupCustomizers][google.ads.googleads.v19.services.AdGroupCustomizerService.MutateAdGroupCustomizers]. + [AdGroupCustomizerService.MutateAdGroupCustomizers][google.ads.googleads.v23.services.AdGroupCustomizerService.MutateAdGroupCustomizers]. Attributes: customer_id (str): Required. The ID of the customer whose ad group customizers are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupCustomizerOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupCustomizerOperation]): Required. The list of operations to perform on individual ad group customizers. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateAdGroupCustomizersRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -106,7 +106,7 @@ class AdGroupCustomizerOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.AdGroupCustomizer): + create (google.ads.googleads.v23.resources.types.AdGroupCustomizer): Create operation: No resource name is expected for the new ad group customizer @@ -136,7 +136,7 @@ class MutateAdGroupCustomizersResponse(proto.Message): r"""Response message for an ad group customizer mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdGroupCustomizerResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdGroupCustomizerResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -166,7 +166,7 @@ class MutateAdGroupCustomizerResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - ad_group_customizer (google.ads.googleads.v19.resources.types.AdGroupCustomizer): + ad_group_customizer (google.ads.googleads.v23.resources.types.AdGroupCustomizer): The mutated AdGroupCustomizer with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/ad_group_label_service.py b/google/ads/googleads/v23/services/types/ad_group_label_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/ad_group_label_service.py rename to google/ads/googleads/v23/services/types/ad_group_label_service.py index 61473cfdc..7e7f4e797 100644 --- a/google/ads/googleads/v19/services/types/ad_group_label_service.py +++ b/google/ads/googleads/v23/services/types/ad_group_label_service.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import ad_group_label +from google.ads.googleads.v23.resources.types import ad_group_label from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdGroupLabelsRequest", "AdGroupLabelOperation", @@ -37,13 +37,13 @@ class MutateAdGroupLabelsRequest(proto.Message): r"""Request message for - [AdGroupLabelService.MutateAdGroupLabels][google.ads.googleads.v19.services.AdGroupLabelService.MutateAdGroupLabels]. + [AdGroupLabelService.MutateAdGroupLabels][google.ads.googleads.v23.services.AdGroupLabelService.MutateAdGroupLabels]. Attributes: customer_id (str): Required. ID of the customer whose ad group labels are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupLabelOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupLabelOperation]): Required. The list of operations to perform on ad group labels. partial_failure (bool): @@ -87,7 +87,7 @@ class AdGroupLabelOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.AdGroupLabel): + create (google.ads.googleads.v23.resources.types.AdGroupLabel): Create operation: No resource name is expected for the new ad group label. @@ -124,7 +124,7 @@ class MutateAdGroupLabelsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdGroupLabelResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdGroupLabelResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/ad_group_service.py b/google/ads/googleads/v23/services/types/ad_group_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/ad_group_service.py rename to google/ads/googleads/v23/services/types/ad_group_service.py index 80e00b6b7..a2c432747 100644 --- a/google/ads/googleads/v19/services/types/ad_group_service.py +++ b/google/ads/googleads/v23/services/types/ad_group_service.py @@ -19,17 +19,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ad_group as gagr_ad_group +from google.ads.googleads.v23.resources.types import ad_group as gagr_ad_group from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdGroupsRequest", "AdGroupOperation", @@ -41,13 +41,13 @@ class MutateAdGroupsRequest(proto.Message): r"""Request message for - [AdGroupService.MutateAdGroups][google.ads.googleads.v19.services.AdGroupService.MutateAdGroups]. + [AdGroupService.MutateAdGroups][google.ads.googleads.v23.services.AdGroupService.MutateAdGroups]. Attributes: customer_id (str): Required. The ID of the customer whose ad groups are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdGroupOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdGroupOperation]): Required. The list of operations to perform on individual ad groups. partial_failure (bool): @@ -59,7 +59,7 @@ class MutateAdGroupsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -105,12 +105,12 @@ class AdGroupOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.AdGroup): + create (google.ads.googleads.v23.resources.types.AdGroup): Create operation: No resource name is expected for the new ad group. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.AdGroup): + update (google.ads.googleads.v23.resources.types.AdGroup): Update operation: The ad group is expected to have a valid resource name. @@ -158,7 +158,7 @@ class MutateAdGroupsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdGroupResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdGroupResult]): All results for the mutate. """ @@ -180,7 +180,7 @@ class MutateAdGroupResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - ad_group (google.ads.googleads.v19.resources.types.AdGroup): + ad_group (google.ads.googleads.v23.resources.types.AdGroup): The mutated ad group with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/ad_parameter_service.py b/google/ads/googleads/v23/services/types/ad_parameter_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/ad_parameter_service.py rename to google/ads/googleads/v23/services/types/ad_parameter_service.py index 91faf6785..f4dc8e192 100644 --- a/google/ads/googleads/v19/services/types/ad_parameter_service.py +++ b/google/ads/googleads/v23/services/types/ad_parameter_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_parameter as gagr_ad_parameter, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdParametersRequest", "AdParameterOperation", @@ -43,13 +43,13 @@ class MutateAdParametersRequest(proto.Message): r"""Request message for - [AdParameterService.MutateAdParameters][google.ads.googleads.v19.services.AdParameterService.MutateAdParameters] + [AdParameterService.MutateAdParameters][google.ads.googleads.v23.services.AdParameterService.MutateAdParameters] Attributes: customer_id (str): Required. The ID of the customer whose ad parameters are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdParameterOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdParameterOperation]): Required. The list of operations to perform on individual ad parameters. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateAdParametersRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -107,12 +107,12 @@ class AdParameterOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.AdParameter): + create (google.ads.googleads.v23.resources.types.AdParameter): Create operation: No resource name is expected for the new ad parameter. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.AdParameter): + update (google.ads.googleads.v23.resources.types.AdParameter): Update operation: The ad parameter is expected to have a valid resource name. @@ -160,7 +160,7 @@ class MutateAdParametersResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdParameterResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdParameterResult]): All results for the mutate. """ @@ -183,7 +183,7 @@ class MutateAdParameterResult(proto.Message): resource_name (str): The resource name returned for successful operations. - ad_parameter (google.ads.googleads.v19.resources.types.AdParameter): + ad_parameter (google.ads.googleads.v23.resources.types.AdParameter): The mutated AdParameter with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/ad_service.py b/google/ads/googleads/v23/services/types/ad_service.py similarity index 88% rename from google/ads/googleads/v19/services/types/ad_service.py rename to google/ads/googleads/v23/services/types/ad_service.py index 6320d0390..6b8e46be5 100644 --- a/google/ads/googleads/v19/services/types/ad_service.py +++ b/google/ads/googleads/v23/services/types/ad_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import policy -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import policy +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ad as gagr_ad +from google.ads.googleads.v23.resources.types import ad as gagr_ad from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAdsRequest", "AdOperation", @@ -42,13 +42,13 @@ class MutateAdsRequest(proto.Message): r"""Request message for - [AdService.MutateAds][google.ads.googleads.v19.services.AdService.MutateAds]. + [AdService.MutateAds][google.ads.googleads.v23.services.AdService.MutateAds]. Attributes: customer_id (str): Required. The ID of the customer whose ads are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AdOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AdOperation]): Required. The list of operations to perform on individual ads. partial_failure (bool): @@ -57,7 +57,7 @@ class MutateAdsRequest(proto.Message): errors. If false, all operations will be carried out in one transaction if and only if they are all valid. Default is false. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -101,9 +101,9 @@ class AdOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - policy_validation_parameter (google.ads.googleads.v19.common.types.PolicyValidationParameter): + policy_validation_parameter (google.ads.googleads.v23.common.types.PolicyValidationParameter): Configuration for how policies are validated. - update (google.ads.googleads.v19.resources.types.Ad): + update (google.ads.googleads.v23.resources.types.Ad): Update operation: The ad is expected to have a valid resource name in this format: @@ -140,7 +140,7 @@ class MutateAdsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAdResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAdResult]): All results for the mutate. """ @@ -163,7 +163,7 @@ class MutateAdResult(proto.Message): resource_name (str): The resource name returned for successful operations. - ad (google.ads.googleads.v19.resources.types.Ad): + ad (google.ads.googleads.v23.resources.types.Ad): The mutated ad with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v23/services/types/asset_generation_service.py b/google/ads/googleads/v23/services/types/asset_generation_service.py new file mode 100644 index 000000000..33f4cc9a5 --- /dev/null +++ b/google/ads/googleads/v23/services/types/asset_generation_service.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.enums.types import ( + advertising_channel_type as gage_advertising_channel_type, +) +from google.ads.googleads.v23.enums.types import ( + asset_field_type as gage_asset_field_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", + manifest={ + "GenerateTextRequest", + "GenerateTextResponse", + "GeneratedText", + "GenerateImagesRequest", + "FinalUrlImageGenerationInput", + "FreeformImageGenerationInput", + "ProductRecontextGenerationImageInput", + "GenerateImagesResponse", + "SourceImage", + "GeneratedImage", + "AssetGenerationExistingContext", + }, +) + + +class GenerateTextRequest(proto.Message): + r"""Request message for + [AssetGenerationService.GenerateText][google.ads.googleads.v23.services.AssetGenerationService.GenerateText] + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + Required. The ID of the customer to generate + assets for. Required. + asset_field_types (MutableSequence[google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType]): + Required. Which field types text is being generated for. + Supported values are: HEADLINE, LONG_HEADLINE, DESCRIPTION. + Required. + final_url (str): + Optional. Final url to use as a source for generating + assets. Required if existing_generation_context is not + provided or does not have a final url associated with it. + freeform_prompt (str): + Optional. A freeform description of what + assets should be generated. The string length + must be between 1 and 1500, inclusive. + keywords (MutableSequence[str]): + Optional. A freeform list of keywords that + are relevant, used to inform asset generation. + existing_generation_context (google.ads.googleads.v23.services.types.AssetGenerationExistingContext): + Optional. The setting for which assets are + being generated, such as an existing AssetGroup + or AdGroupAd. + + This field is a member of `oneof`_ ``context``. + advertising_channel_type (google.ads.googleads.v23.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): + Optional. The advertising channel for which to generate + assets. Required if existing_context is not provided. + + Supported channel types: SEARCH, PERFORMANCE_MAX, DISPLAY, + and DEMAND_GEN + + This field is a member of `oneof`_ ``context``. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + asset_field_types: MutableSequence[ + gage_asset_field_type.AssetFieldTypeEnum.AssetFieldType + ] = proto.RepeatedField( + proto.ENUM, + number=2, + enum=gage_asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + final_url: str = proto.Field( + proto.STRING, + number=5, + ) + freeform_prompt: str = proto.Field( + proto.STRING, + number=6, + ) + keywords: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + existing_generation_context: "AssetGenerationExistingContext" = proto.Field( + proto.MESSAGE, + number=3, + oneof="context", + message="AssetGenerationExistingContext", + ) + advertising_channel_type: ( + gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType + ) = proto.Field( + proto.ENUM, + number=4, + oneof="context", + enum=gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType, + ) + + +class GenerateTextResponse(proto.Message): + r"""Response message for + [AssetGenerationService.GenerateText][google.ads.googleads.v23.services.AssetGenerationService.GenerateText] + + Attributes: + generated_text (MutableSequence[google.ads.googleads.v23.services.types.GeneratedText]): + List of text that was generated and the field + type to use it as. + """ + + generated_text: MutableSequence["GeneratedText"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GeneratedText", + ) + + +class GeneratedText(proto.Message): + r"""Data and metadata about a piece of generated text. + + Attributes: + text (str): + A string of text that was generated. + asset_field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): + The type of asset this text is intended to be + used as. + """ + + text: str = proto.Field( + proto.STRING, + number=1, + ) + asset_field_type: ( + gage_asset_field_type.AssetFieldTypeEnum.AssetFieldType + ) = proto.Field( + proto.ENUM, + number=2, + enum=gage_asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + + +class GenerateImagesRequest(proto.Message): + r"""Request message for + [AssetGenerationService.GenerateImages][google.ads.googleads.v23.services.AssetGenerationService.GenerateImages] + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + Required. The ID of the customer for whom the + images are being generated. Required. + asset_field_types (MutableSequence[google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType]): + Optional. Output field types for generated images. Supported + values are MARKETING_IMAGE, SQUARE_MARKETING_IMAGE, + PORTRAIT_MARKETING_IMAGE, and TALL_PORTRAIT_MARKETING_IMAGE. + All specified field types must be compatible with the + ``advertising_channel_type`` or + ``existing_generation_context`` (whichever is set). If no + field types are provided, images will be generated for all + compatible field types. + advertising_channel_type (google.ads.googleads.v23.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): + Optional. The advertising channel type for which the images + are being generated. This field is required if + ``existing_generation_context`` is not provided. Supported + channel types include SEARCH, PERFORMANCE_MAX, DISPLAY, and + DEMAND_GEN. + + This field is a member of `oneof`_ ``context``. + final_url_generation (google.ads.googleads.v23.services.types.FinalUrlImageGenerationInput): + Optional. Generate images from a final url. + + This field is a member of `oneof`_ ``generation_type``. + freeform_generation (google.ads.googleads.v23.services.types.FreeformImageGenerationInput): + Optional. Generate images from a freeform + prompt. + + This field is a member of `oneof`_ ``generation_type``. + product_recontext_generation (google.ads.googleads.v23.services.types.ProductRecontextGenerationImageInput): + Optional. Generate new images by + recontextualizing existing product images. + + This field is a member of `oneof`_ ``generation_type``. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + asset_field_types: MutableSequence[ + gage_asset_field_type.AssetFieldTypeEnum.AssetFieldType + ] = proto.RepeatedField( + proto.ENUM, + number=4, + enum=gage_asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + advertising_channel_type: ( + gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType + ) = proto.Field( + proto.ENUM, + number=2, + oneof="context", + enum=gage_advertising_channel_type.AdvertisingChannelTypeEnum.AdvertisingChannelType, + ) + final_url_generation: "FinalUrlImageGenerationInput" = proto.Field( + proto.MESSAGE, + number=5, + oneof="generation_type", + message="FinalUrlImageGenerationInput", + ) + freeform_generation: "FreeformImageGenerationInput" = proto.Field( + proto.MESSAGE, + number=6, + oneof="generation_type", + message="FreeformImageGenerationInput", + ) + product_recontext_generation: "ProductRecontextGenerationImageInput" = ( + proto.Field( + proto.MESSAGE, + number=7, + oneof="generation_type", + message="ProductRecontextGenerationImageInput", + ) + ) + + +class FinalUrlImageGenerationInput(proto.Message): + r"""Input for guiding image asset generation with a final url. + + Attributes: + final_url (str): + Required. A final url to guide the image + generation process. Required. + """ + + final_url: str = proto.Field( + proto.STRING, + number=1, + ) + + +class FreeformImageGenerationInput(proto.Message): + r"""Input for guiding image asset generation with a freeform + prompt. + + Attributes: + freeform_prompt (str): + Required. A freeform text description to + guide the image generation process. The maximum + length is 1500 characters. Required. + """ + + freeform_prompt: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ProductRecontextGenerationImageInput(proto.Message): + r"""Input for generating new images by recontextualizing existing + product images. + + Attributes: + prompt (str): + Optional. A freeform description of the + assets to be generated. Maximum character limit + is 1500. + source_images (MutableSequence[google.ads.googleads.v23.services.types.SourceImage]): + Required. Product images to use for + generating new images. 1-3 images must be + provided. + """ + + prompt: str = proto.Field( + proto.STRING, + number=1, + ) + source_images: MutableSequence["SourceImage"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="SourceImage", + ) + + +class GenerateImagesResponse(proto.Message): + r"""Response message for + [AssetGenerationService.GenerateImages][google.ads.googleads.v23.services.AssetGenerationService.GenerateImages] + + Attributes: + generated_images (MutableSequence[google.ads.googleads.v23.services.types.GeneratedImage]): + Successfully generated images. + """ + + generated_images: MutableSequence["GeneratedImage"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="GeneratedImage", + ) + + +class SourceImage(proto.Message): + r"""A source image to be used in the generation process. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + image_data (bytes): + Optional. Raw bytes of the image to use. + + This field is a member of `oneof`_ ``image``. + """ + + image_data: bytes = proto.Field( + proto.BYTES, + number=1, + oneof="image", + ) + + +class GeneratedImage(proto.Message): + r"""Generated image data and metadata. + + Attributes: + image_temporary_url (str): + A temporary URL for the generated image. + asset_field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): + The intended field type for this generated + image. + """ + + image_temporary_url: str = proto.Field( + proto.STRING, + number=1, + ) + asset_field_type: ( + gage_asset_field_type.AssetFieldTypeEnum.AssetFieldType + ) = proto.Field( + proto.ENUM, + number=2, + enum=gage_asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + + +class AssetGenerationExistingContext(proto.Message): + r"""The context for which assets are being generated, such as an + existing AssetGroup or AdGroupAd. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + existing_asset_group (str): + Resource name of an existing AssetGroup for + which these assets are being generated. + + This field is a member of `oneof`_ ``existing_context``. + existing_ad_group_ad (str): + Resource name of an existing AdGroupAd for + which these assets are being generated. + + This field is a member of `oneof`_ ``existing_context``. + """ + + existing_asset_group: str = proto.Field( + proto.STRING, + number=1, + oneof="existing_context", + ) + existing_ad_group_ad: str = proto.Field( + proto.STRING, + number=2, + oneof="existing_context", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/asset_group_asset_service.py b/google/ads/googleads/v23/services/types/asset_group_asset_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/asset_group_asset_service.py rename to google/ads/googleads/v23/services/types/asset_group_asset_service.py index e71ac5af7..ae15fa877 100644 --- a/google/ads/googleads/v19/services/types/asset_group_asset_service.py +++ b/google/ads/googleads/v23/services/types/asset_group_asset_service.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import asset_group_asset +from google.ads.googleads.v23.resources.types import asset_group_asset from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAssetGroupAssetsRequest", "AssetGroupAssetOperation", @@ -38,13 +38,13 @@ class MutateAssetGroupAssetsRequest(proto.Message): r"""Request message for - [AssetGroupAssetService.MutateAssetGroupAssets][google.ads.googleads.v19.services.AssetGroupAssetService.MutateAssetGroupAssets]. + [AssetGroupAssetService.MutateAssetGroupAssets][google.ads.googleads.v23.services.AssetGroupAssetService.MutateAssetGroupAssets]. Attributes: customer_id (str): Required. The ID of the customer whose asset group assets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetGroupAssetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetGroupAssetOperation]): Required. The list of operations to perform on individual asset group assets. partial_failure (bool): @@ -93,12 +93,12 @@ class AssetGroupAssetOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.AssetGroupAsset): + create (google.ads.googleads.v23.resources.types.AssetGroupAsset): Create operation: No resource name is expected for the new asset group asset. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.AssetGroupAsset): + update (google.ads.googleads.v23.resources.types.AssetGroupAsset): Update operation: The asset group asset is expected to have a valid resource name. @@ -139,7 +139,7 @@ class MutateAssetGroupAssetsResponse(proto.Message): r"""Response message for an asset group asset mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAssetGroupAssetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAssetGroupAssetResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial diff --git a/google/ads/googleads/v19/services/types/asset_group_listing_group_filter_service.py b/google/ads/googleads/v23/services/types/asset_group_listing_group_filter_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/asset_group_listing_group_filter_service.py rename to google/ads/googleads/v23/services/types/asset_group_listing_group_filter_service.py index eb57ddab5..2719dff07 100644 --- a/google/ads/googleads/v19/services/types/asset_group_listing_group_filter_service.py +++ b/google/ads/googleads/v23/services/types/asset_group_listing_group_filter_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( asset_group_listing_group_filter as gagr_asset_group_listing_group_filter, ) from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAssetGroupListingGroupFiltersRequest", "AssetGroupListingGroupFilterOperation", @@ -42,7 +42,7 @@ class MutateAssetGroupListingGroupFiltersRequest(proto.Message): r"""Request message for - [AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters][google.ads.googleads.v19.services.AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters]. + [AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters][google.ads.googleads.v23.services.AssetGroupListingGroupFilterService.MutateAssetGroupListingGroupFilters]. partial_failure is not supported because the tree needs to be validated together. @@ -50,13 +50,13 @@ class MutateAssetGroupListingGroupFiltersRequest(proto.Message): customer_id (str): Required. The ID of the customer whose asset group listing group filters are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetGroupListingGroupFilterOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetGroupListingGroupFilterOperation]): Required. The list of operations to perform on individual asset group listing group filters. validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -101,13 +101,13 @@ class AssetGroupListingGroupFilterOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.AssetGroupListingGroupFilter): + create (google.ads.googleads.v23.resources.types.AssetGroupListingGroupFilter): Create operation: No resource name is expected for the new asset group listing group filter. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.AssetGroupListingGroupFilter): + update (google.ads.googleads.v23.resources.types.AssetGroupListingGroupFilter): Update operation: The asset group listing group filter is expected to have a valid resource name. @@ -157,7 +157,7 @@ class MutateAssetGroupListingGroupFiltersResponse(proto.Message): mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAssetGroupListingGroupFilterResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAssetGroupListingGroupFilterResult]): All results for the mutate. """ @@ -176,7 +176,7 @@ class MutateAssetGroupListingGroupFilterResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - asset_group_listing_group_filter (google.ads.googleads.v19.resources.types.AssetGroupListingGroupFilter): + asset_group_listing_group_filter (google.ads.googleads.v23.resources.types.AssetGroupListingGroupFilter): The mutated AssetGroupListingGroupFilter with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/asset_group_service.py b/google/ads/googleads/v23/services/types/asset_group_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/asset_group_service.py rename to google/ads/googleads/v23/services/types/asset_group_service.py index 11efcd6b3..050df1c61 100644 --- a/google/ads/googleads/v19/services/types/asset_group_service.py +++ b/google/ads/googleads/v23/services/types/asset_group_service.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import asset_group +from google.ads.googleads.v23.resources.types import asset_group from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAssetGroupsRequest", "AssetGroupOperation", @@ -38,13 +38,13 @@ class MutateAssetGroupsRequest(proto.Message): r"""Request message for - [AssetGroupService.MutateAssetGroups][google.ads.googleads.v19.services.AssetGroupService.MutateAssetGroups]. + [AssetGroupService.MutateAssetGroups][google.ads.googleads.v23.services.AssetGroupService.MutateAssetGroups]. Attributes: customer_id (str): Required. The ID of the customer whose asset groups are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetGroupOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetGroupOperation]): Required. The list of operations to perform on individual asset groups. validate_only (bool): @@ -81,12 +81,12 @@ class AssetGroupOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.AssetGroup): + create (google.ads.googleads.v23.resources.types.AssetGroup): Create operation: No resource name is expected for the new asset group This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.AssetGroup): + update (google.ads.googleads.v23.resources.types.AssetGroup): Update operation: The asset group is expected to have a valid resource name. @@ -127,7 +127,7 @@ class MutateAssetGroupsResponse(proto.Message): r"""Response message for an asset group mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAssetGroupResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAssetGroupResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial diff --git a/google/ads/googleads/v19/services/types/asset_group_signal_service.py b/google/ads/googleads/v23/services/types/asset_group_signal_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/asset_group_signal_service.py rename to google/ads/googleads/v23/services/types/asset_group_signal_service.py index c0cb6f308..1d29b8a4c 100644 --- a/google/ads/googleads/v19/services/types/asset_group_signal_service.py +++ b/google/ads/googleads/v23/services/types/asset_group_signal_service.py @@ -19,19 +19,19 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import policy -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import policy +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( asset_group_signal as gagr_asset_group_signal, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAssetGroupSignalsRequest", "AssetGroupSignalOperation", @@ -43,13 +43,13 @@ class MutateAssetGroupSignalsRequest(proto.Message): r"""Request message for - [AssetGroupSignalService.MutateAssetGroupSignals][google.ads.googleads.v19.services.AssetGroupSignalService.MutateAssetGroupSignals]. + [AssetGroupSignalService.MutateAssetGroupSignals][google.ads.googleads.v23.services.AssetGroupSignalService.MutateAssetGroupSignals]. Attributes: customer_id (str): Required. The ID of the customer whose asset group signals are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetGroupSignalOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetGroupSignalOperation]): Required. The list of operations to perform on individual asset group signals. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateAssetGroupSignalsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -106,7 +106,7 @@ class AssetGroupSignalOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - exempt_policy_violation_keys (MutableSequence[google.ads.googleads.v19.common.types.PolicyViolationKey]): + exempt_policy_violation_keys (MutableSequence[google.ads.googleads.v23.common.types.PolicyViolationKey]): Optional. The list of policy violation keys that should not cause a PolicyViolationError to be reported. Not all policy violations are exemptable, refer to the is_exemptible field @@ -116,7 +116,7 @@ class AssetGroupSignalOperation(proto.Message): not be eligible to serve. They may begin serving at a later time due to a change in policies, re-review of the resource, or a change in advertiser certificates. - create (google.ads.googleads.v19.resources.types.AssetGroupSignal): + create (google.ads.googleads.v23.resources.types.AssetGroupSignal): Create operation: No resource name is expected for the new asset group signal. @@ -153,7 +153,7 @@ class MutateAssetGroupSignalsResponse(proto.Message): r"""Response message for an asset group signal mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAssetGroupSignalResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAssetGroupSignalResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -183,7 +183,7 @@ class MutateAssetGroupSignalResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - asset_group_signal (google.ads.googleads.v19.resources.types.AssetGroupSignal): + asset_group_signal (google.ads.googleads.v23.resources.types.AssetGroupSignal): The mutated AssetGroupSignal with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/asset_service.py b/google/ads/googleads/v23/services/types/asset_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/asset_service.py rename to google/ads/googleads/v23/services/types/asset_service.py index d8b54fdd6..820eafdba 100644 --- a/google/ads/googleads/v19/services/types/asset_service.py +++ b/google/ads/googleads/v23/services/types/asset_service.py @@ -19,17 +19,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import asset as gagr_asset +from google.ads.googleads.v23.resources.types import asset as gagr_asset from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAssetsRequest", "AssetOperation", @@ -41,13 +41,13 @@ class MutateAssetsRequest(proto.Message): r"""Request message for - [AssetService.MutateAssets][google.ads.googleads.v19.services.AssetService.MutateAssets] + [AssetService.MutateAssets][google.ads.googleads.v23.services.AssetService.MutateAssets] Attributes: customer_id (str): Required. The ID of the customer whose assets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetOperation]): Required. The list of operations to perform on individual assets. partial_failure (bool): @@ -56,7 +56,7 @@ class MutateAssetsRequest(proto.Message): errors. If false, all operations will be carried out in one transaction if and only if they are all valid. Default is false. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -109,12 +109,12 @@ class AssetOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.Asset): + create (google.ads.googleads.v23.resources.types.Asset): Create operation: No resource name is expected for the new asset. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.Asset): + update (google.ads.googleads.v23.resources.types.Asset): Update operation: The asset is expected to have a valid resource name in this format: @@ -152,7 +152,7 @@ class MutateAssetsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAssetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAssetResult]): All results for the mutate. """ @@ -175,7 +175,7 @@ class MutateAssetResult(proto.Message): resource_name (str): The resource name returned for successful operations. - asset (google.ads.googleads.v19.resources.types.Asset): + asset (google.ads.googleads.v23.resources.types.Asset): The mutated asset with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/asset_set_asset_service.py b/google/ads/googleads/v23/services/types/asset_set_asset_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/asset_set_asset_service.py rename to google/ads/googleads/v23/services/types/asset_set_asset_service.py index 379436da0..3aae6bf7a 100644 --- a/google/ads/googleads/v19/services/types/asset_set_asset_service.py +++ b/google/ads/googleads/v23/services/types/asset_set_asset_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( asset_set_asset as gagr_asset_set_asset, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAssetSetAssetsRequest", "AssetSetAssetOperation", @@ -42,13 +42,13 @@ class MutateAssetSetAssetsRequest(proto.Message): r"""Request message for - [AssetSetAssetService.MutateAssetSetAssets][google.ads.googleads.v19.services.AssetSetAssetService.MutateAssetSetAssets]. + [AssetSetAssetService.MutateAssetSetAssets][google.ads.googleads.v23.services.AssetSetAssetService.MutateAssetSetAssets]. Attributes: customer_id (str): Required. The ID of the customer whose asset set assets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetSetAssetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetSetAssetOperation]): Required. The list of operations to perform on individual asset set assets. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateAssetSetAssetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -103,7 +103,7 @@ class AssetSetAssetOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.AssetSetAsset): + create (google.ads.googleads.v23.resources.types.AssetSetAsset): Create operation: No resource name is expected for the new asset set asset @@ -133,7 +133,7 @@ class MutateAssetSetAssetsResponse(proto.Message): r"""Response message for an asset set asset mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAssetSetAssetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAssetSetAssetResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -161,7 +161,7 @@ class MutateAssetSetAssetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - asset_set_asset (google.ads.googleads.v19.resources.types.AssetSetAsset): + asset_set_asset (google.ads.googleads.v23.resources.types.AssetSetAsset): The mutated asset set asset with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/asset_set_service.py b/google/ads/googleads/v23/services/types/asset_set_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/asset_set_service.py rename to google/ads/googleads/v23/services/types/asset_set_service.py index d6c1c3846..ef32dbeb8 100644 --- a/google/ads/googleads/v19/services/types/asset_set_service.py +++ b/google/ads/googleads/v23/services/types/asset_set_service.py @@ -19,17 +19,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import asset_set as gagr_asset_set +from google.ads.googleads.v23.resources.types import asset_set as gagr_asset_set from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAssetSetsRequest", "AssetSetOperation", @@ -41,13 +41,13 @@ class MutateAssetSetsRequest(proto.Message): r"""Request message for - [AssetSetService.MutateAssetSets][google.ads.googleads.v19.services.AssetSetService.MutateAssetSets]. + [AssetSetService.MutateAssetSets][google.ads.googleads.v23.services.AssetSetService.MutateAssetSets]. Attributes: customer_id (str): Required. The ID of the customer whose asset sets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AssetSetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AssetSetOperation]): Required. The list of operations to perform on individual asset sets. partial_failure (bool): @@ -59,7 +59,7 @@ class MutateAssetSetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -105,12 +105,12 @@ class AssetSetOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.AssetSet): + create (google.ads.googleads.v23.resources.types.AssetSet): Create operation: No resource name is expected for the new asset set This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.AssetSet): + update (google.ads.googleads.v23.resources.types.AssetSet): Update operation: The asset set is expected to have a valid resource name. @@ -151,7 +151,7 @@ class MutateAssetSetsResponse(proto.Message): r"""Response message for an asset set mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAssetSetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAssetSetResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -179,7 +179,7 @@ class MutateAssetSetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - asset_set (google.ads.googleads.v19.resources.types.AssetSet): + asset_set (google.ads.googleads.v23.resources.types.AssetSet): The mutated asset set with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v23/services/types/audience_insights_service.py b/google/ads/googleads/v23/services/types/audience_insights_service.py new file mode 100644 index 000000000..f490a9c92 --- /dev/null +++ b/google/ads/googleads/v23/services/types/audience_insights_service.py @@ -0,0 +1,1202 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import additional_application_info +from google.ads.googleads.v23.common.types import audience_insights_attribute +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.common.types import dates +from google.ads.googleads.v23.enums.types import audience_insights_dimension +from google.ads.googleads.v23.enums.types import ( + audience_insights_marketing_objective, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", + manifest={ + "GenerateInsightsFinderReportRequest", + "GenerateInsightsFinderReportResponse", + "GenerateAudienceCompositionInsightsRequest", + "GenerateAudienceCompositionInsightsResponse", + "GenerateSuggestedTargetingInsightsRequest", + "GenerateSuggestedTargetingInsightsResponse", + "TargetingSuggestionMetrics", + "ListAudienceInsightsAttributesRequest", + "ListAudienceInsightsAttributesResponse", + "ListInsightsEligibleDatesRequest", + "ListInsightsEligibleDatesResponse", + "GenerateAudienceOverlapInsightsRequest", + "GenerateAudienceOverlapInsightsResponse", + "DimensionOverlapResult", + "AudienceOverlapItem", + "GenerateTargetingSuggestionMetricsRequest", + "GenerateTargetingSuggestionMetricsResponse", + "GenerateAudienceDefinitionRequest", + "GenerateAudienceDefinitionResponse", + "AudienceInsightsDimensions", + "InsightsAudienceDefinition", + "InsightsAudienceDescription", + "InsightsAudience", + "InsightsAudienceAttributeGroup", + "AudienceCompositionSection", + "AudienceCompositionAttributeCluster", + "AudienceCompositionMetrics", + "AudienceCompositionAttribute", + }, +) + + +class GenerateInsightsFinderReportRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v23.services.AudienceInsightsService.GenerateInsightsFinderReport]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + baseline_audience (google.ads.googleads.v23.services.types.InsightsAudience): + Required. A baseline audience for this + report, typically all people in a region. + specific_audience (google.ads.googleads.v23.services.types.InsightsAudience): + Required. The specific audience of interest + for this report. The insights in the report + will be based on attributes more prevalent in + this audience than in the report's baseline + audience. + customer_insights_group (str): + The name of the customer being planned for. + This is a user-defined value. + insights_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + baseline_audience: "InsightsAudience" = proto.Field( + proto.MESSAGE, + number=6, + message="InsightsAudience", + ) + specific_audience: "InsightsAudience" = proto.Field( + proto.MESSAGE, + number=7, + message="InsightsAudience", + ) + customer_insights_group: str = proto.Field( + proto.STRING, + number=4, + ) + insights_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=5, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class GenerateInsightsFinderReportResponse(proto.Message): + r"""The response message for + [AudienceInsightsService.GenerateInsightsFinderReport][google.ads.googleads.v23.services.AudienceInsightsService.GenerateInsightsFinderReport], + containing the shareable URL for the report. + + Attributes: + saved_report_url (str): + An HTTPS URL providing a deep link into the + Insights Finder UI with the report inputs filled + in according to the request. + """ + + saved_report_url: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GenerateAudienceCompositionInsightsRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + audience (google.ads.googleads.v23.services.types.InsightsAudience): + Required. The audience of interest for which + insights are being requested. + baseline_audience (google.ads.googleads.v23.services.types.InsightsAudience): + The baseline audience to which the audience + of interest is being compared. + data_month (str): + The one-month range of historical data to use + for insights, in the format "yyyy-mm". If unset, + insights will be returned for the last thirty + days of data. + dimensions (MutableSequence[google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): + Required. The audience dimensions for which composition + insights should be returned. Supported dimensions are + KNOWLEDGE_GRAPH, GEO_TARGET_COUNTRY, SUB_COUNTRY_LOCATION, + YOUTUBE_CHANNEL, YOUTUBE_LINEUP, AFFINITY_USER_INTEREST, + IN_MARKET_USER_INTEREST, LIFE_EVENT_USER_INTEREST, + PARENTAL_STATUS, INCOME_RANGE, AGE_RANGE, and GENDER. + customer_insights_group (str): + The name of the customer being planned for. + This is a user-defined value. + insights_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + audience: "InsightsAudience" = proto.Field( + proto.MESSAGE, + number=2, + message="InsightsAudience", + ) + baseline_audience: "InsightsAudience" = proto.Field( + proto.MESSAGE, + number=6, + message="InsightsAudience", + ) + data_month: str = proto.Field( + proto.STRING, + number=3, + ) + dimensions: MutableSequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] = proto.RepeatedField( + proto.ENUM, + number=4, + enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, + ) + customer_insights_group: str = proto.Field( + proto.STRING, + number=5, + ) + insights_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=7, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class GenerateAudienceCompositionInsightsResponse(proto.Message): + r"""Response message for + [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceCompositionInsights]. + + Attributes: + sections (MutableSequence[google.ads.googleads.v23.services.types.AudienceCompositionSection]): + The contents of the insights report, + organized into sections. Each section is + associated with one of the + AudienceInsightsDimension values in the request. + There may be more than one section per + dimension. + """ + + sections: MutableSequence["AudienceCompositionSection"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="AudienceCompositionSection", + ) + ) + + +class GenerateSuggestedTargetingInsightsRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + Required. The ID of the customer. + customer_insights_group (str): + Optional. The name of the customer being + planned for. This is a user-defined value. + insights_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + audience_definition (google.ads.googleads.v23.services.types.InsightsAudienceDefinition): + Provide a seed audience to get suggestions + for. + + This field is a member of `oneof`_ ``audience_input``. + audience_description (google.ads.googleads.v23.services.types.InsightsAudienceDescription): + Provide a text description of an audience to get + AI-generated targeting suggestions. This can take around 5 + or more seconds to complete. Supported marketing objectives + are: AWARENESS and CONSIDERATION. Supported dimensions are: + AGE_RANGE, GENDER, PARENTAL_STATUS, AFFINITY_USER_INTEREST, + IN_MARKET_USER_INTEREST and LIFE_EVENT_USER_INTEREST. + + This field is a member of `oneof`_ ``audience_input``. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + customer_insights_group: str = proto.Field( + proto.STRING, + number=5, + ) + insights_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=8, + message=additional_application_info.AdditionalApplicationInfo, + ) + audience_definition: "InsightsAudienceDefinition" = proto.Field( + proto.MESSAGE, + number=6, + oneof="audience_input", + message="InsightsAudienceDefinition", + ) + audience_description: "InsightsAudienceDescription" = proto.Field( + proto.MESSAGE, + number=7, + oneof="audience_input", + message="InsightsAudienceDescription", + ) + + +class GenerateSuggestedTargetingInsightsResponse(proto.Message): + r"""Response message for + [AudienceInsightsService.GenerateSuggestedTargetingInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateSuggestedTargetingInsights]. + + Attributes: + suggestions (MutableSequence[google.ads.googleads.v23.services.types.TargetingSuggestionMetrics]): + Suggested insights for targetable audiences. + """ + + suggestions: MutableSequence["TargetingSuggestionMetrics"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="TargetingSuggestionMetrics", + ) + ) + + +class TargetingSuggestionMetrics(proto.Message): + r"""A suggested targetable audience relevant to the requested + audience. + + Attributes: + locations (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata]): + Suggested location targeting. These attributes all have + dimension GEO_TARGET_COUNTRY or SUB_COUNTRY_LOCATION + age_ranges (MutableSequence[google.ads.googleads.v23.common.types.AgeRangeInfo]): + Suggested age targeting; may be empty + indicating no age targeting. + gender (google.ads.googleads.v23.common.types.GenderInfo): + Suggested gender targeting. If present, this + attribute has dimension GENDER. + parental_status (google.ads.googleads.v23.common.types.ParentalStatusInfo): + A Parental Status value (parent, or not a + parent). + user_interests (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadataGroup]): + List of user interest attributes with + metadata defining the audience. The combination + has a logical AND-of-ORs structure: The + attributes within each + AudienceInsightsAttributeMetadataGroup are ORed, + and the groups themselves are ANDed. + coverage (float): + The fraction (from 0 to 1 inclusive) of the + requested audience that can be reached using the + suggested targeting. + index (float): + The ratio of coverage to the coverage of the + baseline audience or zero if this ratio is + undefined or is not meaningful. + potential_youtube_reach (int): + The approximate estimated number of people + that can be reached on YouTube using this + targeting. + """ + + locations: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttributeMetadata + ] = proto.RepeatedField( + proto.MESSAGE, + number=9, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + age_ranges: MutableSequence[criteria.AgeRangeInfo] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=criteria.AgeRangeInfo, + ) + gender: criteria.GenderInfo = proto.Field( + proto.MESSAGE, + number=3, + message=criteria.GenderInfo, + ) + parental_status: criteria.ParentalStatusInfo = proto.Field( + proto.MESSAGE, + number=8, + message=criteria.ParentalStatusInfo, + ) + user_interests: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttributeMetadataGroup + ] = proto.RepeatedField( + proto.MESSAGE, + number=11, + message=audience_insights_attribute.AudienceInsightsAttributeMetadataGroup, + ) + coverage: float = proto.Field( + proto.DOUBLE, + number=5, + ) + index: float = proto.Field( + proto.DOUBLE, + number=6, + ) + potential_youtube_reach: int = proto.Field( + proto.INT64, + number=7, + ) + + +class ListAudienceInsightsAttributesRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v23.services.AudienceInsightsService.ListAudienceInsightsAttributes]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + dimensions (MutableSequence[google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): + Required. The types of attributes to be returned. Supported + dimensions are CATEGORY, KNOWLEDGE_GRAPH, DEVICE, + GEO_TARGET_COUNTRY, SUB_COUNTRY_LOCATION, YOUTUBE_LINEUP, + AFFINITY_USER_INTEREST, IN_MARKET_USER_INTEREST, + LIFE_EVENT_USER_INTEREST, PARENTAL_STATUS, INCOME_RANGE, + AGE_RANGE, and GENDER. + query_text (str): + Required. A free text query. If the requested dimensions + include Attributes CATEGORY or KNOWLEDGE_GRAPH, then the + attributes returned for those dimensions will match or be + related to this string. For other dimensions, this field is + ignored and all available attributes are returned. + customer_insights_group (str): + The name of the customer being planned for. + This is a user-defined value. + insights_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + location_country_filters (MutableSequence[google.ads.googleads.v23.common.types.LocationInfo]): + If SUB_COUNTRY_LOCATION attributes are one of the requested + dimensions and this field is present, then the + SUB_COUNTRY_LOCATION attributes returned will be located in + these countries. If this field is absent, then location + attributes are not filtered by country. Setting this field + when SUB_COUNTRY_LOCATION attributes are not requested will + return an error. + youtube_reach_location (google.ads.googleads.v23.common.types.LocationInfo): + If present, potential YouTube reach estimates within the + specified market will be returned for attributes for which + they are available. Reach is only available for the + AGE_RANGE, GENDER, AFFINITY_USER_INTEREST and + IN_MARKET_USER_INTEREST dimensions, and may not be available + for every attribute of those dimensions in every market. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + dimensions: MutableSequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] = proto.RepeatedField( + proto.ENUM, + number=2, + enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, + ) + query_text: str = proto.Field( + proto.STRING, + number=3, + ) + customer_insights_group: str = proto.Field( + proto.STRING, + number=4, + ) + insights_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=7, + message=additional_application_info.AdditionalApplicationInfo, + ) + location_country_filters: MutableSequence[criteria.LocationInfo] = ( + proto.RepeatedField( + proto.MESSAGE, + number=5, + message=criteria.LocationInfo, + ) + ) + youtube_reach_location: criteria.LocationInfo = proto.Field( + proto.MESSAGE, + number=6, + message=criteria.LocationInfo, + ) + + +class ListAudienceInsightsAttributesResponse(proto.Message): + r"""Response message for + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v23.services.AudienceInsightsService.ListAudienceInsightsAttributes]. + + Attributes: + attributes (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata]): + The attributes matching the search query. + """ + + attributes: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttributeMetadata + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + + +class ListInsightsEligibleDatesRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v23.services.AudienceInsightsService.ListInsightsEligibleDates]. + + Attributes: + insights_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + insights_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=1, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class ListInsightsEligibleDatesResponse(proto.Message): + r"""Response message for + [AudienceInsightsService.ListInsightsEligibleDates][google.ads.googleads.v23.services.AudienceInsightsService.ListInsightsEligibleDates]. + + Attributes: + data_months (MutableSequence[str]): + The months for which AudienceInsights data is + currently available, each represented as a + string in the form "YYYY-MM". + last_thirty_days (google.ads.googleads.v23.common.types.DateRange): + The actual dates covered by the "last 30 days" date range + that will be used implicitly for + [AudienceInsightsService.GenerateAudienceCompositionInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceCompositionInsights] + requests that have no data_month set. + """ + + data_months: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + last_thirty_days: dates.DateRange = proto.Field( + proto.MESSAGE, + number=2, + message=dates.DateRange, + ) + + +class GenerateAudienceOverlapInsightsRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + country_location (google.ads.googleads.v23.common.types.LocationInfo): + Required. The country in which to calculate + the sizes and overlaps of audiences. + primary_attribute (google.ads.googleads.v23.common.types.AudienceInsightsAttribute): + Required. The audience attribute that should + be intersected with all other eligible + audiences. This must be an Affinity or + In-Market UserInterest, an AgeRange or a Gender. + dimensions (MutableSequence[google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): + Required. The types of attributes of which to calculate the + overlap with the primary_attribute. The values must be a + subset of AFFINITY_USER_INTEREST, IN_MARKET_USER_INTEREST, + AGE_RANGE and GENDER. + customer_insights_group (str): + The name of the customer being planned for. + This is a user-defined value. + insights_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + country_location: criteria.LocationInfo = proto.Field( + proto.MESSAGE, + number=2, + message=criteria.LocationInfo, + ) + primary_attribute: audience_insights_attribute.AudienceInsightsAttribute = ( + proto.Field( + proto.MESSAGE, + number=6, + message=audience_insights_attribute.AudienceInsightsAttribute, + ) + ) + dimensions: MutableSequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] = proto.RepeatedField( + proto.ENUM, + number=4, + enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, + ) + customer_insights_group: str = proto.Field( + proto.STRING, + number=5, + ) + insights_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=7, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class GenerateAudienceOverlapInsightsResponse(proto.Message): + r"""Response message for + [AudienceInsightsService.GenerateAudienceOverlapInsights][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceOverlapInsights]. + + Attributes: + primary_attribute_metadata (google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata): + Metadata for the primary attribute, including + potential YouTube reach. + dimension_results (MutableSequence[google.ads.googleads.v23.services.types.DimensionOverlapResult]): + Lists of attributes and their overlap with + the primary attribute, one list per requested + dimension. + """ + + primary_attribute_metadata: ( + audience_insights_attribute.AudienceInsightsAttributeMetadata + ) = proto.Field( + proto.MESSAGE, + number=3, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + dimension_results: MutableSequence["DimensionOverlapResult"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=2, + message="DimensionOverlapResult", + ) + ) + + +class DimensionOverlapResult(proto.Message): + r"""A list of audience attributes of a single dimension, including their + overlap with a primary attribute, returned as part of a + [GenerateAudienceOverlapInsightsResponse][google.ads.googleads.v23.services.GenerateAudienceOverlapInsightsResponse]. + + Attributes: + dimension (google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension): + The dimension of all the attributes in this + section. + items (MutableSequence[google.ads.googleads.v23.services.types.AudienceOverlapItem]): + The attributes and their overlap with the + primary attribute. + """ + + dimension: ( + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ) = proto.Field( + proto.ENUM, + number=1, + enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, + ) + items: MutableSequence["AudienceOverlapItem"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="AudienceOverlapItem", + ) + + +class AudienceOverlapItem(proto.Message): + r"""An audience attribute, with metadata including the overlap + between this attribute's potential YouTube reach and that of a + primary attribute. + + Attributes: + attribute_metadata (google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata): + The attribute and its metadata, including + potential YouTube reach. + potential_youtube_reach_intersection (int): + The estimated size of the intersection of + this audience attribute with the primary + attribute, that is, the number of reachable + YouTube users who match BOTH the primary + attribute and this one. + """ + + attribute_metadata: ( + audience_insights_attribute.AudienceInsightsAttributeMetadata + ) = proto.Field( + proto.MESSAGE, + number=3, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + potential_youtube_reach_intersection: int = proto.Field( + proto.INT64, + number=2, + ) + + +class GenerateTargetingSuggestionMetricsRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v23.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + audiences (MutableSequence[google.ads.googleads.v23.services.types.InsightsAudience]): + Required. Audiences to request metrics for. + customer_insights_group (str): + Optional. The name of the customer being + planned for. This is a user-defined value. + insights_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + audiences: MutableSequence["InsightsAudience"] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message="InsightsAudience", + ) + customer_insights_group: str = proto.Field( + proto.STRING, + number=3, + ) + insights_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=4, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class GenerateTargetingSuggestionMetricsResponse(proto.Message): + r"""Response message for + [AudienceInsightsService.GenerateTargetingSuggestionMetrics][google.ads.googleads.v23.services.AudienceInsightsService.GenerateTargetingSuggestionMetrics]. + + Attributes: + suggestions (MutableSequence[google.ads.googleads.v23.services.types.TargetingSuggestionMetrics]): + Suggested targetable audiences. There will be one suggestion + for each + [GenerateTargetingSuggestionMetricsRequest.audiences][google.ads.googleads.v23.services.GenerateTargetingSuggestionMetricsRequest.audiences] + requested, matching the order requested. + """ + + suggestions: MutableSequence["TargetingSuggestionMetrics"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="TargetingSuggestionMetrics", + ) + ) + + +class GenerateAudienceDefinitionRequest(proto.Message): + r"""Request message for + [AudienceInsightsService.GenerateAudienceDefinition][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceDefinition]. + + Attributes: + customer_id (str): + Required. The ID of the customer. + audience_description (google.ads.googleads.v23.services.types.InsightsAudienceDescription): + Required. Provide a text description of an audience to get + AI-generated structured suggestions. This can take around 5 + or more seconds to complete Supported marketing objectives + are: AWARENESS, CONSIDERATION and RESEARCH. Supported + dimensions are: AGE_RANGE, GENDER, PARENTAL_STATUS, + AFFINITY_USER_INTEREST, IN_MARKET_USER_INTEREST, + LIFE_EVENT_USER_INTEREST, CATEGORY and KNOWLEDGE_GRAPH. + customer_insights_group (str): + Optional. The name of the customer being + planned for. This is a user-defined value. + insights_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + audience_description: "InsightsAudienceDescription" = proto.Field( + proto.MESSAGE, + number=2, + message="InsightsAudienceDescription", + ) + customer_insights_group: str = proto.Field( + proto.STRING, + number=3, + ) + insights_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=4, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class GenerateAudienceDefinitionResponse(proto.Message): + r"""Response message for + [AudienceInsightsService.GenerateAudienceDefinition][google.ads.googleads.v23.services.AudienceInsightsService.GenerateAudienceDefinition]. + + Attributes: + high_relevance_attributes (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata]): + The attributes that make up the audience + definition. + medium_relevance_attributes (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata]): + Additional attributes that are less relevant + but still related to the audience description. + Use these attributes to broaden the audience + definition to reach more users. + """ + + high_relevance_attributes: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttributeMetadata + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + medium_relevance_attributes: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttributeMetadata + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + + +class AudienceInsightsDimensions(proto.Message): + r"""A collection of dimensions to be used for generating + insights. + + Attributes: + dimensions (MutableSequence[google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension]): + Required. A list of dimensions. + """ + + dimensions: MutableSequence[ + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ] = proto.RepeatedField( + proto.ENUM, + number=1, + enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, + ) + + +class InsightsAudienceDefinition(proto.Message): + r"""A structured definition of the audience of interest for which + insights are being requested in AudienceInsightsService. + + Attributes: + audience (google.ads.googleads.v23.services.types.InsightsAudience): + Required. The audience of interest for which + insights are being requested. + baseline_audience (google.ads.googleads.v23.services.types.InsightsAudience): + Optional. The baseline audience. The default, + if unspecified, is all people in the same + country as the audience of interest. + data_month (str): + Optional. The one-month range of historical + data to use for insights, in the format + "yyyy-mm". If unset, insights will be returned + for the last thirty days of data. + """ + + audience: "InsightsAudience" = proto.Field( + proto.MESSAGE, + number=1, + message="InsightsAudience", + ) + baseline_audience: "InsightsAudience" = proto.Field( + proto.MESSAGE, + number=2, + message="InsightsAudience", + ) + data_month: str = proto.Field( + proto.STRING, + number=3, + ) + + +class InsightsAudienceDescription(proto.Message): + r"""A text description of the audience of interest for which + insights are being requested in AudienceInsightsService. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + country_locations (MutableSequence[google.ads.googleads.v23.common.types.LocationInfo]): + Required. The countries for the audience. + audience_description (str): + Required. An English language text + description of an audience to get suggestions + for. Maximum length is 2000 characters. For + example, "Women in their 30s who love to + travel". + marketing_objective (google.ads.googleads.v23.enums.types.AudienceInsightsMarketingObjectiveEnum.AudienceInsightsMarketingObjective): + Optional. An optional marketing objective + which will influence the type of suggestions + produced. + + This field is a member of `oneof`_ ``output_types``. + audience_dimensions (google.ads.googleads.v23.services.types.AudienceInsightsDimensions): + Optional. An optional list of audience + dimensions to return. + + This field is a member of `oneof`_ ``output_types``. + """ + + country_locations: MutableSequence[criteria.LocationInfo] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message=criteria.LocationInfo, + ) + ) + audience_description: str = proto.Field( + proto.STRING, + number=2, + ) + marketing_objective: ( + audience_insights_marketing_objective.AudienceInsightsMarketingObjectiveEnum.AudienceInsightsMarketingObjective + ) = proto.Field( + proto.ENUM, + number=4, + oneof="output_types", + enum=audience_insights_marketing_objective.AudienceInsightsMarketingObjectiveEnum.AudienceInsightsMarketingObjective, + ) + audience_dimensions: "AudienceInsightsDimensions" = proto.Field( + proto.MESSAGE, + number=5, + oneof="output_types", + message="AudienceInsightsDimensions", + ) + + +class InsightsAudience(proto.Message): + r"""A set of users, defined by various characteristics, for which + insights can be requested in AudienceInsightsService. + + Attributes: + country_locations (MutableSequence[google.ads.googleads.v23.common.types.LocationInfo]): + Required. The countries for the audience. + sub_country_locations (MutableSequence[google.ads.googleads.v23.common.types.LocationInfo]): + Sub-country geographic location attributes. If present, each + of these must be contained in one of the countries in this + audience. If absent, the audience is geographically to the + country_locations and no further. + gender (google.ads.googleads.v23.common.types.GenderInfo): + Gender for the audience. If absent, the + audience does not restrict by gender. + age_ranges (MutableSequence[google.ads.googleads.v23.common.types.AgeRangeInfo]): + Age ranges for the audience. If absent, the + audience represents all people over 18 that + match the other attributes. + parental_status (google.ads.googleads.v23.common.types.ParentalStatusInfo): + Parental status for the audience. If absent, + the audience does not restrict by parental + status. + income_ranges (MutableSequence[google.ads.googleads.v23.common.types.IncomeRangeInfo]): + Household income percentile ranges for the + audience. If absent, the audience does not + restrict by household income range. + lineups (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsLineup]): + Lineups representing the YouTube content + viewed by the audience. + user_list (google.ads.googleads.v23.common.types.UserListInfo): + User list to be targeted by the audience. + topic_audience_combinations (MutableSequence[google.ads.googleads.v23.services.types.InsightsAudienceAttributeGroup]): + A combination of entity, category and user + interest attributes defining the audience. The + combination has a logical AND-of-ORs structure: + Attributes within each + InsightsAudienceAttributeGroup are combined with + OR, and the combinations themselves are combined + together with AND. For example, the expression + (Entity OR Affinity) AND (In-Market OR Category) + can be formed using two + InsightsAudienceAttributeGroups with two + Attributes each. + """ + + country_locations: MutableSequence[criteria.LocationInfo] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message=criteria.LocationInfo, + ) + ) + sub_country_locations: MutableSequence[criteria.LocationInfo] = ( + proto.RepeatedField( + proto.MESSAGE, + number=2, + message=criteria.LocationInfo, + ) + ) + gender: criteria.GenderInfo = proto.Field( + proto.MESSAGE, + number=3, + message=criteria.GenderInfo, + ) + age_ranges: MutableSequence[criteria.AgeRangeInfo] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=criteria.AgeRangeInfo, + ) + parental_status: criteria.ParentalStatusInfo = proto.Field( + proto.MESSAGE, + number=5, + message=criteria.ParentalStatusInfo, + ) + income_ranges: MutableSequence[criteria.IncomeRangeInfo] = ( + proto.RepeatedField( + proto.MESSAGE, + number=6, + message=criteria.IncomeRangeInfo, + ) + ) + lineups: MutableSequence[ + audience_insights_attribute.AudienceInsightsLineup + ] = proto.RepeatedField( + proto.MESSAGE, + number=10, + message=audience_insights_attribute.AudienceInsightsLineup, + ) + user_list: criteria.UserListInfo = proto.Field( + proto.MESSAGE, + number=11, + message=criteria.UserListInfo, + ) + topic_audience_combinations: MutableSequence[ + "InsightsAudienceAttributeGroup" + ] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message="InsightsAudienceAttributeGroup", + ) + + +class InsightsAudienceAttributeGroup(proto.Message): + r"""A list of AudienceInsightsAttributes. + + Attributes: + attributes (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttribute]): + Required. A collection of audience attributes + to be combined with logical OR. Attributes need + not all be the same dimension. Only Knowledge + Graph entities, Product & Service Categories, + and Affinity and In-Market audiences are + supported in this context. + """ + + attributes: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttribute + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=audience_insights_attribute.AudienceInsightsAttribute, + ) + + +class AudienceCompositionSection(proto.Message): + r"""A collection of related attributes of the same type in an + audience composition insights report. + + Attributes: + dimension (google.ads.googleads.v23.enums.types.AudienceInsightsDimensionEnum.AudienceInsightsDimension): + The type of the attributes in this section. + top_attributes (MutableSequence[google.ads.googleads.v23.services.types.AudienceCompositionAttribute]): + The most relevant segments for this audience. If dimension + is GENDER, AGE_RANGE or PARENTAL_STATUS, then this list of + attributes is exhaustive. + clustered_attributes (MutableSequence[google.ads.googleads.v23.services.types.AudienceCompositionAttributeCluster]): + Additional attributes for this audience, grouped into + clusters. Only populated if dimension is YOUTUBE_CHANNEL. + """ + + dimension: ( + audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension + ) = proto.Field( + proto.ENUM, + number=1, + enum=audience_insights_dimension.AudienceInsightsDimensionEnum.AudienceInsightsDimension, + ) + top_attributes: MutableSequence["AudienceCompositionAttribute"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=3, + message="AudienceCompositionAttribute", + ) + ) + clustered_attributes: MutableSequence[ + "AudienceCompositionAttributeCluster" + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="AudienceCompositionAttributeCluster", + ) + + +class AudienceCompositionAttributeCluster(proto.Message): + r"""A collection of related attributes, with metadata and + metrics, in an audience composition insights report. + + Attributes: + cluster_display_name (str): + The name of this cluster of attributes + cluster_metrics (google.ads.googleads.v23.services.types.AudienceCompositionMetrics): + If the dimension associated with this cluster is + YOUTUBE_CHANNEL, then cluster_metrics are metrics associated + with the cluster as a whole. For other dimensions, this + field is unset. + attributes (MutableSequence[google.ads.googleads.v23.services.types.AudienceCompositionAttribute]): + The individual attributes that make up this + cluster, with metadata and metrics. + """ + + cluster_display_name: str = proto.Field( + proto.STRING, + number=1, + ) + cluster_metrics: "AudienceCompositionMetrics" = proto.Field( + proto.MESSAGE, + number=3, + message="AudienceCompositionMetrics", + ) + attributes: MutableSequence["AudienceCompositionAttribute"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=4, + message="AudienceCompositionAttribute", + ) + ) + + +class AudienceCompositionMetrics(proto.Message): + r"""The share and index metrics associated with an attribute in + an audience composition insights report. + + Attributes: + baseline_audience_share (float): + The fraction (from 0 to 1 inclusive) of the + baseline audience that match the attribute. + audience_share (float): + The fraction (from 0 to 1 inclusive) of the + specific audience that match the attribute. + index (float): + The ratio of audience_share to baseline_audience_share, or + zero if this ratio is undefined or is not meaningful. + score (float): + A relevance score from 0 to 1 inclusive. + """ + + baseline_audience_share: float = proto.Field( + proto.DOUBLE, + number=1, + ) + audience_share: float = proto.Field( + proto.DOUBLE, + number=2, + ) + index: float = proto.Field( + proto.DOUBLE, + number=3, + ) + score: float = proto.Field( + proto.DOUBLE, + number=4, + ) + + +class AudienceCompositionAttribute(proto.Message): + r"""An audience attribute with metadata and metrics. + + Attributes: + attribute_metadata (google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata): + The attribute with its metadata. + metrics (google.ads.googleads.v23.services.types.AudienceCompositionMetrics): + Share and index metrics for the attribute. + """ + + attribute_metadata: ( + audience_insights_attribute.AudienceInsightsAttributeMetadata + ) = proto.Field( + proto.MESSAGE, + number=3, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + metrics: "AudienceCompositionMetrics" = proto.Field( + proto.MESSAGE, + number=2, + message="AudienceCompositionMetrics", + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/audience_service.py b/google/ads/googleads/v23/services/types/audience_service.py similarity index 89% rename from google/ads/googleads/v19/services/types/audience_service.py rename to google/ads/googleads/v23/services/types/audience_service.py index 4c97f00a7..366df6669 100644 --- a/google/ads/googleads/v19/services/types/audience_service.py +++ b/google/ads/googleads/v23/services/types/audience_service.py @@ -19,17 +19,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import audience as gagr_audience +from google.ads.googleads.v23.resources.types import audience as gagr_audience from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateAudiencesRequest", "MutateAudiencesResponse", @@ -41,13 +41,13 @@ class MutateAudiencesRequest(proto.Message): r"""Request message for - [AudienceService.MutateAudiences][google.ads.googleads.v19.services.AudienceService.MutateAudiences]. + [AudienceService.MutateAudiences][google.ads.googleads.v23.services.AudienceService.MutateAudiences]. Attributes: customer_id (str): Required. The ID of the customer whose audiences are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.AudienceOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.AudienceOperation]): Required. The list of operations to perform on individual audiences. partial_failure (bool): @@ -59,7 +59,7 @@ class MutateAudiencesRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -95,7 +95,7 @@ class MutateAudiencesResponse(proto.Message): r"""Response message for an audience mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateAudienceResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateAudienceResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -131,12 +131,12 @@ class AudienceOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.Audience): + create (google.ads.googleads.v23.resources.types.Audience): Create operation: No resource name is expected for the new audience This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.Audience): + update (google.ads.googleads.v23.resources.types.Audience): Update operation: The audience is expected to have a valid resource name. @@ -168,7 +168,7 @@ class MutateAudienceResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - audience (google.ads.googleads.v19.resources.types.Audience): + audience (google.ads.googleads.v23.resources.types.Audience): The mutated Audience with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v23/services/types/automatically_created_asset_removal_service.py b/google/ads/googleads/v23/services/types/automatically_created_asset_removal_service.py new file mode 100644 index 000000000..8078f2f7c --- /dev/null +++ b/google/ads/googleads/v23/services/types/automatically_created_asset_removal_service.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.enums.types import asset_field_type +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", + manifest={ + "RemoveCampaignAutomaticallyCreatedAssetRequest", + "RemoveCampaignAutomaticallyCreatedAssetOperation", + "RemoveCampaignAutomaticallyCreatedAssetResponse", + }, +) + + +class RemoveCampaignAutomaticallyCreatedAssetRequest(proto.Message): + r"""Request message for + [AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset][google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose assets + are being removed. + operations (MutableSequence[google.ads.googleads.v23.services.types.RemoveCampaignAutomaticallyCreatedAssetOperation]): + Required. The list of operations. + partial_failure (bool): + Required. If true, successful operations will + be carried out and invalid operations will + return errors. If false, all operations will be + carried out in one transaction if and only if + they are all valid. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + operations: MutableSequence[ + "RemoveCampaignAutomaticallyCreatedAssetOperation" + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="RemoveCampaignAutomaticallyCreatedAssetOperation", + ) + partial_failure: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class RemoveCampaignAutomaticallyCreatedAssetOperation(proto.Message): + r"""A single operation to remove an automatically created asset + from a campaign. + + Attributes: + campaign (str): + Required. The resource name of the campaign. + asset (str): + Required. The resource name of the asset to + remove. + field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): + Required. The field type of the asset to + remove. + """ + + campaign: str = proto.Field( + proto.STRING, + number=1, + ) + asset: str = proto.Field( + proto.STRING, + number=2, + ) + field_type: asset_field_type.AssetFieldTypeEnum.AssetFieldType = ( + proto.Field( + proto.ENUM, + number=3, + enum=asset_field_type.AssetFieldTypeEnum.AssetFieldType, + ) + ) + + +class RemoveCampaignAutomaticallyCreatedAssetResponse(proto.Message): + r"""Response message for + [AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset][google.ads.googleads.v23.services.AutomaticallyCreatedAssetRemovalService.RemoveCampaignAutomaticallyCreatedAsset]. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to + AutomaticallyCreatedAssetRemoval failures in the + partial failure mode. Returned when all errors + occur inside the operations. If any errors occur + outside the operations (for example, auth + errors), RPC level error will be returned. See + https://developers.google.com/google-ads/api/docs/best-practices/partial-failures + for more information about partial failure. + """ + + partial_failure_error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/batch_job_service.py b/google/ads/googleads/v23/services/types/batch_job_service.py similarity index 87% rename from google/ads/googleads/v19/services/types/batch_job_service.py rename to google/ads/googleads/v23/services/types/batch_job_service.py index 798b35c71..0139c1d24 100644 --- a/google/ads/googleads/v19/services/types/batch_job_service.py +++ b/google/ads/googleads/v23/services/types/batch_job_service.py @@ -19,17 +19,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import batch_job -from google.ads.googleads.v19.services.types import google_ads_service +from google.ads.googleads.v23.resources.types import batch_job +from google.ads.googleads.v23.services.types import google_ads_service from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateBatchJobRequest", "BatchJobOperation", @@ -47,13 +47,13 @@ class MutateBatchJobRequest(proto.Message): r"""Request message for - [BatchJobService.MutateBatchJob][google.ads.googleads.v19.services.BatchJobService.MutateBatchJob]. + [BatchJobService.MutateBatchJob][google.ads.googleads.v23.services.BatchJobService.MutateBatchJob]. Attributes: customer_id (str): Required. The ID of the customer for which to create a batch job. - operation (google.ads.googleads.v19.services.types.BatchJobOperation): + operation (google.ads.googleads.v23.services.types.BatchJobOperation): Required. The operation to perform on an individual batch job. """ @@ -80,7 +80,7 @@ class BatchJobOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.BatchJob): + create (google.ads.googleads.v23.resources.types.BatchJob): Create operation: No resource name is expected for the new batch job. @@ -110,10 +110,10 @@ class BatchJobOperation(proto.Message): class MutateBatchJobResponse(proto.Message): r"""Response message for - [BatchJobService.MutateBatchJob][google.ads.googleads.v19.services.BatchJobService.MutateBatchJob]. + [BatchJobService.MutateBatchJob][google.ads.googleads.v23.services.BatchJobService.MutateBatchJob]. Attributes: - result (google.ads.googleads.v19.services.types.MutateBatchJobResult): + result (google.ads.googleads.v23.services.types.MutateBatchJobResult): The result for the mutate. """ @@ -140,7 +140,7 @@ class MutateBatchJobResult(proto.Message): class RunBatchJobRequest(proto.Message): r"""Request message for - [BatchJobService.RunBatchJob][google.ads.googleads.v19.services.BatchJobService.RunBatchJob]. + [BatchJobService.RunBatchJob][google.ads.googleads.v23.services.BatchJobService.RunBatchJob]. Attributes: resource_name (str): @@ -156,7 +156,7 @@ class RunBatchJobRequest(proto.Message): class AddBatchJobOperationsRequest(proto.Message): r"""Request message for - [BatchJobService.AddBatchJobOperations][google.ads.googleads.v19.services.BatchJobService.AddBatchJobOperations]. + [BatchJobService.AddBatchJobOperations][google.ads.googleads.v23.services.BatchJobService.AddBatchJobOperations]. Attributes: resource_name (str): @@ -168,7 +168,7 @@ class AddBatchJobOperationsRequest(proto.Message): should not set sequence_token. Subsequent requests must set sequence_token to the value of next_sequence_token received in the previous AddBatchJobOperations response. - mutate_operations (MutableSequence[google.ads.googleads.v19.services.types.MutateOperation]): + mutate_operations (MutableSequence[google.ads.googleads.v23.services.types.MutateOperation]): Required. The list of mutates being added. Operations can use negative integers as temp ids @@ -202,7 +202,7 @@ class AddBatchJobOperationsRequest(proto.Message): class AddBatchJobOperationsResponse(proto.Message): r"""Response message for - [BatchJobService.AddBatchJobOperations][google.ads.googleads.v19.services.BatchJobService.AddBatchJobOperations]. + [BatchJobService.AddBatchJobOperations][google.ads.googleads.v23.services.BatchJobService.AddBatchJobOperations]. Attributes: total_operations (int): @@ -227,7 +227,7 @@ class AddBatchJobOperationsResponse(proto.Message): class ListBatchJobResultsRequest(proto.Message): r"""Request message for - [BatchJobService.ListBatchJobResults][google.ads.googleads.v19.services.BatchJobService.ListBatchJobResults]. + [BatchJobService.ListBatchJobResults][google.ads.googleads.v23.services.BatchJobService.ListBatchJobResults]. Attributes: resource_name (str): @@ -239,11 +239,12 @@ class ListBatchJobResultsRequest(proto.Message): from ``next_page_token`` in the previous response in order to request the next page of results. page_size (int): - Number of elements to retrieve in a single - page. When a page request is too large, the - server may decide to further limit the number of - returned resources. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + Number of elements to retrieve in a single page. The default + and the page_size limit is 1000. A value of 0 or an unset + page size will be defaulted to 1000. A page size less than 0 + or greater than 1000 will result in an INVALID_PAGE_SIZE + error. + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned. @@ -272,10 +273,10 @@ class ListBatchJobResultsRequest(proto.Message): class ListBatchJobResultsResponse(proto.Message): r"""Response message for - [BatchJobService.ListBatchJobResults][google.ads.googleads.v19.services.BatchJobService.ListBatchJobResults]. + [BatchJobService.ListBatchJobResults][google.ads.googleads.v23.services.BatchJobService.ListBatchJobResults]. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.BatchJobResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.BatchJobResult]): The list of rows that matched the query. next_page_token (str): Pagination token used to retrieve the next page of results. @@ -305,7 +306,7 @@ class BatchJobResult(proto.Message): Attributes: operation_index (int): Index of the mutate operation. - mutate_operation_response (google.ads.googleads.v19.services.types.MutateOperationResponse): + mutate_operation_response (google.ads.googleads.v23.services.types.MutateOperationResponse): Response for the mutate. May be empty if errors occurred. status (google.rpc.status_pb2.Status): diff --git a/google/ads/googleads/v23/services/types/benchmarks_service.py b/google/ads/googleads/v23/services/types/benchmarks_service.py new file mode 100644 index 000000000..a54551346 --- /dev/null +++ b/google/ads/googleads/v23/services/types/benchmarks_service.py @@ -0,0 +1,673 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import additional_application_info +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.common.types import dates +from google.ads.googleads.v23.enums.types import benchmarks_marketing_objective +from google.ads.googleads.v23.enums.types import ( + benchmarks_source_type as gage_benchmarks_source_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", + manifest={ + "ListBenchmarksAvailableDatesRequest", + "ListBenchmarksAvailableDatesResponse", + "ListBenchmarksLocationsRequest", + "ListBenchmarksLocationsResponse", + "BenchmarksLocation", + "ListBenchmarksProductsRequest", + "ListBenchmarksProductsResponse", + "BenchmarksProductMetadata", + "ListBenchmarksSourcesRequest", + "ListBenchmarksSourcesResponse", + "BenchmarksSourceMetadata", + "IndustryVerticalInfo", + "GenerateBenchmarksMetricsRequest", + "BenchmarksSource", + "ProductFilter", + "GenerateBenchmarksMetricsResponse", + "Metrics", + "RateMetrics", + }, +) + + +class ListBenchmarksAvailableDatesRequest(proto.Message): + r"""Request message for + [BenchmarksService.ListBenchmarksAvailableDates][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksAvailableDates]. + + Attributes: + application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Additional information on the application + issuing the request. + """ + + application_info: additional_application_info.AdditionalApplicationInfo = ( + proto.Field( + proto.MESSAGE, + number=1, + message=additional_application_info.AdditionalApplicationInfo, + ) + ) + + +class ListBenchmarksAvailableDatesResponse(proto.Message): + r"""Response message for + [BenchmarksService.ListBenchmarksAvailableDates][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksAvailableDates]. + + Attributes: + supported_dates (google.ads.googleads.v23.common.types.DateRange): + The dates that support benchmarks metrics. + Data is supported for any dates within this date + range inclusive. + """ + + supported_dates: dates.DateRange = proto.Field( + proto.MESSAGE, + number=1, + message=dates.DateRange, + ) + + +class ListBenchmarksLocationsRequest(proto.Message): + r"""Request message for + [BenchmarksService.ListBenchmarksLocations][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksLocations]. + + Attributes: + application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Additional information on the application + issuing the request. + """ + + application_info: additional_application_info.AdditionalApplicationInfo = ( + proto.Field( + proto.MESSAGE, + number=1, + message=additional_application_info.AdditionalApplicationInfo, + ) + ) + + +class ListBenchmarksLocationsResponse(proto.Message): + r"""Response message for + [BenchmarksService.ListBenchmarksLocations][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksLocations]. + + Attributes: + benchmarks_locations (MutableSequence[google.ads.googleads.v23.services.types.BenchmarksLocation]): + The list of locations supported for + benchmarks data. + """ + + benchmarks_locations: MutableSequence["BenchmarksLocation"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="BenchmarksLocation", + ) + ) + + +class BenchmarksLocation(proto.Message): + r"""A location that supports benchmarks data. + + Attributes: + location_name (str): + The unique location name in English. + location_type (str): + The location's type. Location types correspond to + target_type returned by searching location type in + GoogleAdsService.Search/SearchStream. + location_info (google.ads.googleads.v23.common.types.LocationInfo): + Information on the geographic location, + including the location ID. + """ + + location_name: str = proto.Field( + proto.STRING, + number=1, + ) + location_type: str = proto.Field( + proto.STRING, + number=2, + ) + location_info: criteria.LocationInfo = proto.Field( + proto.MESSAGE, + number=3, + message=criteria.LocationInfo, + ) + + +class ListBenchmarksProductsRequest(proto.Message): + r"""Request message for + [BenchmarksService.ListBenchmarksProducts][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksProducts]. + + Attributes: + application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Additional information on the application + issuing the request. + """ + + application_info: additional_application_info.AdditionalApplicationInfo = ( + proto.Field( + proto.MESSAGE, + number=1, + message=additional_application_info.AdditionalApplicationInfo, + ) + ) + + +class ListBenchmarksProductsResponse(proto.Message): + r"""Response message for + [BenchmarksService.ListBenchmarksProducts][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksProducts]. + + Attributes: + benchmarks_products (MutableSequence[google.ads.googleads.v23.services.types.BenchmarksProductMetadata]): + The list of products available for benchmarks + data. + """ + + benchmarks_products: MutableSequence["BenchmarksProductMetadata"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="BenchmarksProductMetadata", + ) + ) + + +class BenchmarksProductMetadata(proto.Message): + r"""The metadata associated with a product supported for + benchmarks data. + + Attributes: + product_name (str): + The name of the product. + product_code (str): + The identifier of the product. The identifier can be used as + inputs for + [BenchmarksService.GenerateBenchmarksMetrics][google.ads.googleads.v23.services.BenchmarksService.GenerateBenchmarksMetrics]. + marketing_objective (google.ads.googleads.v23.enums.types.BenchmarksMarketingObjectiveEnum.BenchmarksMarketingObjective): + The marketing objective associated with the + product. A marketing objective is a broader + classification of products. + """ + + product_name: str = proto.Field( + proto.STRING, + number=1, + ) + product_code: str = proto.Field( + proto.STRING, + number=2, + ) + marketing_objective: ( + benchmarks_marketing_objective.BenchmarksMarketingObjectiveEnum.BenchmarksMarketingObjective + ) = proto.Field( + proto.ENUM, + number=3, + enum=benchmarks_marketing_objective.BenchmarksMarketingObjectiveEnum.BenchmarksMarketingObjective, + ) + + +class ListBenchmarksSourcesRequest(proto.Message): + r"""Request message for + [BenchmarksService.ListBenchmarksSources][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksSources]. + + Attributes: + benchmarks_sources (MutableSequence[google.ads.googleads.v23.enums.types.BenchmarksSourceTypeEnum.BenchmarksSourceType]): + Required. The types of benchmarks sources to be returned + (for example, INDUSTRY_VERTICAL). + application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Additional information on the application + issuing the request. + """ + + benchmarks_sources: MutableSequence[ + gage_benchmarks_source_type.BenchmarksSourceTypeEnum.BenchmarksSourceType + ] = proto.RepeatedField( + proto.ENUM, + number=1, + enum=gage_benchmarks_source_type.BenchmarksSourceTypeEnum.BenchmarksSourceType, + ) + application_info: additional_application_info.AdditionalApplicationInfo = ( + proto.Field( + proto.MESSAGE, + number=2, + message=additional_application_info.AdditionalApplicationInfo, + ) + ) + + +class ListBenchmarksSourcesResponse(proto.Message): + r"""Response message for + [BenchmarksService.ListBenchmarksSources][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksSources]. + + Attributes: + benchmarks_sources (MutableSequence[google.ads.googleads.v23.services.types.BenchmarksSourceMetadata]): + The list of available source used to generate + benchmarks data for. + """ + + benchmarks_sources: MutableSequence["BenchmarksSourceMetadata"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="BenchmarksSourceMetadata", + ) + ) + + +class BenchmarksSourceMetadata(proto.Message): + r"""The metadata associated with a benchmarks source. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + benchmarks_source_type (google.ads.googleads.v23.enums.types.BenchmarksSourceTypeEnum.BenchmarksSourceType): + The type of benchmarks source. + industry_vertical_info (google.ads.googleads.v23.services.types.IndustryVerticalInfo): + Information on the Industry Vertical. + + This field is a member of `oneof`_ ``benchmarks_source_info``. + """ + + benchmarks_source_type: ( + gage_benchmarks_source_type.BenchmarksSourceTypeEnum.BenchmarksSourceType + ) = proto.Field( + proto.ENUM, + number=1, + enum=gage_benchmarks_source_type.BenchmarksSourceTypeEnum.BenchmarksSourceType, + ) + industry_vertical_info: "IndustryVerticalInfo" = proto.Field( + proto.MESSAGE, + number=2, + oneof="benchmarks_source_info", + message="IndustryVerticalInfo", + ) + + +class IndustryVerticalInfo(proto.Message): + r"""The information associated with an Industry Vertical. + + Attributes: + industry_vertical_name (str): + The name of the Industry Vertical. + industry_vertical_id (int): + The unique identifier of the Industry + Vertical. + parent_industry_vertical_id (int): + The unique identifier of the parent Industry + Vertical, if exists. + """ + + industry_vertical_name: str = proto.Field( + proto.STRING, + number=1, + ) + industry_vertical_id: int = proto.Field( + proto.INT64, + number=2, + ) + parent_industry_vertical_id: int = proto.Field( + proto.INT64, + number=3, + ) + + +class GenerateBenchmarksMetricsRequest(proto.Message): + r"""Request message for + [BenchmarksService.GenerateBenchmarksMetrics][google.ads.googleads.v23.services.BenchmarksService.GenerateBenchmarksMetrics]. + + Attributes: + customer_id (str): + Required. The ID of the customer. Supply a + client customer ID to generate metrics for the + customer. A manager account customer ID will not + return customer metrics since it does not have + any associated direct ad campaigns. + date_range (google.ads.googleads.v23.common.types.DateRange): + The date range to aggregate metrics over. If unset, data + will be returned for the most recent quarter for which data + is available. Dates can be retrieved using + [BenchmarksService.ListBenchmarksAvailableDates][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksAvailableDates]. + location (google.ads.googleads.v23.common.types.LocationInfo): + Required. The location to generate benchmarks + metrics for. + benchmarks_source (google.ads.googleads.v23.services.types.BenchmarksSource): + Required. The source used to generate + benchmarks metrics for. + product_filter (google.ads.googleads.v23.services.types.ProductFilter): + Required. The products to aggregate metrics + over. Product filter settings support a list of + product IDs or a list of marketing objectives. + currency_code (str): + Optional. The three-character ISO 4217 + currency code. If unspecified, the default + currency for monetary values is USD. + customer_benchmarks_group (str): + The name of the customer being planned for. + This is a user-defined value. + application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Additional information on the application + issuing the request. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + date_range: dates.DateRange = proto.Field( + proto.MESSAGE, + number=2, + message=dates.DateRange, + ) + location: criteria.LocationInfo = proto.Field( + proto.MESSAGE, + number=3, + message=criteria.LocationInfo, + ) + benchmarks_source: "BenchmarksSource" = proto.Field( + proto.MESSAGE, + number=4, + message="BenchmarksSource", + ) + product_filter: "ProductFilter" = proto.Field( + proto.MESSAGE, + number=5, + message="ProductFilter", + ) + currency_code: str = proto.Field( + proto.STRING, + number=6, + ) + customer_benchmarks_group: str = proto.Field( + proto.STRING, + number=7, + ) + application_info: additional_application_info.AdditionalApplicationInfo = ( + proto.Field( + proto.MESSAGE, + number=8, + message=additional_application_info.AdditionalApplicationInfo, + ) + ) + + +class BenchmarksSource(proto.Message): + r"""The source used to generate benchmarks metrics for. The ID of the + source can be obtained from + [BenchmarksService.ListBenchmarksSources][google.ads.googleads.v23.services.BenchmarksService.ListBenchmarksSources]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + industry_vertical_id (int): + The ID of the Industry Vertical. + + This field is a member of `oneof`_ ``benchmarks_source_id``. + """ + + industry_vertical_id: int = proto.Field( + proto.INT64, + number=1, + oneof="benchmarks_source_id", + ) + + +class ProductFilter(proto.Message): + r"""The type and list of products to aggregate benchmarks metrics + over. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + product_list (google.ads.googleads.v23.services.types.ProductFilter.ProductList): + The list of products. + + This field is a member of `oneof`_ ``filter_settings``. + marketing_objective_list (google.ads.googleads.v23.services.types.ProductFilter.MarketingObjectiveList): + The list of marketing goals. Marketing + objective is a broader product classification of + products. + + This field is a member of `oneof`_ ``filter_settings``. + """ + + class ProductList(proto.Message): + r"""The list of products to generate benchmarks metrics for. + + Attributes: + product_codes (MutableSequence[str]): + Required. Products to generate benchmarks + metrics for. + """ + + product_codes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class MarketingObjectiveList(proto.Message): + r"""The list of marketing objectives to generate benchmarks + metrics for. + + Attributes: + marketing_objectives (MutableSequence[google.ads.googleads.v23.enums.types.BenchmarksMarketingObjectiveEnum.BenchmarksMarketingObjective]): + Required. Marketing objectives to generate + benchmarks metrics for. + """ + + marketing_objectives: MutableSequence[ + benchmarks_marketing_objective.BenchmarksMarketingObjectiveEnum.BenchmarksMarketingObjective + ] = proto.RepeatedField( + proto.ENUM, + number=1, + enum=benchmarks_marketing_objective.BenchmarksMarketingObjectiveEnum.BenchmarksMarketingObjective, + ) + + product_list: ProductList = proto.Field( + proto.MESSAGE, + number=1, + oneof="filter_settings", + message=ProductList, + ) + marketing_objective_list: MarketingObjectiveList = proto.Field( + proto.MESSAGE, + number=2, + oneof="filter_settings", + message=MarketingObjectiveList, + ) + + +class GenerateBenchmarksMetricsResponse(proto.Message): + r"""Response message for + [BenchmarksService.GenerateBenchmarksMetrics][google.ads.googleads.v23.services.BenchmarksService.GenerateBenchmarksMetrics]. + + Attributes: + customer_metrics (google.ads.googleads.v23.services.types.Metrics): + Metrics belonging to the customer. + average_benchmarks_metrics (google.ads.googleads.v23.services.types.Metrics): + Metrics for the selected benchmarks source. + """ + + customer_metrics: "Metrics" = proto.Field( + proto.MESSAGE, + number=1, + message="Metrics", + ) + average_benchmarks_metrics: "Metrics" = proto.Field( + proto.MESSAGE, + number=2, + message="Metrics", + ) + + +class Metrics(proto.Message): + r"""All metrics returned against a criteria. + + Attributes: + average_rate_metrics (google.ads.googleads.v23.services.types.RateMetrics): + Average rate metrics calculated by dividing + one metric by another. + """ + + average_rate_metrics: "RateMetrics" = proto.Field( + proto.MESSAGE, + number=1, + message="RateMetrics", + ) + + +class RateMetrics(proto.Message): + r"""Average rate metrics. Metrics that represent monetary values + are returned in USD by default, if unspecified in the request. + + Attributes: + average_cpm (float): + Average cost-per-thousand impressions (CPM). + average_active_view_cpm (float): + Average cost-per-thousand viewable + impressions. + trueview_average_cpv (float): + The average TrueView cost-per-view (CPV) is + defined by the total cost of all ad TrueView + views divided by the number of TrueView views. + average_cpc (float): + The average cost-per-click (CPC) is defined + by the total cost of all clicks divided by the + total number of clicks received. + average_cpi (float): + The average cost-per-interaction (CPI) is + defined by the total cost of all interactions + divided by the total number of interactions. + average_cpe (float): + The average cost-per-engagement (CPE) is + defined by the total cost of all ad engagements + divided by the total number of ad engagements. + interaction_rate (float): + How often people interact with your ad after + it is shown to them. This is the number of + interactions divided by the number of times your + ad is shown. + engagement_rate (float): + How often people engage with your ad after + it's shown to them. This is the number of ad + expansions divided by the number of times your + ad is shown. + active_view_viewability (float): + The percentage of time when your ad appeared + on an Active View enabled site (measurable + impressions) and was viewable (viewable + impressions). + trueview_view_rate (float): + Number of completed TrueView views divided by + the number of impressions. + click_through_rate (float): + The number of clicks your ad receives + (Clicks) divided by the number of times your ad + is shown (Impressions). + video_completion_p25_rate (float): + Percentage of impressions where the viewer + watched 25% of your video. + video_completion_p50_rate (float): + Percentage of impressions where the viewer + watched 50% of your video. + video_completion_p75_rate (float): + Percentage of impressions where the viewer + watched 75% of your video. + video_completion_p100_rate (float): + Percentage of impressions where the viewer + watched all of your video. + """ + + average_cpm: float = proto.Field( + proto.DOUBLE, + number=1, + ) + average_active_view_cpm: float = proto.Field( + proto.DOUBLE, + number=2, + ) + trueview_average_cpv: float = proto.Field( + proto.DOUBLE, + number=3, + ) + average_cpc: float = proto.Field( + proto.DOUBLE, + number=4, + ) + average_cpi: float = proto.Field( + proto.DOUBLE, + number=5, + ) + average_cpe: float = proto.Field( + proto.DOUBLE, + number=6, + ) + interaction_rate: float = proto.Field( + proto.DOUBLE, + number=7, + ) + engagement_rate: float = proto.Field( + proto.DOUBLE, + number=8, + ) + active_view_viewability: float = proto.Field( + proto.DOUBLE, + number=9, + ) + trueview_view_rate: float = proto.Field( + proto.DOUBLE, + number=10, + ) + click_through_rate: float = proto.Field( + proto.DOUBLE, + number=11, + ) + video_completion_p25_rate: float = proto.Field( + proto.DOUBLE, + number=12, + ) + video_completion_p50_rate: float = proto.Field( + proto.DOUBLE, + number=13, + ) + video_completion_p75_rate: float = proto.Field( + proto.DOUBLE, + number=14, + ) + video_completion_p100_rate: float = proto.Field( + proto.DOUBLE, + number=15, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/bidding_data_exclusion_service.py b/google/ads/googleads/v23/services/types/bidding_data_exclusion_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/bidding_data_exclusion_service.py rename to google/ads/googleads/v23/services/types/bidding_data_exclusion_service.py index c6cefafad..cd2e38509 100644 --- a/google/ads/googleads/v19/services/types/bidding_data_exclusion_service.py +++ b/google/ads/googleads/v23/services/types/bidding_data_exclusion_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( bidding_data_exclusion as gagr_bidding_data_exclusion, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateBiddingDataExclusionsRequest", "BiddingDataExclusionOperation", @@ -43,13 +43,13 @@ class MutateBiddingDataExclusionsRequest(proto.Message): r"""Request message for - [BiddingDataExclusionService.MutateBiddingDataExclusions][google.ads.googleads.v19.services.BiddingDataExclusionService.MutateBiddingDataExclusions]. + [BiddingDataExclusionService.MutateBiddingDataExclusions][google.ads.googleads.v23.services.BiddingDataExclusionService.MutateBiddingDataExclusions]. Attributes: customer_id (str): Required. ID of the customer whose data exclusions are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.BiddingDataExclusionOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.BiddingDataExclusionOperation]): Required. The list of operations to perform on individual data exclusions. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateBiddingDataExclusionsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class BiddingDataExclusionOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.BiddingDataExclusion): + create (google.ads.googleads.v23.resources.types.BiddingDataExclusion): Create operation: No resource name is expected for the new data exclusion. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.BiddingDataExclusion): + update (google.ads.googleads.v23.resources.types.BiddingDataExclusion): Update operation: The data exclusion is expected to have a valid resource name. @@ -163,7 +163,7 @@ class MutateBiddingDataExclusionsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateBiddingDataExclusionsResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateBiddingDataExclusionsResult]): All results for the mutate. """ @@ -187,7 +187,7 @@ class MutateBiddingDataExclusionsResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - bidding_data_exclusion (google.ads.googleads.v19.resources.types.BiddingDataExclusion): + bidding_data_exclusion (google.ads.googleads.v23.resources.types.BiddingDataExclusion): The mutated bidding data exclusion with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/bidding_seasonality_adjustment_service.py b/google/ads/googleads/v23/services/types/bidding_seasonality_adjustment_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/bidding_seasonality_adjustment_service.py rename to google/ads/googleads/v23/services/types/bidding_seasonality_adjustment_service.py index cf886e450..0c9530450 100644 --- a/google/ads/googleads/v19/services/types/bidding_seasonality_adjustment_service.py +++ b/google/ads/googleads/v23/services/types/bidding_seasonality_adjustment_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( bidding_seasonality_adjustment as gagr_bidding_seasonality_adjustment, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateBiddingSeasonalityAdjustmentsRequest", "BiddingSeasonalityAdjustmentOperation", @@ -43,13 +43,13 @@ class MutateBiddingSeasonalityAdjustmentsRequest(proto.Message): r"""Request message for - [BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments][google.ads.googleads.v19.services.BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments]. + [BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments][google.ads.googleads.v23.services.BiddingSeasonalityAdjustmentService.MutateBiddingSeasonalityAdjustments]. Attributes: customer_id (str): Required. ID of the customer whose seasonality adjustments are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.BiddingSeasonalityAdjustmentOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.BiddingSeasonalityAdjustmentOperation]): Required. The list of operations to perform on individual seasonality adjustments. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateBiddingSeasonalityAdjustmentsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class BiddingSeasonalityAdjustmentOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.BiddingSeasonalityAdjustment): + create (google.ads.googleads.v23.resources.types.BiddingSeasonalityAdjustment): Create operation: No resource name is expected for the new seasonality adjustment. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.BiddingSeasonalityAdjustment): + update (google.ads.googleads.v23.resources.types.BiddingSeasonalityAdjustment): Update operation: The seasonality adjustment is expected to have a valid resource name. @@ -167,7 +167,7 @@ class MutateBiddingSeasonalityAdjustmentsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateBiddingSeasonalityAdjustmentsResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateBiddingSeasonalityAdjustmentsResult]): All results for the mutate. """ @@ -191,7 +191,7 @@ class MutateBiddingSeasonalityAdjustmentsResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - bidding_seasonality_adjustment (google.ads.googleads.v19.resources.types.BiddingSeasonalityAdjustment): + bidding_seasonality_adjustment (google.ads.googleads.v23.resources.types.BiddingSeasonalityAdjustment): The mutated bidding seasonality adjustment with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/bidding_strategy_service.py b/google/ads/googleads/v23/services/types/bidding_strategy_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/bidding_strategy_service.py rename to google/ads/googleads/v23/services/types/bidding_strategy_service.py index e69d2129b..72fbf471a 100644 --- a/google/ads/googleads/v19/services/types/bidding_strategy_service.py +++ b/google/ads/googleads/v23/services/types/bidding_strategy_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( bidding_strategy as gagr_bidding_strategy, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateBiddingStrategiesRequest", "BiddingStrategyOperation", @@ -43,13 +43,13 @@ class MutateBiddingStrategiesRequest(proto.Message): r"""Request message for - [BiddingStrategyService.MutateBiddingStrategies][google.ads.googleads.v19.services.BiddingStrategyService.MutateBiddingStrategies]. + [BiddingStrategyService.MutateBiddingStrategies][google.ads.googleads.v23.services.BiddingStrategyService.MutateBiddingStrategies]. Attributes: customer_id (str): Required. The ID of the customer whose bidding strategies are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.BiddingStrategyOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.BiddingStrategyOperation]): Required. The list of operations to perform on individual bidding strategies. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateBiddingStrategiesRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class BiddingStrategyOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.BiddingStrategy): + create (google.ads.googleads.v23.resources.types.BiddingStrategy): Create operation: No resource name is expected for the new bidding strategy. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.BiddingStrategy): + update (google.ads.googleads.v23.resources.types.BiddingStrategy): Update operation: The bidding strategy is expected to have a valid resource name. @@ -163,7 +163,7 @@ class MutateBiddingStrategiesResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateBiddingStrategyResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateBiddingStrategyResult]): All results for the mutate. """ @@ -187,7 +187,7 @@ class MutateBiddingStrategyResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - bidding_strategy (google.ads.googleads.v19.resources.types.BiddingStrategy): + bidding_strategy (google.ads.googleads.v23.resources.types.BiddingStrategy): The mutated bidding strategy with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/billing_setup_service.py b/google/ads/googleads/v23/services/types/billing_setup_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/billing_setup_service.py rename to google/ads/googleads/v23/services/types/billing_setup_service.py index 609ac7152..2221b9949 100644 --- a/google/ads/googleads/v19/services/types/billing_setup_service.py +++ b/google/ads/googleads/v23/services/types/billing_setup_service.py @@ -18,12 +18,12 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import billing_setup +from google.ads.googleads.v23.resources.types import billing_setup __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateBillingSetupRequest", "BillingSetupOperation", @@ -40,7 +40,7 @@ class MutateBillingSetupRequest(proto.Message): customer_id (str): Required. Id of the customer to apply the billing setup mutate operation to. - operation (google.ads.googleads.v19.services.types.BillingSetupOperation): + operation (google.ads.googleads.v23.services.types.BillingSetupOperation): Required. The operation to perform. """ @@ -67,7 +67,7 @@ class BillingSetupOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.BillingSetup): + create (google.ads.googleads.v23.resources.types.BillingSetup): Creates a billing setup. No resource name is expected for the new billing setup. @@ -98,7 +98,7 @@ class MutateBillingSetupResponse(proto.Message): r"""Response message for a billing setup operation. Attributes: - result (google.ads.googleads.v19.services.types.MutateBillingSetupResult): + result (google.ads.googleads.v23.services.types.MutateBillingSetupResult): A result that identifies the resource affected by the mutate request. """ diff --git a/google/ads/googleads/v19/services/types/brand_suggestion_service.py b/google/ads/googleads/v23/services/types/brand_suggestion_service.py similarity index 89% rename from google/ads/googleads/v19/services/types/brand_suggestion_service.py rename to google/ads/googleads/v23/services/types/brand_suggestion_service.py index 8ea7160a8..8b632ccb0 100644 --- a/google/ads/googleads/v19/services/types/brand_suggestion_service.py +++ b/google/ads/googleads/v23/services/types/brand_suggestion_service.py @@ -19,12 +19,12 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import brand_state +from google.ads.googleads.v23.enums.types import brand_state __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "SuggestBrandsRequest", "SuggestBrandsResponse", @@ -35,7 +35,7 @@ class SuggestBrandsRequest(proto.Message): r"""Request message for - [BrandSuggestionService.SuggestBrands][google.ads.googleads.v19.services.BrandSuggestionService.SuggestBrands]. + [BrandSuggestionService.SuggestBrands][google.ads.googleads.v23.services.BrandSuggestionService.SuggestBrands]. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -72,10 +72,10 @@ class SuggestBrandsRequest(proto.Message): class SuggestBrandsResponse(proto.Message): r"""Response message for - [BrandSuggestionService.SuggestBrands][google.ads.googleads.v19.services.BrandSuggestionService.SuggestBrands]. + [BrandSuggestionService.SuggestBrands][google.ads.googleads.v23.services.BrandSuggestionService.SuggestBrands]. Attributes: - brands (MutableSequence[google.ads.googleads.v19.services.types.BrandSuggestion]): + brands (MutableSequence[google.ads.googleads.v23.services.types.BrandSuggestion]): Generated brand suggestions of verified brands for the given prefix. """ @@ -98,7 +98,7 @@ class BrandSuggestion(proto.Message): Name of the brand. urls (MutableSequence[str]): Urls which uniquely identify the brand. - state (google.ads.googleads.v19.enums.types.BrandStateEnum.BrandState): + state (google.ads.googleads.v23.enums.types.BrandStateEnum.BrandState): Current state of the brand. """ diff --git a/google/ads/googleads/v19/services/types/campaign_asset_service.py b/google/ads/googleads/v23/services/types/campaign_asset_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/campaign_asset_service.py rename to google/ads/googleads/v23/services/types/campaign_asset_service.py index f47fa94ec..ef1945d39 100644 --- a/google/ads/googleads/v19/services/types/campaign_asset_service.py +++ b/google/ads/googleads/v23/services/types/campaign_asset_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_asset as gagr_campaign_asset, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignAssetsRequest", "CampaignAssetOperation", @@ -43,13 +43,13 @@ class MutateCampaignAssetsRequest(proto.Message): r"""Request message for - [CampaignAssetService.MutateCampaignAssets][google.ads.googleads.v19.services.CampaignAssetService.MutateCampaignAssets]. + [CampaignAssetService.MutateCampaignAssets][google.ads.googleads.v23.services.CampaignAssetService.MutateCampaignAssets]. Attributes: customer_id (str): Required. The ID of the customer whose campaign assets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignAssetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignAssetOperation]): Required. The list of operations to perform on individual campaign assets. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateCampaignAssetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -108,12 +108,12 @@ class CampaignAssetOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CampaignAsset): + create (google.ads.googleads.v23.resources.types.CampaignAsset): Create operation: No resource name is expected for the new campaign asset. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CampaignAsset): + update (google.ads.googleads.v23.resources.types.CampaignAsset): Update operation: The campaign asset is expected to have a valid resource name. @@ -161,7 +161,7 @@ class MutateCampaignAssetsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignAssetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignAssetResult]): All results for the mutate. """ @@ -183,7 +183,7 @@ class MutateCampaignAssetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - campaign_asset (google.ads.googleads.v19.resources.types.CampaignAsset): + campaign_asset (google.ads.googleads.v23.resources.types.CampaignAsset): The mutated campaign asset with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/campaign_asset_set_service.py b/google/ads/googleads/v23/services/types/campaign_asset_set_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/campaign_asset_set_service.py rename to google/ads/googleads/v23/services/types/campaign_asset_set_service.py index e6a1550f2..504b8afe9 100644 --- a/google/ads/googleads/v19/services/types/campaign_asset_set_service.py +++ b/google/ads/googleads/v23/services/types/campaign_asset_set_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_asset_set as gagr_campaign_asset_set, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignAssetSetsRequest", "CampaignAssetSetOperation", @@ -42,13 +42,13 @@ class MutateCampaignAssetSetsRequest(proto.Message): r"""Request message for - [CampaignAssetSetService.MutateCampaignAssetSets][google.ads.googleads.v19.services.CampaignAssetSetService.MutateCampaignAssetSets]. + [CampaignAssetSetService.MutateCampaignAssetSets][google.ads.googleads.v23.services.CampaignAssetSetService.MutateCampaignAssetSets]. Attributes: customer_id (str): Required. The ID of the customer whose campaign asset sets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignAssetSetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignAssetSetOperation]): Required. The list of operations to perform on individual campaign asset sets. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateCampaignAssetSetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -105,7 +105,7 @@ class CampaignAssetSetOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.CampaignAssetSet): + create (google.ads.googleads.v23.resources.types.CampaignAssetSet): Create operation: No resource name is expected for the new campaign asset set. @@ -135,7 +135,7 @@ class MutateCampaignAssetSetsResponse(proto.Message): r"""Response message for a campaign asset set mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignAssetSetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignAssetSetResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -165,7 +165,7 @@ class MutateCampaignAssetSetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - campaign_asset_set (google.ads.googleads.v19.resources.types.CampaignAssetSet): + campaign_asset_set (google.ads.googleads.v23.resources.types.CampaignAssetSet): The mutated campaign asset set with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/campaign_bid_modifier_service.py b/google/ads/googleads/v23/services/types/campaign_bid_modifier_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/campaign_bid_modifier_service.py rename to google/ads/googleads/v23/services/types/campaign_bid_modifier_service.py index 3f4f80c34..d27d7a372 100644 --- a/google/ads/googleads/v19/services/types/campaign_bid_modifier_service.py +++ b/google/ads/googleads/v23/services/types/campaign_bid_modifier_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_bid_modifier as gagr_campaign_bid_modifier, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignBidModifiersRequest", "CampaignBidModifierOperation", @@ -43,13 +43,13 @@ class MutateCampaignBidModifiersRequest(proto.Message): r"""Request message for - [CampaignBidModifierService.MutateCampaignBidModifiers][google.ads.googleads.v19.services.CampaignBidModifierService.MutateCampaignBidModifiers]. + [CampaignBidModifierService.MutateCampaignBidModifiers][google.ads.googleads.v23.services.CampaignBidModifierService.MutateCampaignBidModifiers]. Attributes: customer_id (str): Required. ID of the customer whose campaign bid modifiers are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignBidModifierOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignBidModifierOperation]): Required. The list of operations to perform on individual campaign bid modifiers. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateCampaignBidModifiersRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class CampaignBidModifierOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CampaignBidModifier): + create (google.ads.googleads.v23.resources.types.CampaignBidModifier): Create operation: No resource name is expected for the new campaign bid modifier. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CampaignBidModifier): + update (google.ads.googleads.v23.resources.types.CampaignBidModifier): Update operation: The campaign bid modifier is expected to have a valid resource name. @@ -163,7 +163,7 @@ class MutateCampaignBidModifiersResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignBidModifierResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignBidModifierResult]): All results for the mutate. """ @@ -187,7 +187,7 @@ class MutateCampaignBidModifierResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - campaign_bid_modifier (google.ads.googleads.v19.resources.types.CampaignBidModifier): + campaign_bid_modifier (google.ads.googleads.v23.resources.types.CampaignBidModifier): The mutated campaign bid modifier with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/campaign_budget_service.py b/google/ads/googleads/v23/services/types/campaign_budget_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/campaign_budget_service.py rename to google/ads/googleads/v23/services/types/campaign_budget_service.py index 915bee1ff..311edec8f 100644 --- a/google/ads/googleads/v19/services/types/campaign_budget_service.py +++ b/google/ads/googleads/v23/services/types/campaign_budget_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_budget as gagr_campaign_budget, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignBudgetsRequest", "CampaignBudgetOperation", @@ -43,13 +43,13 @@ class MutateCampaignBudgetsRequest(proto.Message): r"""Request message for - [CampaignBudgetService.MutateCampaignBudgets][google.ads.googleads.v19.services.CampaignBudgetService.MutateCampaignBudgets]. + [CampaignBudgetService.MutateCampaignBudgets][google.ads.googleads.v23.services.CampaignBudgetService.MutateCampaignBudgets]. Attributes: customer_id (str): Required. The ID of the customer whose campaign budgets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignBudgetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignBudgetOperation]): Required. The list of operations to perform on individual campaign budgets. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateCampaignBudgetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class CampaignBudgetOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CampaignBudget): + create (google.ads.googleads.v23.resources.types.CampaignBudget): Create operation: No resource name is expected for the new budget. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CampaignBudget): + update (google.ads.googleads.v23.resources.types.CampaignBudget): Update operation: The campaign budget is expected to have a valid resource name. @@ -163,7 +163,7 @@ class MutateCampaignBudgetsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignBudgetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignBudgetResult]): All results for the mutate. """ @@ -187,7 +187,7 @@ class MutateCampaignBudgetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - campaign_budget (google.ads.googleads.v19.resources.types.CampaignBudget): + campaign_budget (google.ads.googleads.v23.resources.types.CampaignBudget): The mutated campaign budget with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/campaign_conversion_goal_service.py b/google/ads/googleads/v23/services/types/campaign_conversion_goal_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/campaign_conversion_goal_service.py rename to google/ads/googleads/v23/services/types/campaign_conversion_goal_service.py index 10bc542e5..c747eae8a 100644 --- a/google/ads/googleads/v19/services/types/campaign_conversion_goal_service.py +++ b/google/ads/googleads/v23/services/types/campaign_conversion_goal_service.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import campaign_conversion_goal +from google.ads.googleads.v23.resources.types import campaign_conversion_goal from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignConversionGoalsRequest", "CampaignConversionGoalOperation", @@ -37,13 +37,13 @@ class MutateCampaignConversionGoalsRequest(proto.Message): r"""Request message for - [CampaignConversionGoalService.MutateCampaignConversionGoals][google.ads.googleads.v19.services.CampaignConversionGoalService.MutateCampaignConversionGoals]. + [CampaignConversionGoalService.MutateCampaignConversionGoals][google.ads.googleads.v23.services.CampaignConversionGoalService.MutateCampaignConversionGoals]. Attributes: customer_id (str): Required. The ID of the customer whose campaign conversion goals are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignConversionGoalOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignConversionGoalOperation]): Required. The list of operations to perform on individual campaign conversion goal. validate_only (bool): @@ -77,7 +77,7 @@ class CampaignConversionGoalOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - update (google.ads.googleads.v19.resources.types.CampaignConversionGoal): + update (google.ads.googleads.v23.resources.types.CampaignConversionGoal): Update operation: The customer conversion goal is expected to have a valid resource name. @@ -101,7 +101,7 @@ class MutateCampaignConversionGoalsResponse(proto.Message): r"""Response message for a campaign conversion goal mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignConversionGoalResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignConversionGoalResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/campaign_criterion_service.py b/google/ads/googleads/v23/services/types/campaign_criterion_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/campaign_criterion_service.py rename to google/ads/googleads/v23/services/types/campaign_criterion_service.py index 353f8c14f..a83a830dc 100644 --- a/google/ads/googleads/v19/services/types/campaign_criterion_service.py +++ b/google/ads/googleads/v23/services/types/campaign_criterion_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_criterion as gagr_campaign_criterion, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignCriteriaRequest", "CampaignCriterionOperation", @@ -43,13 +43,13 @@ class MutateCampaignCriteriaRequest(proto.Message): r"""Request message for - [CampaignCriterionService.MutateCampaignCriteria][google.ads.googleads.v19.services.CampaignCriterionService.MutateCampaignCriteria]. + [CampaignCriterionService.MutateCampaignCriteria][google.ads.googleads.v23.services.CampaignCriterionService.MutateCampaignCriteria]. Attributes: customer_id (str): Required. The ID of the customer whose criteria are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignCriterionOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignCriterionOperation]): Required. The list of operations to perform on individual criteria. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateCampaignCriteriaRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class CampaignCriterionOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CampaignCriterion): + create (google.ads.googleads.v23.resources.types.CampaignCriterion): Create operation: No resource name is expected for the new criterion. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CampaignCriterion): + update (google.ads.googleads.v23.resources.types.CampaignCriterion): Update operation: The criterion is expected to have a valid resource name. Note that for smart campaigns, you cannot use the update @@ -165,7 +165,7 @@ class MutateCampaignCriteriaResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignCriterionResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignCriterionResult]): All results for the mutate. """ @@ -189,7 +189,7 @@ class MutateCampaignCriterionResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - campaign_criterion (google.ads.googleads.v19.resources.types.CampaignCriterion): + campaign_criterion (google.ads.googleads.v23.resources.types.CampaignCriterion): The mutated campaign criterion with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/campaign_customizer_service.py b/google/ads/googleads/v23/services/types/campaign_customizer_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/campaign_customizer_service.py rename to google/ads/googleads/v23/services/types/campaign_customizer_service.py index cbc56ea16..40f38b650 100644 --- a/google/ads/googleads/v19/services/types/campaign_customizer_service.py +++ b/google/ads/googleads/v23/services/types/campaign_customizer_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_customizer as gagr_campaign_customizer, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignCustomizersRequest", "CampaignCustomizerOperation", @@ -42,13 +42,13 @@ class MutateCampaignCustomizersRequest(proto.Message): r"""Request message for - [CampaignCustomizerService.MutateCampaignCustomizers][google.ads.googleads.v19.services.CampaignCustomizerService.MutateCampaignCustomizers]. + [CampaignCustomizerService.MutateCampaignCustomizers][google.ads.googleads.v23.services.CampaignCustomizerService.MutateCampaignCustomizers]. Attributes: customer_id (str): Required. The ID of the customer whose campaign customizers are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignCustomizerOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignCustomizerOperation]): Required. The list of operations to perform on individual campaign customizers. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateCampaignCustomizersRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -106,7 +106,7 @@ class CampaignCustomizerOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.CampaignCustomizer): + create (google.ads.googleads.v23.resources.types.CampaignCustomizer): Create operation: No resource name is expected for the new campaign customizer @@ -136,7 +136,7 @@ class MutateCampaignCustomizersResponse(proto.Message): r"""Response message for a campaign customizer mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignCustomizerResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignCustomizerResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -166,7 +166,7 @@ class MutateCampaignCustomizerResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - campaign_customizer (google.ads.googleads.v19.resources.types.CampaignCustomizer): + campaign_customizer (google.ads.googleads.v23.resources.types.CampaignCustomizer): The mutated CampaignCustomizer with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/campaign_draft_service.py b/google/ads/googleads/v23/services/types/campaign_draft_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/campaign_draft_service.py rename to google/ads/googleads/v23/services/types/campaign_draft_service.py index cf377a0d1..8133526b4 100644 --- a/google/ads/googleads/v19/services/types/campaign_draft_service.py +++ b/google/ads/googleads/v23/services/types/campaign_draft_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_draft as gagr_campaign_draft, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignDraftsRequest", "PromoteCampaignDraftRequest", @@ -46,13 +46,13 @@ class MutateCampaignDraftsRequest(proto.Message): r"""Request message for - [CampaignDraftService.MutateCampaignDrafts][google.ads.googleads.v19.services.CampaignDraftService.MutateCampaignDrafts]. + [CampaignDraftService.MutateCampaignDrafts][google.ads.googleads.v23.services.CampaignDraftService.MutateCampaignDrafts]. Attributes: customer_id (str): Required. The ID of the customer whose campaign drafts are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignDraftOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignDraftOperation]): Required. The list of operations to perform on individual campaign drafts. partial_failure (bool): @@ -64,7 +64,7 @@ class MutateCampaignDraftsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -98,7 +98,7 @@ class MutateCampaignDraftsRequest(proto.Message): class PromoteCampaignDraftRequest(proto.Message): r"""Request message for - [CampaignDraftService.PromoteCampaignDraft][google.ads.googleads.v19.services.CampaignDraftService.PromoteCampaignDraft]. + [CampaignDraftService.PromoteCampaignDraft][google.ads.googleads.v23.services.CampaignDraftService.PromoteCampaignDraft]. Attributes: campaign_draft (str): @@ -135,12 +135,12 @@ class CampaignDraftOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CampaignDraft): + create (google.ads.googleads.v23.resources.types.CampaignDraft): Create operation: No resource name is expected for the new campaign draft. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CampaignDraft): + update (google.ads.googleads.v23.resources.types.CampaignDraft): Update operation: The campaign draft is expected to have a valid resource name. @@ -188,7 +188,7 @@ class MutateCampaignDraftsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignDraftResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignDraftResult]): All results for the mutate. """ @@ -210,7 +210,7 @@ class MutateCampaignDraftResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - campaign_draft (google.ads.googleads.v19.resources.types.CampaignDraft): + campaign_draft (google.ads.googleads.v23.resources.types.CampaignDraft): The mutated campaign draft with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". @@ -229,7 +229,7 @@ class MutateCampaignDraftResult(proto.Message): class ListCampaignDraftAsyncErrorsRequest(proto.Message): r"""Request message for - [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v19.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v23.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. Attributes: resource_name (str): @@ -263,7 +263,7 @@ class ListCampaignDraftAsyncErrorsRequest(proto.Message): class ListCampaignDraftAsyncErrorsResponse(proto.Message): r"""Response message for - [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v19.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. + [CampaignDraftService.ListCampaignDraftAsyncErrors][google.ads.googleads.v23.services.CampaignDraftService.ListCampaignDraftAsyncErrors]. Attributes: errors (MutableSequence[google.rpc.status_pb2.Status]): diff --git a/google/ads/googleads/v23/services/types/campaign_goal_config_service.py b/google/ads/googleads/v23/services/types/campaign_goal_config_service.py new file mode 100644 index 000000000..4f7a4cd4d --- /dev/null +++ b/google/ads/googleads/v23/services/types/campaign_goal_config_service.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.resources.types import campaign_goal_config +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", + manifest={ + "MutateCampaignGoalConfigsRequest", + "CampaignGoalConfigOperation", + "MutateCampaignGoalConfigsResponse", + "MutateCampaignGoalConfigResult", + }, +) + + +class MutateCampaignGoalConfigsRequest(proto.Message): + r"""Request message for + [CampaignGoalConfigService.MutateCampaignGoalConfigs][google.ads.googleads.v23.services.CampaignGoalConfigService.MutateCampaignGoalConfigs]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose + campaign goal configs are being modified. + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignGoalConfigOperation]): + Required. The list of operations to perform + on the campaign goal configs. + partial_failure (bool): + Optional. If true, successful operations will + be carried out and invalid operations will + return errors. If false, all operations will be + carried out in one transaction if and only if + they are all valid. Default is false. + validate_only (bool): + Optional. If true, the request is validated + but not executed. Only errors are returned, not + results. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + operations: MutableSequence["CampaignGoalConfigOperation"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=2, + message="CampaignGoalConfigOperation", + ) + ) + partial_failure: bool = proto.Field( + proto.BOOL, + number=3, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class CampaignGoalConfigOperation(proto.Message): + r"""A single mutate operation on the campaign goal config. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which fields are + modified in an update. + create (google.ads.googleads.v23.resources.types.CampaignGoalConfig): + Create a new campaign goal config. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v23.resources.types.CampaignGoalConfig): + Update an existing campaign goal config. + + This field is a member of `oneof`_ ``operation``. + remove (str): + Remove an existing campaign goal config. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + create: campaign_goal_config.CampaignGoalConfig = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=campaign_goal_config.CampaignGoalConfig, + ) + update: campaign_goal_config.CampaignGoalConfig = proto.Field( + proto.MESSAGE, + number=3, + oneof="operation", + message=campaign_goal_config.CampaignGoalConfig, + ) + remove: str = proto.Field( + proto.STRING, + number=2, + oneof="operation", + ) + + +class MutateCampaignGoalConfigsResponse(proto.Message): + r"""Response message for a campaign goal config mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in + the partial failure mode. + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignGoalConfigResult]): + All results for the mutate. + """ + + partial_failure_error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + results: MutableSequence["MutateCampaignGoalConfigResult"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=2, + message="MutateCampaignGoalConfigResult", + ) + ) + + +class MutateCampaignGoalConfigResult(proto.Message): + r"""The result for the campaign goal config mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/campaign_group_service.py b/google/ads/googleads/v23/services/types/campaign_group_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/campaign_group_service.py rename to google/ads/googleads/v23/services/types/campaign_group_service.py index 1507eaa87..0d3ff1014 100644 --- a/google/ads/googleads/v19/services/types/campaign_group_service.py +++ b/google/ads/googleads/v23/services/types/campaign_group_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_group as gagr_campaign_group, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignGroupsRequest", "CampaignGroupOperation", @@ -43,13 +43,13 @@ class MutateCampaignGroupsRequest(proto.Message): r"""Request message for - [CampaignGroupService.MutateCampaignGroups][google.ads.googleads.v19.services.CampaignGroupService.MutateCampaignGroups]. + [CampaignGroupService.MutateCampaignGroups][google.ads.googleads.v23.services.CampaignGroupService.MutateCampaignGroups]. Attributes: customer_id (str): Required. The ID of the customer whose campaign groups are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignGroupOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignGroupOperation]): Required. The list of operations to perform on individual campaign groups. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateCampaignGroupsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -108,12 +108,12 @@ class CampaignGroupOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CampaignGroup): + create (google.ads.googleads.v23.resources.types.CampaignGroup): Create operation: No resource name is expected for the new campaign group. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CampaignGroup): + update (google.ads.googleads.v23.resources.types.CampaignGroup): Update operation: The campaign group is expected to have a valid resource name. @@ -155,7 +155,7 @@ class MutateCampaignGroupsResponse(proto.Message): r"""Response message for campaign group mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignGroupResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignGroupResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -183,7 +183,7 @@ class MutateCampaignGroupResult(proto.Message): Attributes: resource_name (str): Required. Returned for successful operations. - campaign_group (google.ads.googleads.v19.resources.types.CampaignGroup): + campaign_group (google.ads.googleads.v23.resources.types.CampaignGroup): The mutated campaign group with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/campaign_label_service.py b/google/ads/googleads/v23/services/types/campaign_label_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/campaign_label_service.py rename to google/ads/googleads/v23/services/types/campaign_label_service.py index bbd9629c1..734e23c6a 100644 --- a/google/ads/googleads/v19/services/types/campaign_label_service.py +++ b/google/ads/googleads/v23/services/types/campaign_label_service.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import campaign_label +from google.ads.googleads.v23.resources.types import campaign_label from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignLabelsRequest", "CampaignLabelOperation", @@ -37,13 +37,13 @@ class MutateCampaignLabelsRequest(proto.Message): r"""Request message for - [CampaignLabelService.MutateCampaignLabels][google.ads.googleads.v19.services.CampaignLabelService.MutateCampaignLabels]. + [CampaignLabelService.MutateCampaignLabels][google.ads.googleads.v23.services.CampaignLabelService.MutateCampaignLabels]. Attributes: customer_id (str): Required. ID of the customer whose campaign-label relationships are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignLabelOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignLabelOperation]): Required. The list of operations to perform on campaign-label relationships. partial_failure (bool): @@ -88,7 +88,7 @@ class CampaignLabelOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.CampaignLabel): + create (google.ads.googleads.v23.resources.types.CampaignLabel): Create operation: No resource name is expected for the new campaign-label relationship. @@ -126,7 +126,7 @@ class MutateCampaignLabelsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignLabelResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignLabelResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/campaign_lifecycle_goal_service.py b/google/ads/googleads/v23/services/types/campaign_lifecycle_goal_service.py similarity index 85% rename from google/ads/googleads/v19/services/types/campaign_lifecycle_goal_service.py rename to google/ads/googleads/v23/services/types/campaign_lifecycle_goal_service.py index ebdfa2cfe..6850a0bbd 100644 --- a/google/ads/googleads/v19/services/types/campaign_lifecycle_goal_service.py +++ b/google/ads/googleads/v23/services/types/campaign_lifecycle_goal_service.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import campaign_lifecycle_goal +from google.ads.googleads.v23.resources.types import campaign_lifecycle_goal from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "ConfigureCampaignLifecycleGoalsRequest", "CampaignLifecycleGoalOperation", @@ -36,13 +36,13 @@ class ConfigureCampaignLifecycleGoalsRequest(proto.Message): r"""Request message for - [CampaignLifecycleGoalService.configureCampaignLifecycleGoals][]. + [CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals][google.ads.googleads.v23.services.CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals]. Attributes: customer_id (str): Required. The ID of the customer performing the upload. - operation (google.ads.googleads.v19.services.types.CampaignLifecycleGoalOperation): + operation (google.ads.googleads.v23.services.types.CampaignLifecycleGoalOperation): Required. The operation to perform campaign lifecycle goal update. validate_only (bool): @@ -80,13 +80,13 @@ class CampaignLifecycleGoalOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): Optional. FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CampaignLifecycleGoal): + create (google.ads.googleads.v23.resources.types.CampaignLifecycleGoal): Create operation: Create a new campaign lifecycle goal. The campaign field should be set for this operation. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CampaignLifecycleGoal): + update (google.ads.googleads.v23.resources.types.CampaignLifecycleGoal): Update operation: Update an existing campaign lifecycle goal. The campaign field should not be set for this operation. @@ -115,10 +115,10 @@ class CampaignLifecycleGoalOperation(proto.Message): class ConfigureCampaignLifecycleGoalsResponse(proto.Message): r"""Response message for - [CampaignLifecycleGoalService.configureCampaignLifecycleGoals][]. + [CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals][google.ads.googleads.v23.services.CampaignLifecycleGoalService.ConfigureCampaignLifecycleGoals]. Attributes: - result (google.ads.googleads.v19.services.types.ConfigureCampaignLifecycleGoalsResult): + result (google.ads.googleads.v23.services.types.ConfigureCampaignLifecycleGoalsResult): Result for the campaign lifecycle goal configuration. """ diff --git a/google/ads/googleads/v19/services/types/campaign_service.py b/google/ads/googleads/v23/services/types/campaign_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/campaign_service.py rename to google/ads/googleads/v23/services/types/campaign_service.py index a66341e7d..452e8474a 100644 --- a/google/ads/googleads/v19/services/types/campaign_service.py +++ b/google/ads/googleads/v23/services/types/campaign_service.py @@ -19,17 +19,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import campaign as gagr_campaign +from google.ads.googleads.v23.resources.types import campaign as gagr_campaign from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignsRequest", "CampaignOperation", @@ -46,13 +46,13 @@ class MutateCampaignsRequest(proto.Message): r"""Request message for - [CampaignService.MutateCampaigns][google.ads.googleads.v19.services.CampaignService.MutateCampaigns]. + [CampaignService.MutateCampaigns][google.ads.googleads.v23.services.CampaignService.MutateCampaigns]. Attributes: customer_id (str): Required. The ID of the customer whose campaigns are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignOperation]): Required. The list of operations to perform on individual campaigns. partial_failure (bool): @@ -64,7 +64,7 @@ class MutateCampaignsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class CampaignOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.Campaign): + create (google.ads.googleads.v23.resources.types.Campaign): Create operation: No resource name is expected for the new campaign. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.Campaign): + update (google.ads.googleads.v23.resources.types.Campaign): Update operation: The campaign is expected to have a valid resource name. @@ -163,7 +163,7 @@ class MutateCampaignsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignResult]): All results for the mutate. """ @@ -185,7 +185,7 @@ class MutateCampaignResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - campaign (google.ads.googleads.v19.resources.types.Campaign): + campaign (google.ads.googleads.v23.resources.types.Campaign): The mutated campaign with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". @@ -210,7 +210,7 @@ class EnablePMaxBrandGuidelinesRequest(proto.Message): customer_id (str): Required. The ID of the customer whose campaigns are being enabled. - operations (MutableSequence[google.ads.googleads.v19.services.types.EnableOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.EnableOperation]): Required. The list of individual campaign operations. A maximum of 10 enable operations can be executed in a request. @@ -239,7 +239,7 @@ class EnableOperation(proto.Message): top-performing brand assets. This field is required. If true, top-performing brand assets will be automatically populated. If false, the brand_assets field is required. - brand_assets (google.ads.googleads.v19.services.types.BrandCampaignAssets): + brand_assets (google.ads.googleads.v23.services.types.BrandCampaignAssets): Optional. The brand assets linked to the campaign. This field is required when the value of auto_populate_brand_assets is false. @@ -326,7 +326,7 @@ class EnablePMaxBrandGuidelinesResponse(proto.Message): r"""Brand Guidelines campaign enablement response. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.EnablementResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.EnablementResult]): Campaign enablement results per campaign. """ diff --git a/google/ads/googleads/v19/services/types/campaign_shared_set_service.py b/google/ads/googleads/v23/services/types/campaign_shared_set_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/campaign_shared_set_service.py rename to google/ads/googleads/v23/services/types/campaign_shared_set_service.py index 0eb10d94d..f227e75e8 100644 --- a/google/ads/googleads/v19/services/types/campaign_shared_set_service.py +++ b/google/ads/googleads/v23/services/types/campaign_shared_set_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_shared_set as gagr_campaign_shared_set, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCampaignSharedSetsRequest", "CampaignSharedSetOperation", @@ -42,13 +42,13 @@ class MutateCampaignSharedSetsRequest(proto.Message): r"""Request message for - [CampaignSharedSetService.MutateCampaignSharedSets][google.ads.googleads.v19.services.CampaignSharedSetService.MutateCampaignSharedSets]. + [CampaignSharedSetService.MutateCampaignSharedSets][google.ads.googleads.v23.services.CampaignSharedSetService.MutateCampaignSharedSets]. Attributes: customer_id (str): Required. The ID of the customer whose campaign shared sets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CampaignSharedSetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CampaignSharedSetOperation]): Required. The list of operations to perform on individual campaign shared sets. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateCampaignSharedSetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -105,7 +105,7 @@ class CampaignSharedSetOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.CampaignSharedSet): + create (google.ads.googleads.v23.resources.types.CampaignSharedSet): Create operation: No resource name is expected for the new campaign shared set. @@ -142,7 +142,7 @@ class MutateCampaignSharedSetsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCampaignSharedSetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCampaignSharedSetResult]): All results for the mutate. """ @@ -166,7 +166,7 @@ class MutateCampaignSharedSetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - campaign_shared_set (google.ads.googleads.v19.resources.types.CampaignSharedSet): + campaign_shared_set (google.ads.googleads.v23.resources.types.CampaignSharedSet): The mutated campaign shared set with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v23/services/types/content_creator_insights_service.py b/google/ads/googleads/v23/services/types/content_creator_insights_service.py new file mode 100644 index 000000000..8c825994f --- /dev/null +++ b/google/ads/googleads/v23/services/types/content_creator_insights_service.py @@ -0,0 +1,767 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import additional_application_info +from google.ads.googleads.v23.common.types import audience_insights_attribute +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.enums.types import insights_trend + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", + manifest={ + "GenerateCreatorInsightsRequest", + "GenerateCreatorInsightsResponse", + "GenerateTrendingInsightsRequest", + "GenerateTrendingInsightsResponse", + "YouTubeCreatorInsights", + "YouTubeMetrics", + "YouTubeChannelInsights", + "SearchAudience", + "SearchTopics", + "TrendInsight", + "TrendInsightMetrics", + "LanguageDistribution", + }, +) + + +class GenerateCreatorInsightsRequest(proto.Message): + r"""Request message for + [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateCreatorInsights]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + Required. The ID of the customer. + customer_insights_group (str): + Required. The name of the customer being + planned for. This is a user-defined value. + insights_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + country_locations (MutableSequence[google.ads.googleads.v23.common.types.LocationInfo]): + Required. The countries to search that apply + to the criteria. + sub_country_locations (MutableSequence[google.ads.googleads.v23.common.types.LocationInfo]): + The sub-country geographic locations to search that apply to + the criteria. Only supported for + [SearchAttributes][google.ads.googleads.v23.services.GenerateCreatorInsightsRequest.SearchAttributes] + criteria. + search_attributes (google.ads.googleads.v23.services.types.GenerateCreatorInsightsRequest.SearchAttributes): + The attributes used to identify top creators. Data fetched + is based on the list of countries or sub-country locations + specified in + [country_locations][google.ads.googleads.v23.services.GenerateCreatorInsightsRequest.country_locations] + or + [sub_country_locations][google.ads.googleads.v23.services.GenerateCreatorInsightsRequest.sub_country_locations]. + + This field is a member of `oneof`_ ``criteria``. + search_brand (google.ads.googleads.v23.services.types.GenerateCreatorInsightsRequest.SearchBrand): + A brand used to search for top creators. Data fetched is + based on the list of countries specified in + [country_locations][google.ads.googleads.v23.services.GenerateCreatorInsightsRequest.country_locations]. + + This field is a member of `oneof`_ ``criteria``. + search_channels (google.ads.googleads.v23.services.types.GenerateCreatorInsightsRequest.YouTubeChannels): + YouTube Channel IDs for Creator Insights. Data fetched for + channels is based on the list of countries specified in + [country_locations][google.ads.googleads.v23.services.GenerateCreatorInsightsRequest.country_locations]. + + This field is a member of `oneof`_ ``criteria``. + """ + + class SearchAttributes(proto.Message): + r"""The audience attributes (such as Age, Gender, Affinity, and + In-Market) and creator attributes (such as creator's content + topics) used to search for top creators. + + Attributes: + audience_attributes (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttribute]): + Optional. Audience attributes that describe an audience of + viewers. This is used to search for creators whose own + viewers match the input audience. Attributes age_range, + gender, user_interest, entity, category, device, + parental_status, and income_range are supported. Attribute + location is not supported. + creator_attributes (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttribute]): + Optional. Creator attributes that describe a collection of + types of content. This is used to search for creators whose + content matches the input creator attributes. Only Knowledge + Graph Entities tagged with + [CREATOR_ATTRIBUTE][google.ads.googleads.v23.enums.InsightsKnowledgeGraphEntityCapabilitiesEnum.InsightsKnowledgeGraphEntityCapabilities.CREATOR_ATTRIBUTE] + are supported. Use + [AudienceInsightsService.ListAudienceInsightsAttributes][google.ads.googleads.v23.services.AudienceInsightsService.ListAudienceInsightsAttributes] + to get the list of supported entities. Other attributes + including location are not supported. + """ + + audience_attributes: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttribute + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=audience_insights_attribute.AudienceInsightsAttribute, + ) + creator_attributes: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttribute + ] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=audience_insights_attribute.AudienceInsightsAttribute, + ) + + class SearchBrand(proto.Message): + r"""The brand used to search for top creators. + + Attributes: + brand_entities (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttribute]): + Optional. One or more Knowledge Graph + Entities that represent the brand for which to + find insights. + include_related_topics (bool): + Optional. When true, we will expand the search to beyond + just the entities specified in [brand_entities] to other + related knowledge graph entities similar to the brand. The + default value is ``false``. + """ + + brand_entities: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttribute + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=audience_insights_attribute.AudienceInsightsAttribute, + ) + include_related_topics: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class YouTubeChannels(proto.Message): + r"""A collection of YouTube Channels. + + Attributes: + youtube_channels (MutableSequence[google.ads.googleads.v23.common.types.YouTubeChannelInfo]): + Optional. The YouTube Channel IDs to fetch + creator insights for. + """ + + youtube_channels: MutableSequence[criteria.YouTubeChannelInfo] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message=criteria.YouTubeChannelInfo, + ) + ) + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + customer_insights_group: str = proto.Field( + proto.STRING, + number=2, + ) + insights_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=8, + message=additional_application_info.AdditionalApplicationInfo, + ) + country_locations: MutableSequence[criteria.LocationInfo] = ( + proto.RepeatedField( + proto.MESSAGE, + number=6, + message=criteria.LocationInfo, + ) + ) + sub_country_locations: MutableSequence[criteria.LocationInfo] = ( + proto.RepeatedField( + proto.MESSAGE, + number=7, + message=criteria.LocationInfo, + ) + ) + search_attributes: SearchAttributes = proto.Field( + proto.MESSAGE, + number=3, + oneof="criteria", + message=SearchAttributes, + ) + search_brand: SearchBrand = proto.Field( + proto.MESSAGE, + number=5, + oneof="criteria", + message=SearchBrand, + ) + search_channels: YouTubeChannels = proto.Field( + proto.MESSAGE, + number=4, + oneof="criteria", + message=YouTubeChannels, + ) + + +class GenerateCreatorInsightsResponse(proto.Message): + r"""Response message for + [ContentCreatorInsightsService.GenerateCreatorInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateCreatorInsights]. + + Attributes: + creator_insights (MutableSequence[google.ads.googleads.v23.services.types.YouTubeCreatorInsights]): + A collection of YouTube Creators, each + containing a collection of YouTube Channels + maintained by the YouTube Creator. + """ + + creator_insights: MutableSequence["YouTubeCreatorInsights"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="YouTubeCreatorInsights", + ) + ) + + +class GenerateTrendingInsightsRequest(proto.Message): + r"""Request message for + [ContentCreatorInsightsService.GenerateTrendingInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateTrendingInsights]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + Required. The ID of the customer. + customer_insights_group (str): + Required. The name of the customer being + planned for. This is a user-defined value. + insights_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + country_location (google.ads.googleads.v23.common.types.LocationInfo): + Required. The country to find trends in. + search_audience (google.ads.googleads.v23.services.types.SearchAudience): + An audience to search for trending content + in. + + This field is a member of `oneof`_ ``criteria``. + search_topics (google.ads.googleads.v23.services.types.SearchTopics): + Content topics to return trend information + for. + + This field is a member of `oneof`_ ``criteria``. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + customer_insights_group: str = proto.Field( + proto.STRING, + number=2, + ) + insights_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=6, + message=additional_application_info.AdditionalApplicationInfo, + ) + country_location: criteria.LocationInfo = proto.Field( + proto.MESSAGE, + number=3, + message=criteria.LocationInfo, + ) + search_audience: "SearchAudience" = proto.Field( + proto.MESSAGE, + number=4, + oneof="criteria", + message="SearchAudience", + ) + search_topics: "SearchTopics" = proto.Field( + proto.MESSAGE, + number=5, + oneof="criteria", + message="SearchTopics", + ) + + +class GenerateTrendingInsightsResponse(proto.Message): + r"""Response message for + [ContentCreatorInsightsService.GenerateTrendingInsights][google.ads.googleads.v23.services.ContentCreatorInsightsService.GenerateTrendingInsights]. + + Attributes: + trend_insights (MutableSequence[google.ads.googleads.v23.services.types.TrendInsight]): + The list of trending insights for the given + criteria. + """ + + trend_insights: MutableSequence["TrendInsight"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="TrendInsight", + ) + + +class YouTubeCreatorInsights(proto.Message): + r"""A YouTube creator and the insights for this creator. + + Attributes: + creator_name (str): + The name of the creator. + creator_channels (MutableSequence[google.ads.googleads.v23.services.types.YouTubeChannelInsights]): + The list of YouTube Channels + """ + + creator_name: str = proto.Field( + proto.STRING, + number=1, + ) + creator_channels: MutableSequence["YouTubeChannelInsights"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=2, + message="YouTubeChannelInsights", + ) + ) + + +class YouTubeMetrics(proto.Message): + r"""YouTube Channel metrics. + + Attributes: + subscriber_count (int): + The number of subscribers. + views_count (int): + The total number of views. + video_count (int): + The total number of videos. + likes_count (int): + The total number of likes across all videos + of this channel. + shares_count (int): + The total number of shares across all videos + of this channel. + comments_count (int): + The total number of comments across all + videos of this channel. + engagement_rate (float): + The lifetime engagement rate of this channel. + The value is computed as the total number of + likes, shares, and comments across all videos + divided by the total number of video views. + average_views_per_video (float): + The average number of views per video in the + last 28 days. + average_likes_per_video (float): + The average number of likes per video in the + last 28 days. + average_shares_per_video (float): + The average number of shares per video in the + last 28 days. + average_comments_per_video (float): + The average number of comments per video in + the last 28 days. + shorts_views_count (int): + The total number of views across all Shorts + videos of this channel. + shorts_video_count (int): + The total number of Shorts videos. + is_active_shorts_creator (bool): + When true, this channel has published a + Shorts video in the last 90 days. + is_active_live_stream_creator (bool): + When true, this channel has published a live + stream in the last 90 days. + is_brand_connect_creator (bool): + When true, this creator can be partnered with + to create original branded content using the + Google Ads creator partnership platform, + BrandConnect. + + See + https://support.google.com/google-ads/answer/13828964 + for more information about BrandConnect. + """ + + subscriber_count: int = proto.Field( + proto.INT64, + number=1, + ) + views_count: int = proto.Field( + proto.INT64, + number=2, + ) + video_count: int = proto.Field( + proto.INT64, + number=3, + ) + likes_count: int = proto.Field( + proto.INT64, + number=5, + ) + shares_count: int = proto.Field( + proto.INT64, + number=6, + ) + comments_count: int = proto.Field( + proto.INT64, + number=7, + ) + engagement_rate: float = proto.Field( + proto.DOUBLE, + number=8, + ) + average_views_per_video: float = proto.Field( + proto.DOUBLE, + number=9, + ) + average_likes_per_video: float = proto.Field( + proto.DOUBLE, + number=10, + ) + average_shares_per_video: float = proto.Field( + proto.DOUBLE, + number=11, + ) + average_comments_per_video: float = proto.Field( + proto.DOUBLE, + number=12, + ) + shorts_views_count: int = proto.Field( + proto.INT64, + number=13, + ) + shorts_video_count: int = proto.Field( + proto.INT64, + number=14, + ) + is_active_shorts_creator: bool = proto.Field( + proto.BOOL, + number=4, + ) + is_active_live_stream_creator: bool = proto.Field( + proto.BOOL, + number=16, + ) + is_brand_connect_creator: bool = proto.Field( + proto.BOOL, + number=15, + ) + + +class YouTubeChannelInsights(proto.Message): + r"""YouTube Channel insights, and its metadata (such as channel + name and channel ID), returned for a creator insights response. + + Attributes: + display_name (str): + The name of the YouTube Channel. + youtube_channel (google.ads.googleads.v23.common.types.YouTubeChannelInfo): + The YouTube Channel ID. + channel_url (str): + URL for the channel in the form of + https://www.youtube.com/channel/{channel_id}. + channel_description (str): + Description of the channel. + handle (str): + The unique, short, and user-visible + identifier for the channel starting with an "@" + symbol (such as "@youtubecreators"). See + https://support.google.com/youtube/answer/11585688 + for more information. + thumbnail_url (str): + URL for a 240px by 240px thumbnail image of + the channel. + publish_date (str): + The date that the channel was created. + Formatted as "yyyy-mm-dd". + country_location (google.ads.googleads.v23.common.types.LocationInfo): + The country with which the channel is + associated. + channel_metrics (google.ads.googleads.v23.services.types.YouTubeMetrics): + The metrics for a YouTube Channel. + channel_audience_attributes (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata]): + The types of audiences and demographics + linked to the channel's main audience. Audiences + and demographics have a breakdown of subscriber + share across dimensions of the same value, such + as Age Range, Gender, and User Interest. + channel_attributes (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata]): + The attributes associated with the content + made by a channel. + top_videos (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata]): + The top 10 videos for the channel. + language_distributions (MutableSequence[google.ads.googleads.v23.services.types.LanguageDistribution]): + The languages associated with the content + made by a channel. + channel_type (str): + Metadata string associated with the type of + channel. + relevance_score (float): + The relevance score of the channel to the topic being + searched for weighted by views. The value is between 0 and + 1, with 1 being the most relevant. Only populated for trends + using search_topics. + """ + + display_name: str = proto.Field( + proto.STRING, + number=1, + ) + youtube_channel: criteria.YouTubeChannelInfo = proto.Field( + proto.MESSAGE, + number=2, + message=criteria.YouTubeChannelInfo, + ) + channel_url: str = proto.Field( + proto.STRING, + number=9, + ) + channel_description: str = proto.Field( + proto.STRING, + number=10, + ) + handle: str = proto.Field( + proto.STRING, + number=11, + ) + thumbnail_url: str = proto.Field( + proto.STRING, + number=12, + ) + publish_date: str = proto.Field( + proto.STRING, + number=13, + ) + country_location: criteria.LocationInfo = proto.Field( + proto.MESSAGE, + number=14, + message=criteria.LocationInfo, + ) + channel_metrics: "YouTubeMetrics" = proto.Field( + proto.MESSAGE, + number=3, + message="YouTubeMetrics", + ) + channel_audience_attributes: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttributeMetadata + ] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + channel_attributes: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttributeMetadata + ] = proto.RepeatedField( + proto.MESSAGE, + number=5, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + top_videos: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttributeMetadata + ] = proto.RepeatedField( + proto.MESSAGE, + number=8, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + language_distributions: MutableSequence["LanguageDistribution"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=15, + message="LanguageDistribution", + ) + ) + channel_type: str = proto.Field( + proto.STRING, + number=6, + ) + relevance_score: float = proto.Field( + proto.DOUBLE, + number=16, + ) + + +class SearchAudience(proto.Message): + r"""A collection of audience attributes that describe an audience + of viewers. This is used to search for topics trending for the + defined audience. + + Attributes: + audience_attributes (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttribute]): + Required. Audience attributes that describe + an audience of viewers. This is used to search + for topics trending for the defined audience. + """ + + audience_attributes: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttribute + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=audience_insights_attribute.AudienceInsightsAttribute, + ) + + +class SearchTopics(proto.Message): + r"""A collection of content topics to return trend information + for. + + Attributes: + entities (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsEntity]): + Required. A list of knowledge graph entities to retrieve + trend information for. Supported entities are tagged with + [CONTENT_TRENDING_INSIGHTS][google.ads.googleads.v23.enums.InsightsKnowledgeGraphEntityCapabilitiesEnum.InsightsKnowledgeGraphEntityCapabilities.CONTENT_TRENDING_INSIGHTS]. + """ + + entities: MutableSequence[ + audience_insights_attribute.AudienceInsightsEntity + ] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=audience_insights_attribute.AudienceInsightsEntity, + ) + + +class TrendInsight(proto.Message): + r"""A trend insight for a given attribute. + + Attributes: + trend_attribute (google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata): + The attribute this trend is for. + trend_metrics (google.ads.googleads.v23.services.types.TrendInsightMetrics): + Metrics associated with this trend. + trend (google.ads.googleads.v23.enums.types.InsightsTrendEnum.InsightsTrend): + The direction of trend (such as RISING or + DECLINING). + related_videos (MutableSequence[google.ads.googleads.v23.common.types.AudienceInsightsAttributeMetadata]): + Related videos for this topic. Only populated for trends + using search_topics. + related_creators (MutableSequence[google.ads.googleads.v23.services.types.YouTubeCreatorInsights]): + Related creators for this topic. Only populated for trends + using search_topics. + """ + + trend_attribute: ( + audience_insights_attribute.AudienceInsightsAttributeMetadata + ) = proto.Field( + proto.MESSAGE, + number=1, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + trend_metrics: "TrendInsightMetrics" = proto.Field( + proto.MESSAGE, + number=2, + message="TrendInsightMetrics", + ) + trend: insights_trend.InsightsTrendEnum.InsightsTrend = proto.Field( + proto.ENUM, + number=3, + enum=insights_trend.InsightsTrendEnum.InsightsTrend, + ) + related_videos: MutableSequence[ + audience_insights_attribute.AudienceInsightsAttributeMetadata + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=audience_insights_attribute.AudienceInsightsAttributeMetadata, + ) + related_creators: MutableSequence["YouTubeCreatorInsights"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=5, + message="YouTubeCreatorInsights", + ) + ) + + +class TrendInsightMetrics(proto.Message): + r"""Metrics associated with a trend insight. + + Attributes: + views_count (int): + The number of views for this trend. This is + only populated for SearchTopics requests. + audience_share (float): + The fraction (from 0 to 1 inclusive) of the + requested audience that has has searched or + viewed this trend. This is only populated for + SearchAudience requests. + trend_change_percent (float): + The percentage of the change in the trend's + value over the comparison period, where 1.0 + represents 100%. If this is not set, it means + that the trend is emerging. + """ + + views_count: int = proto.Field( + proto.INT64, + number=1, + ) + audience_share: float = proto.Field( + proto.DOUBLE, + number=2, + ) + trend_change_percent: float = proto.Field( + proto.DOUBLE, + number=3, + ) + + +class LanguageDistribution(proto.Message): + r"""Languages that pertain to a YouTube channel based on the + channel content. Only languages above a certain proportion + threshold are included. + + Attributes: + language_code (str): + `Language + code `__ + of the language for the YouTube channel. + proportion (float): + The proportion (between 0 and 1) of the + channel's videos in the language. + """ + + language_code: str = proto.Field( + proto.STRING, + number=1, + ) + proportion: float = proto.Field( + proto.DOUBLE, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/conversion_action_service.py b/google/ads/googleads/v23/services/types/conversion_action_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/conversion_action_service.py rename to google/ads/googleads/v23/services/types/conversion_action_service.py index 961e3588e..fa3f30748 100644 --- a/google/ads/googleads/v19/services/types/conversion_action_service.py +++ b/google/ads/googleads/v23/services/types/conversion_action_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( conversion_action as gagr_conversion_action, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateConversionActionsRequest", "ConversionActionOperation", @@ -43,13 +43,13 @@ class MutateConversionActionsRequest(proto.Message): r"""Request message for - [ConversionActionService.MutateConversionActions][google.ads.googleads.v19.services.ConversionActionService.MutateConversionActions]. + [ConversionActionService.MutateConversionActions][google.ads.googleads.v23.services.ConversionActionService.MutateConversionActions]. Attributes: customer_id (str): Required. The ID of the customer whose conversion actions are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.ConversionActionOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.ConversionActionOperation]): Required. The list of operations to perform on individual conversion actions. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateConversionActionsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class ConversionActionOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.ConversionAction): + create (google.ads.googleads.v23.resources.types.ConversionAction): Create operation: No resource name is expected for the new conversion action. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.ConversionAction): + update (google.ads.googleads.v23.resources.types.ConversionAction): Update operation: The conversion action is expected to have a valid resource name. @@ -155,7 +155,7 @@ class ConversionActionOperation(proto.Message): class MutateConversionActionsResponse(proto.Message): r"""Response message for - [ConversionActionService.MutateConversionActions][google.ads.googleads.v19.services.ConversionActionService.MutateConversionActions]. + [ConversionActionService.MutateConversionActions][google.ads.googleads.v23.services.ConversionActionService.MutateConversionActions]. Attributes: partial_failure_error (google.rpc.status_pb2.Status): @@ -164,7 +164,7 @@ class MutateConversionActionsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateConversionActionResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateConversionActionResult]): All results for the mutate. """ @@ -188,7 +188,7 @@ class MutateConversionActionResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - conversion_action (google.ads.googleads.v19.resources.types.ConversionAction): + conversion_action (google.ads.googleads.v23.resources.types.ConversionAction): The mutated conversion action with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/conversion_adjustment_upload_service.py b/google/ads/googleads/v23/services/types/conversion_adjustment_upload_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/conversion_adjustment_upload_service.py rename to google/ads/googleads/v23/services/types/conversion_adjustment_upload_service.py index 5f600f173..5e0a484d7 100644 --- a/google/ads/googleads/v19/services/types/conversion_adjustment_upload_service.py +++ b/google/ads/googleads/v23/services/types/conversion_adjustment_upload_service.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import offline_user_data -from google.ads.googleads.v19.enums.types import conversion_adjustment_type +from google.ads.googleads.v23.common.types import offline_user_data +from google.ads.googleads.v23.enums.types import conversion_adjustment_type from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "UploadConversionAdjustmentsRequest", "UploadConversionAdjustmentsResponse", @@ -40,7 +40,7 @@ class UploadConversionAdjustmentsRequest(proto.Message): r"""Request message for - [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v19.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. + [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v23.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -49,7 +49,7 @@ class UploadConversionAdjustmentsRequest(proto.Message): customer_id (str): Required. The ID of the customer performing the upload. - conversion_adjustments (MutableSequence[google.ads.googleads.v19.services.types.ConversionAdjustment]): + conversion_adjustments (MutableSequence[google.ads.googleads.v23.services.types.ConversionAdjustment]): Required. The conversion adjustments that are being uploaded. partial_failure (bool): @@ -104,7 +104,7 @@ class UploadConversionAdjustmentsRequest(proto.Message): class UploadConversionAdjustmentsResponse(proto.Message): r"""Response message for - [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v19.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. + [ConversionAdjustmentUploadService.UploadConversionAdjustments][google.ads.googleads.v23.services.ConversionAdjustmentUploadService.UploadConversionAdjustments]. Attributes: partial_failure_error (google.rpc.status_pb2.Status): @@ -116,7 +116,7 @@ class UploadConversionAdjustmentsResponse(proto.Message): error. See https://developers.google.com/google-ads/api/docs/best-practices/partial-failures for more information about partial failure. - results (MutableSequence[google.ads.googleads.v19.services.types.ConversionAdjustmentResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.ConversionAdjustmentResult]): Returned for successfully processed conversion adjustments. Proto will be empty for rows that received an error. Results are not returned when validate_only is true. @@ -148,7 +148,7 @@ class ConversionAdjustment(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - gclid_date_time_pair (google.ads.googleads.v19.services.types.GclidDateTimePair): + gclid_date_time_pair (google.ads.googleads.v23.services.types.GclidDateTimePair): For adjustments, uniquely identifies a conversion that was reported without an order ID specified. If the adjustment_type is ENHANCEMENT, this value is optional but @@ -174,13 +174,13 @@ class ConversionAdjustment(proto.Message): adjustment_date_time (str): The date time at which the adjustment occurred. Must be after the conversion_date_time. The timezone must be - specified. The format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for + specified. The format is "yyyy-mm-dd hh:mm:ss+\|-hh:mm", for example, "2019-01-01 12:32:45-08:00". This field is a member of `oneof`_ ``_adjustment_date_time``. - adjustment_type (google.ads.googleads.v19.enums.types.ConversionAdjustmentTypeEnum.ConversionAdjustmentType): + adjustment_type (google.ads.googleads.v23.enums.types.ConversionAdjustmentTypeEnum.ConversionAdjustmentType): The adjustment type. - restatement_value (google.ads.googleads.v19.services.types.RestatementValue): + restatement_value (google.ads.googleads.v23.services.types.RestatementValue): Information needed to restate the conversion's value. Required for restatements. Should not be supplied for retractions. An error @@ -190,7 +190,7 @@ class ConversionAdjustment(proto.Message): new, more recent, adjustment occurrence time. Otherwise, it will be treated as a duplicate of the previous restatement and ignored. - user_identifiers (MutableSequence[google.ads.googleads.v19.common.types.UserIdentifier]): + user_identifiers (MutableSequence[google.ads.googleads.v23.common.types.UserIdentifier]): The user identifiers to enhance the original conversion. ConversionAdjustmentUploadService only accepts user identifiers in enhancements. @@ -314,7 +314,7 @@ class GclidDateTimePair(proto.Message): conversion_date_time (str): The date time at which the original conversion for this adjustment occurred. The timezone must be specified. The - format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, + format is "yyyy-mm-dd hh:mm:ss+\|-hh:mm", for example, "2019-01-01 12:32:45-08:00". This field is a member of `oneof`_ ``_conversion_date_time``. @@ -340,7 +340,7 @@ class ConversionAdjustmentResult(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - gclid_date_time_pair (google.ads.googleads.v19.services.types.GclidDateTimePair): + gclid_date_time_pair (google.ads.googleads.v23.services.types.GclidDateTimePair): The gclid and conversion date time of the conversion. order_id (str): @@ -353,11 +353,11 @@ class ConversionAdjustmentResult(proto.Message): This field is a member of `oneof`_ ``_conversion_action``. adjustment_date_time (str): The date time at which the adjustment occurred. The format - is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, "2019-01-01 + is "yyyy-mm-dd hh:mm:ss+\|-hh:mm", for example, "2019-01-01 12:32:45-08:00". This field is a member of `oneof`_ ``_adjustment_date_time``. - adjustment_type (google.ads.googleads.v19.enums.types.ConversionAdjustmentTypeEnum.ConversionAdjustmentType): + adjustment_type (google.ads.googleads.v23.enums.types.ConversionAdjustmentTypeEnum.ConversionAdjustmentType): The adjustment type. """ diff --git a/google/ads/googleads/v19/services/types/conversion_custom_variable_service.py b/google/ads/googleads/v23/services/types/conversion_custom_variable_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/conversion_custom_variable_service.py rename to google/ads/googleads/v23/services/types/conversion_custom_variable_service.py index 6a2b7effd..40107bd5b 100644 --- a/google/ads/googleads/v19/services/types/conversion_custom_variable_service.py +++ b/google/ads/googleads/v23/services/types/conversion_custom_variable_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( conversion_custom_variable as gagr_conversion_custom_variable, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateConversionCustomVariablesRequest", "ConversionCustomVariableOperation", @@ -43,13 +43,13 @@ class MutateConversionCustomVariablesRequest(proto.Message): r"""Request message for - [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v19.services.ConversionCustomVariableService.MutateConversionCustomVariables]. + [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v23.services.ConversionCustomVariableService.MutateConversionCustomVariables]. Attributes: customer_id (str): Required. The ID of the customer whose conversion custom variables are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.ConversionCustomVariableOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.ConversionCustomVariableOperation]): Required. The list of operations to perform on individual conversion custom variables. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateConversionCustomVariablesRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class ConversionCustomVariableOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.ConversionCustomVariable): + create (google.ads.googleads.v23.resources.types.ConversionCustomVariable): Create operation: No resource name is expected for the new conversion custom variable. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.ConversionCustomVariable): + update (google.ads.googleads.v23.resources.types.ConversionCustomVariable): Update operation: The conversion custom variable is expected to have a valid resource name. @@ -148,7 +148,7 @@ class ConversionCustomVariableOperation(proto.Message): class MutateConversionCustomVariablesResponse(proto.Message): r"""Response message for - [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v19.services.ConversionCustomVariableService.MutateConversionCustomVariables]. + [ConversionCustomVariableService.MutateConversionCustomVariables][google.ads.googleads.v23.services.ConversionCustomVariableService.MutateConversionCustomVariables]. Attributes: partial_failure_error (google.rpc.status_pb2.Status): @@ -157,7 +157,7 @@ class MutateConversionCustomVariablesResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateConversionCustomVariableResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateConversionCustomVariableResult]): All results for the mutate. """ @@ -181,7 +181,7 @@ class MutateConversionCustomVariableResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - conversion_custom_variable (google.ads.googleads.v19.resources.types.ConversionCustomVariable): + conversion_custom_variable (google.ads.googleads.v23.resources.types.ConversionCustomVariable): The mutated conversion custom variable with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/conversion_goal_campaign_config_service.py b/google/ads/googleads/v23/services/types/conversion_goal_campaign_config_service.py similarity index 89% rename from google/ads/googleads/v19/services/types/conversion_goal_campaign_config_service.py rename to google/ads/googleads/v23/services/types/conversion_goal_campaign_config_service.py index 0cfae2869..8a50009cb 100644 --- a/google/ads/googleads/v19/services/types/conversion_goal_campaign_config_service.py +++ b/google/ads/googleads/v23/services/types/conversion_goal_campaign_config_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( conversion_goal_campaign_config as gagr_conversion_goal_campaign_config, ) from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateConversionGoalCampaignConfigsRequest", "ConversionGoalCampaignConfigOperation", @@ -42,19 +42,19 @@ class MutateConversionGoalCampaignConfigsRequest(proto.Message): r"""Request message for - [ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs][google.ads.googleads.v19.services.ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs]. + [ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs][google.ads.googleads.v23.services.ConversionGoalCampaignConfigService.MutateConversionGoalCampaignConfigs]. Attributes: customer_id (str): Required. The ID of the customer whose custom conversion goals are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.ConversionGoalCampaignConfigOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.ConversionGoalCampaignConfigOperation]): Required. The list of operations to perform on individual conversion goal campaign config. validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -95,7 +95,7 @@ class ConversionGoalCampaignConfigOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - update (google.ads.googleads.v19.resources.types.ConversionGoalCampaignConfig): + update (google.ads.googleads.v23.resources.types.ConversionGoalCampaignConfig): Update operation: The conversion goal campaign config is expected to have a valid resource name. @@ -123,7 +123,7 @@ class MutateConversionGoalCampaignConfigsResponse(proto.Message): mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateConversionGoalCampaignConfigResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateConversionGoalCampaignConfigResult]): All results for the mutate. """ @@ -142,7 +142,7 @@ class MutateConversionGoalCampaignConfigResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - conversion_goal_campaign_config (google.ads.googleads.v19.resources.types.ConversionGoalCampaignConfig): + conversion_goal_campaign_config (google.ads.googleads.v23.resources.types.ConversionGoalCampaignConfig): The mutated ConversionGoalCampaignConfig with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/conversion_upload_service.py b/google/ads/googleads/v23/services/types/conversion_upload_service.py similarity index 86% rename from google/ads/googleads/v19/services/types/conversion_upload_service.py rename to google/ads/googleads/v23/services/types/conversion_upload_service.py index 680ccb683..f1de9ddf9 100644 --- a/google/ads/googleads/v19/services/types/conversion_upload_service.py +++ b/google/ads/googleads/v23/services/types/conversion_upload_service.py @@ -19,16 +19,16 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import consent as gagc_consent -from google.ads.googleads.v19.common.types import offline_user_data -from google.ads.googleads.v19.enums.types import conversion_customer_type -from google.ads.googleads.v19.enums.types import conversion_environment_enum +from google.ads.googleads.v23.common.types import consent as gagc_consent +from google.ads.googleads.v23.common.types import offline_user_data +from google.ads.googleads.v23.enums.types import conversion_customer_type +from google.ads.googleads.v23.enums.types import conversion_environment_enum from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "UploadClickConversionsRequest", "UploadClickConversionsResponse", @@ -49,7 +49,7 @@ class UploadClickConversionsRequest(proto.Message): r"""Request message for - [ConversionUploadService.UploadClickConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadClickConversions]. + [ConversionUploadService.UploadClickConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadClickConversions]. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -58,7 +58,7 @@ class UploadClickConversionsRequest(proto.Message): customer_id (str): Required. The ID of the customer performing the upload. - conversions (MutableSequence[google.ads.googleads.v19.services.types.ClickConversion]): + conversions (MutableSequence[google.ads.googleads.v23.services.types.ClickConversion]): Required. The conversions that are being uploaded. partial_failure (bool): @@ -74,29 +74,6 @@ class UploadClickConversionsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - debug_enabled (bool): - If true, the API will perform all upload checks and return - errors if any are found. If false, it will perform only - basic input validation, skip subsequent upload checks, and - return success even if no click was found for the provided - ``user_identifiers``. - - This setting only affects Enhanced conversions for leads - uploads that use ``user_identifiers`` instead of ``GCLID``, - ``GBRAID``, or ``WBRAID``. When uploading enhanced - conversions for leads, you should upload all conversion - events to the API, including those that may not come from - Google Ads campaigns. The upload of an event that is not - from a Google Ads campaign will result in a - ``CLICK_NOT_FOUND`` error if this field is set to ``true``. - Since these errors are expected for such events, set this - field to ``false`` so you can confirm your uploads are - properly formatted but ignore ``CLICK_NOT_FOUND`` errors - from all of the conversions that are not from a Google Ads - campaign. This will allow you to focus only on errors that - you can address. - - Default is false. job_id (int): Optional. Optional input to set job ID. Must be a non-negative number that is less than 2^31 if provided. If @@ -125,10 +102,6 @@ class UploadClickConversionsRequest(proto.Message): proto.BOOL, number=4, ) - debug_enabled: bool = proto.Field( - proto.BOOL, - number=5, - ) job_id: int = proto.Field( proto.INT32, number=6, @@ -138,7 +111,7 @@ class UploadClickConversionsRequest(proto.Message): class UploadClickConversionsResponse(proto.Message): r"""Response message for - [ConversionUploadService.UploadClickConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadClickConversions]. + [ConversionUploadService.UploadClickConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadClickConversions]. Attributes: partial_failure_error (google.rpc.status_pb2.Status): @@ -150,7 +123,7 @@ class UploadClickConversionsResponse(proto.Message): error. See https://developers.google.com/google-ads/api/docs/best-practices/partial-failures for more information about partial failure. - results (MutableSequence[google.ads.googleads.v19.services.types.ClickConversionResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.ClickConversionResult]): Returned for successfully processed conversions. Proto will be empty for rows that received an error. Results are not returned when validate_only is true. @@ -176,13 +149,13 @@ class UploadClickConversionsResponse(proto.Message): class UploadCallConversionsRequest(proto.Message): r"""Request message for - [ConversionUploadService.UploadCallConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadCallConversions]. + [ConversionUploadService.UploadCallConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadCallConversions]. Attributes: customer_id (str): Required. The ID of the customer performing the upload. - conversions (MutableSequence[google.ads.googleads.v19.services.types.CallConversion]): + conversions (MutableSequence[google.ads.googleads.v23.services.types.CallConversion]): Required. The conversions that are being uploaded. partial_failure (bool): @@ -221,7 +194,7 @@ class UploadCallConversionsRequest(proto.Message): class UploadCallConversionsResponse(proto.Message): r"""Response message for - [ConversionUploadService.UploadCallConversions][google.ads.googleads.v19.services.ConversionUploadService.UploadCallConversions]. + [ConversionUploadService.UploadCallConversions][google.ads.googleads.v23.services.ConversionUploadService.UploadCallConversions]. Attributes: partial_failure_error (google.rpc.status_pb2.Status): @@ -233,7 +206,7 @@ class UploadCallConversionsResponse(proto.Message): error. See https://developers.google.com/google-ads/api/docs/best-practices/partial-failures for more information about partial failure. - results (MutableSequence[google.ads.googleads.v19.services.types.CallConversionResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.CallConversionResult]): Returned for successfully processed conversions. Proto will be empty for rows that received an error. Results are not returned when validate_only is true. @@ -268,13 +241,11 @@ class ClickConversion(proto.Message): This field is a member of `oneof`_ ``_gclid``. gbraid (str): - The click identifier for clicks associated - with app conversions and originating from iOS - devices starting with iOS14. + The URL parameter for clicks associated with + app conversions. wbraid (str): - The click identifier for clicks associated - with web conversions and originating from iOS - devices starting with iOS14. + The URL parameter for clicks associated with + web conversions. conversion_action (str): Resource name of the conversion action associated with this conversion. Note: Although @@ -287,7 +258,7 @@ class ClickConversion(proto.Message): conversion_date_time (str): The date time at which the conversion occurred. Must be after the click time. The timezone must be specified. The - format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, + format is "yyyy-mm-dd hh:mm:ss+\|-hh:mm", for example, "2019-01-01 12:32:45-08:00". This field is a member of `oneof`_ ``_conversion_date_time``. @@ -308,32 +279,52 @@ class ClickConversion(proto.Message): per conversion action. This field is a member of `oneof`_ ``_order_id``. - external_attribution_data (google.ads.googleads.v19.services.types.ExternalAttributionData): + external_attribution_data (google.ads.googleads.v23.services.types.ExternalAttributionData): Additional data about externally attributed conversions. This field is required for conversions with an externally attributed conversion action, but should not be set otherwise. - custom_variables (MutableSequence[google.ads.googleads.v19.services.types.CustomVariable]): + custom_variables (MutableSequence[google.ads.googleads.v23.services.types.CustomVariable]): The custom variables associated with this conversion. - cart_data (google.ads.googleads.v19.services.types.CartData): + cart_data (google.ads.googleads.v23.services.types.CartData): The cart data associated with this conversion. - user_identifiers (MutableSequence[google.ads.googleads.v19.common.types.UserIdentifier]): + user_identifiers (MutableSequence[google.ads.googleads.v23.common.types.UserIdentifier]): The user identifiers associated with this conversion. Only hashed_email and hashed_phone_number are supported for conversion uploads. The maximum number of user identifiers for each conversion is 5. - conversion_environment (google.ads.googleads.v19.enums.types.ConversionEnvironmentEnum.ConversionEnvironment): + conversion_environment (google.ads.googleads.v23.enums.types.ConversionEnvironmentEnum.ConversionEnvironment): The environment this conversion was recorded on, for example, App or Web. - consent (google.ads.googleads.v19.common.types.Consent): + consent (google.ads.googleads.v23.common.types.Consent): The consent setting for the event. - customer_type (google.ads.googleads.v19.enums.types.ConversionCustomerTypeEnum.ConversionCustomerType): + customer_type (google.ads.googleads.v23.enums.types.ConversionCustomerTypeEnum.ConversionCustomerType): Type of the customer associated with the conversion (new or returning). Accessible only to customers on the allow-list. + user_ip_address (str): + The IP address of the customer when they + arrived on the landing page after an ad click + but before a conversion event. This is the IP + address of the customer's device, not the + advertiser's server. Google Ads does not support + IP address matching for end users in the + European Economic Area (EEA), United Kingdom + (UK), or Switzerland (CH). Add logic to + conditionally exclude sharing IP addresses from + users from these regions and ensure that you + provide users with clear and comprehensive + information about the data you collect on your + sites, apps, and other properties and get + consent where required by law or any applicable + Google policies. See the + https://support.google.com/google-ads/answer/2998031 + page for more details. + + This field is a member of `oneof`_ ``_user_ip_address``. session_attributes_encoded (bytes): The session attributes for the event, represented as a base64-encoded JSON string. The content should be generated @@ -342,7 +333,7 @@ class ClickConversion(proto.Message): instead. This field is a member of `oneof`_ ``session_attributes``. - session_attributes_key_value_pairs (google.ads.googleads.v19.services.types.SessionAttributesKeyValuePairs): + session_attributes_key_value_pairs (google.ads.googleads.v23.services.types.SessionAttributesKeyValuePairs): The session attributes for the event, represented as key-value pairs. @@ -428,6 +419,11 @@ class ClickConversion(proto.Message): number=26, enum=conversion_customer_type.ConversionCustomerTypeEnum.ConversionCustomerType, ) + user_ip_address: str = proto.Field( + proto.STRING, + number=27, + optional=True, + ) session_attributes_encoded: bytes = proto.Field( proto.BYTES, number=24, @@ -458,7 +454,7 @@ class CallConversion(proto.Message): This field is a member of `oneof`_ ``_caller_id``. call_start_date_time (str): The date time at which the call occurred. The timezone must - be specified. The format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", + be specified. The format is "yyyy-mm-dd hh:mm:ss+\|-hh:mm", for example, "2019-01-01 12:32:45-08:00". This field is a member of `oneof`_ ``_call_start_date_time``. @@ -474,7 +470,7 @@ class CallConversion(proto.Message): conversion_date_time (str): The date time at which the conversion occurred. Must be after the call time. The timezone must be specified. The - format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, + format is "yyyy-mm-dd hh:mm:ss+\|-hh:mm", for example, "2019-01-01 12:32:45-08:00". This field is a member of `oneof`_ ``_conversion_date_time``. @@ -489,10 +485,10 @@ class CallConversion(proto.Message): code. For example: USD, EUR. This field is a member of `oneof`_ ``_currency_code``. - custom_variables (MutableSequence[google.ads.googleads.v19.services.types.CustomVariable]): + custom_variables (MutableSequence[google.ads.googleads.v23.services.types.CustomVariable]): The custom variables associated with this conversion. - consent (google.ads.googleads.v19.common.types.Consent): + consent (google.ads.googleads.v23.common.types.Consent): The consent setting for the event. """ @@ -583,13 +579,11 @@ class ClickConversionResult(proto.Message): This field is a member of `oneof`_ ``_gclid``. gbraid (str): - The click identifier for clicks associated - with app conversions and originating from iOS - devices starting with iOS14. + The URL parameter for clicks associated with + app conversions. wbraid (str): - The click identifier for clicks associated - with web conversions and originating from iOS - devices starting with iOS14. + The URL parameter for clicks associated with + web conversions. conversion_action (str): Resource name of the conversion action associated with this conversion. @@ -597,11 +591,11 @@ class ClickConversionResult(proto.Message): This field is a member of `oneof`_ ``_conversion_action``. conversion_date_time (str): The date time at which the conversion occurred. The format - is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, "2019-01-01 + is "yyyy-mm-dd hh:mm:ss+\|-hh:mm", for example, "2019-01-01 12:32:45-08:00". This field is a member of `oneof`_ ``_conversion_date_time``. - user_identifiers (MutableSequence[google.ads.googleads.v19.common.types.UserIdentifier]): + user_identifiers (MutableSequence[google.ads.googleads.v23.common.types.UserIdentifier]): The user identifiers associated with this conversion. Only hashed_email and hashed_phone_number are supported for conversion uploads. The maximum number of user identifiers @@ -656,7 +650,7 @@ class CallConversionResult(proto.Message): This field is a member of `oneof`_ ``_caller_id``. call_start_date_time (str): The date time at which the call occurred. The format is - "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, "2019-01-01 + "yyyy-mm-dd hh:mm:ss+\|-hh:mm", for example, "2019-01-01 12:32:45-08:00". This field is a member of `oneof`_ ``_call_start_date_time``. @@ -667,7 +661,7 @@ class CallConversionResult(proto.Message): This field is a member of `oneof`_ ``_conversion_action``. conversion_date_time (str): The date time at which the conversion occurred. The format - is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, "2019-01-01 + is "yyyy-mm-dd hh:mm:ss+\|-hh:mm", for example, "2019-01-01 12:32:45-08:00". This field is a member of `oneof`_ ``_conversion_date_time``. @@ -742,7 +736,7 @@ class CartData(proto.Message): as free shipping and coupon discounts for the whole cart. The currency code is the same as that in the ClickConversion message. - items (MutableSequence[google.ads.googleads.v19.services.types.CartData.Item]): + items (MutableSequence[google.ads.googleads.v23.services.types.CartData.Item]): Data of the items purchased. """ @@ -823,7 +817,7 @@ class SessionAttributesKeyValuePairs(proto.Message): key-value pairs. Attributes: - key_value_pairs (MutableSequence[google.ads.googleads.v19.services.types.SessionAttributeKeyValuePair]): + key_value_pairs (MutableSequence[google.ads.googleads.v23.services.types.SessionAttributeKeyValuePair]): Required. The session attributes for the conversion. """ diff --git a/google/ads/googleads/v19/services/types/conversion_value_rule_service.py b/google/ads/googleads/v23/services/types/conversion_value_rule_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/conversion_value_rule_service.py rename to google/ads/googleads/v23/services/types/conversion_value_rule_service.py index 709de61db..c9cd05075 100644 --- a/google/ads/googleads/v19/services/types/conversion_value_rule_service.py +++ b/google/ads/googleads/v23/services/types/conversion_value_rule_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( conversion_value_rule as gagr_conversion_value_rule, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateConversionValueRulesRequest", "ConversionValueRuleOperation", @@ -43,13 +43,13 @@ class MutateConversionValueRulesRequest(proto.Message): r"""Request message for - [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v19.services.ConversionValueRuleService.MutateConversionValueRules]. + [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v23.services.ConversionValueRuleService.MutateConversionValueRules]. Attributes: customer_id (str): Required. The ID of the customer whose conversion value rules are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.ConversionValueRuleOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.ConversionValueRuleOperation]): Required. The list of operations to perform on individual conversion value rules. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateConversionValueRulesRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class ConversionValueRuleOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.ConversionValueRule): + create (google.ads.googleads.v23.resources.types.ConversionValueRule): Create operation: No resource name is expected for the new conversion value rule. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.ConversionValueRule): + update (google.ads.googleads.v23.resources.types.ConversionValueRule): Update operation: The conversion value rule is expected to have a valid resource name. @@ -155,10 +155,10 @@ class ConversionValueRuleOperation(proto.Message): class MutateConversionValueRulesResponse(proto.Message): r"""Response message for - [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v19.services.ConversionValueRuleService.MutateConversionValueRules]. + [ConversionValueRuleService.MutateConversionValueRules][google.ads.googleads.v23.services.ConversionValueRuleService.MutateConversionValueRules]. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateConversionValueRuleResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateConversionValueRuleResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -188,7 +188,7 @@ class MutateConversionValueRuleResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - conversion_value_rule (google.ads.googleads.v19.resources.types.ConversionValueRule): + conversion_value_rule (google.ads.googleads.v23.resources.types.ConversionValueRule): The mutated conversion value rule with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/conversion_value_rule_set_service.py b/google/ads/googleads/v23/services/types/conversion_value_rule_set_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/conversion_value_rule_set_service.py rename to google/ads/googleads/v23/services/types/conversion_value_rule_set_service.py index 762757f32..1f5afdde0 100644 --- a/google/ads/googleads/v19/services/types/conversion_value_rule_set_service.py +++ b/google/ads/googleads/v23/services/types/conversion_value_rule_set_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( conversion_value_rule_set as gagr_conversion_value_rule_set, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateConversionValueRuleSetsRequest", "ConversionValueRuleSetOperation", @@ -43,13 +43,13 @@ class MutateConversionValueRuleSetsRequest(proto.Message): r"""Request message for - [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v19.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. + [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v23.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. Attributes: customer_id (str): Required. The ID of the customer whose conversion value rule sets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.ConversionValueRuleSetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.ConversionValueRuleSetOperation]): Required. The list of operations to perform on individual conversion value rule sets. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateConversionValueRuleSetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,12 +110,12 @@ class ConversionValueRuleSetOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.ConversionValueRuleSet): + create (google.ads.googleads.v23.resources.types.ConversionValueRuleSet): Create operation: No resource name is expected for the new conversion value rule set. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.ConversionValueRuleSet): + update (google.ads.googleads.v23.resources.types.ConversionValueRuleSet): Update operation: The conversion value rule set is expected to have a valid resource name. @@ -155,10 +155,10 @@ class ConversionValueRuleSetOperation(proto.Message): class MutateConversionValueRuleSetsResponse(proto.Message): r"""Response message for - [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v19.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. + [ConversionValueRuleSetService.MutateConversionValueRuleSets][google.ads.googleads.v23.services.ConversionValueRuleSetService.MutateConversionValueRuleSets]. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateConversionValueRuleSetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateConversionValueRuleSetResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -188,7 +188,7 @@ class MutateConversionValueRuleSetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - conversion_value_rule_set (google.ads.googleads.v19.resources.types.ConversionValueRuleSet): + conversion_value_rule_set (google.ads.googleads.v23.resources.types.ConversionValueRuleSet): The mutated conversion value rule set with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/custom_audience_service.py b/google/ads/googleads/v23/services/types/custom_audience_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/custom_audience_service.py rename to google/ads/googleads/v23/services/types/custom_audience_service.py index 7b4fecf07..6a428c313 100644 --- a/google/ads/googleads/v19/services/types/custom_audience_service.py +++ b/google/ads/googleads/v23/services/types/custom_audience_service.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import custom_audience +from google.ads.googleads.v23.resources.types import custom_audience from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomAudiencesRequest", "CustomAudienceOperation", @@ -37,13 +37,13 @@ class MutateCustomAudiencesRequest(proto.Message): r"""Request message for - [CustomAudienceService.MutateCustomAudiences][google.ads.googleads.v19.services.CustomAudienceService.MutateCustomAudiences]. + [CustomAudienceService.MutateCustomAudiences][google.ads.googleads.v23.services.CustomAudienceService.MutateCustomAudiences]. Attributes: customer_id (str): Required. The ID of the customer whose custom audiences are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomAudienceOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomAudienceOperation]): Required. The list of operations to perform on individual custom audiences. validate_only (bool): @@ -82,12 +82,12 @@ class CustomAudienceOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CustomAudience): + create (google.ads.googleads.v23.resources.types.CustomAudience): Create operation: No resource name is expected for the new custom audience. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CustomAudience): + update (google.ads.googleads.v23.resources.types.CustomAudience): Update operation: The custom audience is expected to have a valid resource name. @@ -129,7 +129,7 @@ class MutateCustomAudiencesResponse(proto.Message): r"""Response message for custom audience mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCustomAudienceResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCustomAudienceResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/custom_conversion_goal_service.py b/google/ads/googleads/v23/services/types/custom_conversion_goal_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/custom_conversion_goal_service.py rename to google/ads/googleads/v23/services/types/custom_conversion_goal_service.py index e5703922f..dbc930416 100644 --- a/google/ads/googleads/v19/services/types/custom_conversion_goal_service.py +++ b/google/ads/googleads/v23/services/types/custom_conversion_goal_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( custom_conversion_goal as gagr_custom_conversion_goal, ) from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomConversionGoalsRequest", "CustomConversionGoalOperation", @@ -42,19 +42,19 @@ class MutateCustomConversionGoalsRequest(proto.Message): r"""Request message for - [CustomConversionGoalService.MutateCustomConversionGoals][google.ads.googleads.v19.services.CustomConversionGoalService.MutateCustomConversionGoals]. + [CustomConversionGoalService.MutateCustomConversionGoals][google.ads.googleads.v23.services.CustomConversionGoalService.MutateCustomConversionGoals]. Attributes: customer_id (str): Required. The ID of the customer whose custom conversion goals are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomConversionGoalOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomConversionGoalOperation]): Required. The list of operations to perform on individual custom conversion goal. validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -99,12 +99,12 @@ class CustomConversionGoalOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CustomConversionGoal): + create (google.ads.googleads.v23.resources.types.CustomConversionGoal): Create operation: No resource name is expected for the new custom conversion goal This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CustomConversionGoal): + update (google.ads.googleads.v23.resources.types.CustomConversionGoal): Update operation: The custom conversion goal is expected to have a valid resource name. @@ -146,7 +146,7 @@ class MutateCustomConversionGoalsResponse(proto.Message): r"""Response message for a custom conversion goal mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCustomConversionGoalResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCustomConversionGoalResult]): All results for the mutate. """ @@ -165,7 +165,7 @@ class MutateCustomConversionGoalResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - custom_conversion_goal (google.ads.googleads.v19.resources.types.CustomConversionGoal): + custom_conversion_goal (google.ads.googleads.v23.resources.types.CustomConversionGoal): The mutated CustomConversionGoal with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/custom_interest_service.py b/google/ads/googleads/v23/services/types/custom_interest_service.py similarity index 89% rename from google/ads/googleads/v19/services/types/custom_interest_service.py rename to google/ads/googleads/v23/services/types/custom_interest_service.py index 18f093085..65efcf124 100644 --- a/google/ads/googleads/v19/services/types/custom_interest_service.py +++ b/google/ads/googleads/v23/services/types/custom_interest_service.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import custom_interest +from google.ads.googleads.v23.resources.types import custom_interest from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomInterestsRequest", "CustomInterestOperation", @@ -37,13 +37,13 @@ class MutateCustomInterestsRequest(proto.Message): r"""Request message for - [CustomInterestService.MutateCustomInterests][google.ads.googleads.v19.services.CustomInterestService.MutateCustomInterests]. + [CustomInterestService.MutateCustomInterests][google.ads.googleads.v23.services.CustomInterestService.MutateCustomInterests]. Attributes: customer_id (str): Required. The ID of the customer whose custom interests are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomInterestOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomInterestOperation]): Required. The list of operations to perform on individual custom interests. validate_only (bool): @@ -82,12 +82,12 @@ class CustomInterestOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CustomInterest): + create (google.ads.googleads.v23.resources.types.CustomInterest): Create operation: No resource name is expected for the new custom interest. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CustomInterest): + update (google.ads.googleads.v23.resources.types.CustomInterest): Update operation: The custom interest is expected to have a valid resource name. @@ -117,7 +117,7 @@ class MutateCustomInterestsResponse(proto.Message): r"""Response message for custom interest mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCustomInterestResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCustomInterestResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/customer_asset_service.py b/google/ads/googleads/v23/services/types/customer_asset_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/customer_asset_service.py rename to google/ads/googleads/v23/services/types/customer_asset_service.py index bcece1f8b..d31971b68 100644 --- a/google/ads/googleads/v19/services/types/customer_asset_service.py +++ b/google/ads/googleads/v23/services/types/customer_asset_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_asset as gagr_customer_asset, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomerAssetsRequest", "CustomerAssetOperation", @@ -43,13 +43,13 @@ class MutateCustomerAssetsRequest(proto.Message): r"""Request message for - [CustomerAssetService.MutateCustomerAssets][google.ads.googleads.v19.services.CustomerAssetService.MutateCustomerAssets]. + [CustomerAssetService.MutateCustomerAssets][google.ads.googleads.v23.services.CustomerAssetService.MutateCustomerAssets]. Attributes: customer_id (str): Required. The ID of the customer whose customer assets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerAssetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerAssetOperation]): Required. The list of operations to perform on individual customer assets. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateCustomerAssetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -108,12 +108,12 @@ class CustomerAssetOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CustomerAsset): + create (google.ads.googleads.v23.resources.types.CustomerAsset): Create operation: No resource name is expected for the new customer asset. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CustomerAsset): + update (google.ads.googleads.v23.resources.types.CustomerAsset): Update operation: The customer asset is expected to have a valid resource name. @@ -161,7 +161,7 @@ class MutateCustomerAssetsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCustomerAssetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCustomerAssetResult]): All results for the mutate. """ @@ -183,7 +183,7 @@ class MutateCustomerAssetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - customer_asset (google.ads.googleads.v19.resources.types.CustomerAsset): + customer_asset (google.ads.googleads.v23.resources.types.CustomerAsset): The mutated customer asset with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/customer_asset_set_service.py b/google/ads/googleads/v23/services/types/customer_asset_set_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/customer_asset_set_service.py rename to google/ads/googleads/v23/services/types/customer_asset_set_service.py index 1758388fe..0024fa7a3 100644 --- a/google/ads/googleads/v19/services/types/customer_asset_set_service.py +++ b/google/ads/googleads/v23/services/types/customer_asset_set_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_asset_set as gagr_customer_asset_set, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomerAssetSetsRequest", "CustomerAssetSetOperation", @@ -42,13 +42,13 @@ class MutateCustomerAssetSetsRequest(proto.Message): r"""Request message for - [CustomerAssetSetService.MutateCustomerAssetSets][google.ads.googleads.v19.services.CustomerAssetSetService.MutateCustomerAssetSets]. + [CustomerAssetSetService.MutateCustomerAssetSets][google.ads.googleads.v23.services.CustomerAssetSetService.MutateCustomerAssetSets]. Attributes: customer_id (str): Required. The ID of the customer whose customer asset sets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerAssetSetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerAssetSetOperation]): Required. The list of operations to perform on individual customer asset sets. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateCustomerAssetSetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -105,7 +105,7 @@ class CustomerAssetSetOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.CustomerAssetSet): + create (google.ads.googleads.v23.resources.types.CustomerAssetSet): Create operation: No resource name is expected for the new customer asset set. @@ -135,7 +135,7 @@ class MutateCustomerAssetSetsResponse(proto.Message): r"""Response message for a customer asset set mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCustomerAssetSetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCustomerAssetSetResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -165,7 +165,7 @@ class MutateCustomerAssetSetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - customer_asset_set (google.ads.googleads.v19.resources.types.CustomerAssetSet): + customer_asset_set (google.ads.googleads.v23.resources.types.CustomerAssetSet): The mutated customer asset set with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/customer_client_link_service.py b/google/ads/googleads/v23/services/types/customer_client_link_service.py similarity index 89% rename from google/ads/googleads/v19/services/types/customer_client_link_service.py rename to google/ads/googleads/v23/services/types/customer_client_link_service.py index c0c15f41c..3fb7c9542 100644 --- a/google/ads/googleads/v19/services/types/customer_client_link_service.py +++ b/google/ads/googleads/v23/services/types/customer_client_link_service.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import customer_client_link +from google.ads.googleads.v23.resources.types import customer_client_link from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomerClientLinkRequest", "CustomerClientLinkOperation", @@ -36,13 +36,13 @@ class MutateCustomerClientLinkRequest(proto.Message): r"""Request message for - [CustomerClientLinkService.MutateCustomerClientLink][google.ads.googleads.v19.services.CustomerClientLinkService.MutateCustomerClientLink]. + [CustomerClientLinkService.MutateCustomerClientLink][google.ads.googleads.v23.services.CustomerClientLinkService.MutateCustomerClientLink]. Attributes: customer_id (str): Required. The ID of the customer whose customer link are being modified. - operation (google.ads.googleads.v19.services.types.CustomerClientLinkOperation): + operation (google.ads.googleads.v23.services.types.CustomerClientLinkOperation): Required. The operation to perform on the individual CustomerClientLink. validate_only (bool): @@ -79,12 +79,12 @@ class CustomerClientLinkOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CustomerClientLink): + create (google.ads.googleads.v23.resources.types.CustomerClientLink): Create operation: No resource name is expected for the new link. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CustomerClientLink): + update (google.ads.googleads.v23.resources.types.CustomerClientLink): Update operation: The link is expected to have a valid resource name. @@ -114,7 +114,7 @@ class MutateCustomerClientLinkResponse(proto.Message): r"""Response message for a CustomerClientLink mutate. Attributes: - result (google.ads.googleads.v19.services.types.MutateCustomerClientLinkResult): + result (google.ads.googleads.v23.services.types.MutateCustomerClientLinkResult): A result that identifies the resource affected by the mutate request. """ diff --git a/google/ads/googleads/v19/services/types/customer_conversion_goal_service.py b/google/ads/googleads/v23/services/types/customer_conversion_goal_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/customer_conversion_goal_service.py rename to google/ads/googleads/v23/services/types/customer_conversion_goal_service.py index 949e92637..752015c43 100644 --- a/google/ads/googleads/v19/services/types/customer_conversion_goal_service.py +++ b/google/ads/googleads/v23/services/types/customer_conversion_goal_service.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import customer_conversion_goal +from google.ads.googleads.v23.resources.types import customer_conversion_goal from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomerConversionGoalsRequest", "CustomerConversionGoalOperation", @@ -37,13 +37,13 @@ class MutateCustomerConversionGoalsRequest(proto.Message): r"""Request message for - [CustomerConversionGoalService.MutateCustomerConversionGoals][google.ads.googleads.v19.services.CustomerConversionGoalService.MutateCustomerConversionGoals]. + [CustomerConversionGoalService.MutateCustomerConversionGoals][google.ads.googleads.v23.services.CustomerConversionGoalService.MutateCustomerConversionGoals]. Attributes: customer_id (str): Required. The ID of the customer whose customer conversion goals are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerConversionGoalOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerConversionGoalOperation]): Required. The list of operations to perform on individual customer conversion goal. validate_only (bool): @@ -77,7 +77,7 @@ class CustomerConversionGoalOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - update (google.ads.googleads.v19.resources.types.CustomerConversionGoal): + update (google.ads.googleads.v23.resources.types.CustomerConversionGoal): Update operation: The customer conversion goal is expected to have a valid resource name. @@ -101,7 +101,7 @@ class MutateCustomerConversionGoalsResponse(proto.Message): r"""Response message for a customer conversion goal mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCustomerConversionGoalResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCustomerConversionGoalResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/customer_customizer_service.py b/google/ads/googleads/v23/services/types/customer_customizer_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/customer_customizer_service.py rename to google/ads/googleads/v23/services/types/customer_customizer_service.py index 069c47da8..a712ae0b2 100644 --- a/google/ads/googleads/v19/services/types/customer_customizer_service.py +++ b/google/ads/googleads/v23/services/types/customer_customizer_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_customizer as gagr_customer_customizer, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomerCustomizersRequest", "CustomerCustomizerOperation", @@ -42,13 +42,13 @@ class MutateCustomerCustomizersRequest(proto.Message): r"""Request message for - [CustomerCustomizerService.MutateCustomerCustomizers][google.ads.googleads.v19.services.CustomerCustomizerService.MutateCustomerCustomizers]. + [CustomerCustomizerService.MutateCustomerCustomizers][google.ads.googleads.v23.services.CustomerCustomizerService.MutateCustomerCustomizers]. Attributes: customer_id (str): Required. The ID of the customer whose customer customizers are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerCustomizerOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerCustomizerOperation]): Required. The list of operations to perform on individual customer customizers. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateCustomerCustomizersRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -106,7 +106,7 @@ class CustomerCustomizerOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.CustomerCustomizer): + create (google.ads.googleads.v23.resources.types.CustomerCustomizer): Create operation: No resource name is expected for the new customer customizer @@ -136,7 +136,7 @@ class MutateCustomerCustomizersResponse(proto.Message): r"""Response message for a customizer attribute mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCustomerCustomizerResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCustomerCustomizerResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -166,7 +166,7 @@ class MutateCustomerCustomizerResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - customer_customizer (google.ads.googleads.v19.resources.types.CustomerCustomizer): + customer_customizer (google.ads.googleads.v23.resources.types.CustomerCustomizer): The mutated CustomerCustomizer with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/customer_label_service.py b/google/ads/googleads/v23/services/types/customer_label_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/customer_label_service.py rename to google/ads/googleads/v23/services/types/customer_label_service.py index 30772c796..784420812 100644 --- a/google/ads/googleads/v19/services/types/customer_label_service.py +++ b/google/ads/googleads/v23/services/types/customer_label_service.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import customer_label +from google.ads.googleads.v23.resources.types import customer_label from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomerLabelsRequest", "CustomerLabelOperation", @@ -37,13 +37,13 @@ class MutateCustomerLabelsRequest(proto.Message): r"""Request message for - [CustomerLabelService.MutateCustomerLabels][google.ads.googleads.v19.services.CustomerLabelService.MutateCustomerLabels]. + [CustomerLabelService.MutateCustomerLabels][google.ads.googleads.v23.services.CustomerLabelService.MutateCustomerLabels]. Attributes: customer_id (str): Required. ID of the customer whose customer-label relationships are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerLabelOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerLabelOperation]): Required. The list of operations to perform on customer-label relationships. partial_failure (bool): @@ -88,7 +88,7 @@ class CustomerLabelOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.CustomerLabel): + create (google.ads.googleads.v23.resources.types.CustomerLabel): Create operation: No resource name is expected for the new customer-label relationship. @@ -126,7 +126,7 @@ class MutateCustomerLabelsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCustomerLabelResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCustomerLabelResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/customer_lifecycle_goal_service.py b/google/ads/googleads/v23/services/types/customer_lifecycle_goal_service.py similarity index 84% rename from google/ads/googleads/v19/services/types/customer_lifecycle_goal_service.py rename to google/ads/googleads/v23/services/types/customer_lifecycle_goal_service.py index 7c2ac38a7..4a7758116 100644 --- a/google/ads/googleads/v19/services/types/customer_lifecycle_goal_service.py +++ b/google/ads/googleads/v23/services/types/customer_lifecycle_goal_service.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import customer_lifecycle_goal +from google.ads.googleads.v23.resources.types import customer_lifecycle_goal from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "ConfigureCustomerLifecycleGoalsRequest", "CustomerLifecycleGoalOperation", @@ -36,13 +36,13 @@ class ConfigureCustomerLifecycleGoalsRequest(proto.Message): r"""Request message for - [CustomerLifecycleGoalService.configureCustomerLifecycleGoals][]. + [CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals][google.ads.googleads.v23.services.CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals]. Attributes: customer_id (str): Required. The ID of the customer performing the upload. - operation (google.ads.googleads.v19.services.types.CustomerLifecycleGoalOperation): + operation (google.ads.googleads.v23.services.types.CustomerLifecycleGoalOperation): Required. The operation to perform customer lifecycle goal update. validate_only (bool): @@ -80,12 +80,12 @@ class CustomerLifecycleGoalOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): Optional. FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CustomerLifecycleGoal): + create (google.ads.googleads.v23.resources.types.CustomerLifecycleGoal): Create operation: Create a new customer lifecycle goal. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.CustomerLifecycleGoal): + update (google.ads.googleads.v23.resources.types.CustomerLifecycleGoal): Update operation: Update an existing customer lifecycle goal. @@ -113,10 +113,10 @@ class CustomerLifecycleGoalOperation(proto.Message): class ConfigureCustomerLifecycleGoalsResponse(proto.Message): r"""Response message for - [CustomerLifecycleGoalService.configureCustomerLifecycleGoals][]. + [CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals][google.ads.googleads.v23.services.CustomerLifecycleGoalService.ConfigureCustomerLifecycleGoals]. Attributes: - result (google.ads.googleads.v19.services.types.ConfigureCustomerLifecycleGoalsResult): + result (google.ads.googleads.v23.services.types.ConfigureCustomerLifecycleGoalsResult): result for the customer lifecycle goal configuration. """ diff --git a/google/ads/googleads/v19/services/types/customer_manager_link_service.py b/google/ads/googleads/v23/services/types/customer_manager_link_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/customer_manager_link_service.py rename to google/ads/googleads/v23/services/types/customer_manager_link_service.py index b6a7a04c3..eb901c089 100644 --- a/google/ads/googleads/v19/services/types/customer_manager_link_service.py +++ b/google/ads/googleads/v23/services/types/customer_manager_link_service.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import customer_manager_link +from google.ads.googleads.v23.resources.types import customer_manager_link from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomerManagerLinkRequest", "MoveManagerLinkRequest", @@ -39,13 +39,13 @@ class MutateCustomerManagerLinkRequest(proto.Message): r"""Request message for - [CustomerManagerLinkService.MutateCustomerManagerLink][google.ads.googleads.v19.services.CustomerManagerLinkService.MutateCustomerManagerLink]. + [CustomerManagerLinkService.MutateCustomerManagerLink][google.ads.googleads.v23.services.CustomerManagerLinkService.MutateCustomerManagerLink]. Attributes: customer_id (str): Required. The ID of the customer whose customer manager links are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerManagerLinkOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerManagerLinkOperation]): Required. The list of operations to perform on individual customer manager links. validate_only (bool): @@ -72,7 +72,7 @@ class MutateCustomerManagerLinkRequest(proto.Message): class MoveManagerLinkRequest(proto.Message): r"""Request message for - [CustomerManagerLinkService.MoveManagerLink][google.ads.googleads.v19.services.CustomerManagerLinkService.MoveManagerLink]. + [CustomerManagerLinkService.MoveManagerLink][google.ads.googleads.v23.services.CustomerManagerLinkService.MoveManagerLink]. Attributes: customer_id (str): @@ -127,7 +127,7 @@ class CustomerManagerLinkOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - update (google.ads.googleads.v19.resources.types.CustomerManagerLink): + update (google.ads.googleads.v23.resources.types.CustomerManagerLink): Update operation: The link is expected to have a valid resource name. @@ -151,7 +151,7 @@ class MutateCustomerManagerLinkResponse(proto.Message): r"""Response message for a CustomerManagerLink mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCustomerManagerLinkResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCustomerManagerLinkResult]): A result that identifies the resource affected by the mutate request. """ diff --git a/google/ads/googleads/v19/services/types/customer_negative_criterion_service.py b/google/ads/googleads/v23/services/types/customer_negative_criterion_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/customer_negative_criterion_service.py rename to google/ads/googleads/v23/services/types/customer_negative_criterion_service.py index 5faebd9e9..b7779afc0 100644 --- a/google/ads/googleads/v19/services/types/customer_negative_criterion_service.py +++ b/google/ads/googleads/v23/services/types/customer_negative_criterion_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_negative_criterion as gagr_customer_negative_criterion, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomerNegativeCriteriaRequest", "CustomerNegativeCriterionOperation", @@ -42,13 +42,13 @@ class MutateCustomerNegativeCriteriaRequest(proto.Message): r"""Request message for - [CustomerNegativeCriterionService.MutateCustomerNegativeCriteria][google.ads.googleads.v19.services.CustomerNegativeCriterionService.MutateCustomerNegativeCriteria]. + [CustomerNegativeCriterionService.MutateCustomerNegativeCriteria][google.ads.googleads.v23.services.CustomerNegativeCriterionService.MutateCustomerNegativeCriteria]. Attributes: customer_id (str): Required. The ID of the customer whose criteria are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomerNegativeCriterionOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomerNegativeCriterionOperation]): Required. The list of operations to perform on individual criteria. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateCustomerNegativeCriteriaRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -106,7 +106,7 @@ class CustomerNegativeCriterionOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.CustomerNegativeCriterion): + create (google.ads.googleads.v23.resources.types.CustomerNegativeCriterion): Create operation: No resource name is expected for the new criterion. @@ -145,7 +145,7 @@ class MutateCustomerNegativeCriteriaResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCustomerNegativeCriteriaResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCustomerNegativeCriteriaResult]): All results for the mutate. """ @@ -169,7 +169,7 @@ class MutateCustomerNegativeCriteriaResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - customer_negative_criterion (google.ads.googleads.v19.resources.types.CustomerNegativeCriterion): + customer_negative_criterion (google.ads.googleads.v23.resources.types.CustomerNegativeCriterion): The mutated criterion with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/customer_service.py b/google/ads/googleads/v23/services/types/customer_service.py similarity index 88% rename from google/ads/googleads/v19/services/types/customer_service.py rename to google/ads/googleads/v23/services/types/customer_service.py index e4c2d4e04..91e9d5a7e 100644 --- a/google/ads/googleads/v19/services/types/customer_service.py +++ b/google/ads/googleads/v23/services/types/customer_service.py @@ -19,17 +19,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import access_role as gage_access_role -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import access_role as gage_access_role +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import customer as gagr_customer +from google.ads.googleads.v23.resources.types import customer as gagr_customer from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomerRequest", "CreateCustomerClientRequest", @@ -45,19 +45,19 @@ class MutateCustomerRequest(proto.Message): r"""Request message for - [CustomerService.MutateCustomer][google.ads.googleads.v19.services.CustomerService.MutateCustomer]. + [CustomerService.MutateCustomer][google.ads.googleads.v23.services.CustomerService.MutateCustomer]. Attributes: customer_id (str): Required. The ID of the customer being modified. - operation (google.ads.googleads.v19.services.types.CustomerOperation): + operation (google.ads.googleads.v23.services.types.CustomerOperation): Required. The operation to perform on the customer validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -87,7 +87,7 @@ class MutateCustomerRequest(proto.Message): class CreateCustomerClientRequest(proto.Message): r"""Request message for - [CustomerService.CreateCustomerClient][google.ads.googleads.v19.services.CustomerService.CreateCustomerClient]. + [CustomerService.CreateCustomerClient][google.ads.googleads.v23.services.CustomerService.CreateCustomerClient]. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -96,7 +96,7 @@ class CreateCustomerClientRequest(proto.Message): customer_id (str): Required. The ID of the Manager under whom client customer is being created. - customer_client (google.ads.googleads.v19.resources.types.Customer): + customer_client (google.ads.googleads.v23.resources.types.Customer): Required. The new client customer to create. The resource name on this customer will be ignored. @@ -106,7 +106,7 @@ class CreateCustomerClientRequest(proto.Message): Accessible only to customers on the allow-list. This field is a member of `oneof`_ ``_email_address``. - access_role (google.ads.googleads.v19.enums.types.AccessRoleEnum.AccessRole): + access_role (google.ads.googleads.v23.enums.types.AccessRoleEnum.AccessRole): The proposed role of user on the created client customer. Accessible only to customers on the allow-list. @@ -144,7 +144,7 @@ class CustomerOperation(proto.Message): r"""A single update on a customer. Attributes: - update (google.ads.googleads.v19.resources.types.Customer): + update (google.ads.googleads.v23.resources.types.Customer): Mutate operation. Only updates are supported for customer. update_mask (google.protobuf.field_mask_pb2.FieldMask): @@ -191,7 +191,7 @@ class MutateCustomerResponse(proto.Message): r"""Response message for customer mutate. Attributes: - result (google.ads.googleads.v19.services.types.MutateCustomerResult): + result (google.ads.googleads.v23.services.types.MutateCustomerResult): Result for the mutate. """ @@ -208,7 +208,7 @@ class MutateCustomerResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - customer (google.ads.googleads.v19.resources.types.Customer): + customer (google.ads.googleads.v23.resources.types.Customer): The mutated customer with only mutable fields after mutate. The fields will only be returned when response_content_type is set to "MUTABLE_RESOURCE". @@ -227,14 +227,14 @@ class MutateCustomerResult(proto.Message): class ListAccessibleCustomersRequest(proto.Message): r"""Request message for - [CustomerService.ListAccessibleCustomers][google.ads.googleads.v19.services.CustomerService.ListAccessibleCustomers]. + [CustomerService.ListAccessibleCustomers][google.ads.googleads.v23.services.CustomerService.ListAccessibleCustomers]. """ class ListAccessibleCustomersResponse(proto.Message): r"""Response message for - [CustomerService.ListAccessibleCustomers][google.ads.googleads.v19.services.CustomerService.ListAccessibleCustomers]. + [CustomerService.ListAccessibleCustomers][google.ads.googleads.v23.services.CustomerService.ListAccessibleCustomers]. Attributes: resource_names (MutableSequence[str]): diff --git a/google/ads/googleads/v19/services/types/customer_sk_ad_network_conversion_value_schema_service.py b/google/ads/googleads/v23/services/types/customer_sk_ad_network_conversion_value_schema_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/customer_sk_ad_network_conversion_value_schema_service.py rename to google/ads/googleads/v23/services/types/customer_sk_ad_network_conversion_value_schema_service.py index eb9ad88cd..778f6a4d2 100644 --- a/google/ads/googleads/v19/services/types/customer_sk_ad_network_conversion_value_schema_service.py +++ b/google/ads/googleads/v23/services/types/customer_sk_ad_network_conversion_value_schema_service.py @@ -18,15 +18,15 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_sk_ad_network_conversion_value_schema, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "CustomerSkAdNetworkConversionValueSchemaOperation", "MutateCustomerSkAdNetworkConversionValueSchemaRequest", @@ -41,7 +41,7 @@ class CustomerSkAdNetworkConversionValueSchemaOperation(proto.Message): CustomerSkAdNetworkConversionValueSchema. Attributes: - update (google.ads.googleads.v19.resources.types.CustomerSkAdNetworkConversionValueSchema): + update (google.ads.googleads.v23.resources.types.CustomerSkAdNetworkConversionValueSchema): Update operation: The schema is expected to have a valid resource name. """ @@ -57,13 +57,13 @@ class CustomerSkAdNetworkConversionValueSchemaOperation(proto.Message): class MutateCustomerSkAdNetworkConversionValueSchemaRequest(proto.Message): r"""Request message for - [CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema][google.ads.googleads.v19.services.CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema]. + [CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema][google.ads.googleads.v23.services.CustomerSkAdNetworkConversionValueSchemaService.MutateCustomerSkAdNetworkConversionValueSchema]. Attributes: customer_id (str): The ID of the customer whose shared sets are being modified. - operation (google.ads.googleads.v19.services.types.CustomerSkAdNetworkConversionValueSchemaOperation): + operation (google.ads.googleads.v23.services.types.CustomerSkAdNetworkConversionValueSchemaOperation): The operation to perform. validate_only (bool): If true, the request is validated but not @@ -123,7 +123,7 @@ class MutateCustomerSkAdNetworkConversionValueSchemaResponse(proto.Message): MutateCustomerSkAdNetworkConversionValueSchema. Attributes: - result (google.ads.googleads.v19.services.types.MutateCustomerSkAdNetworkConversionValueSchemaResult): + result (google.ads.googleads.v23.services.types.MutateCustomerSkAdNetworkConversionValueSchemaResult): All results for the mutate. warning (google.rpc.status_pb2.Status): Non blocking errors that provides schema validation failure diff --git a/google/ads/googleads/v19/services/types/customer_user_access_invitation_service.py b/google/ads/googleads/v23/services/types/customer_user_access_invitation_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/customer_user_access_invitation_service.py rename to google/ads/googleads/v23/services/types/customer_user_access_invitation_service.py index 56f9ab4b4..914027622 100644 --- a/google/ads/googleads/v19/services/types/customer_user_access_invitation_service.py +++ b/google/ads/googleads/v23/services/types/customer_user_access_invitation_service.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_user_access_invitation, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomerUserAccessInvitationRequest", "CustomerUserAccessInvitationOperation", @@ -37,13 +37,13 @@ class MutateCustomerUserAccessInvitationRequest(proto.Message): r"""Request message for - [CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation][google.ads.googleads.v19.services.CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation] + [CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation][google.ads.googleads.v23.services.CustomerUserAccessInvitationService.MutateCustomerUserAccessInvitation] Attributes: customer_id (str): Required. The ID of the customer whose access invitation is being modified. - operation (google.ads.googleads.v19.services.types.CustomerUserAccessInvitationOperation): + operation (google.ads.googleads.v23.services.types.CustomerUserAccessInvitationOperation): Required. The operation to perform on the access invitation """ @@ -71,7 +71,7 @@ class CustomerUserAccessInvitationOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.CustomerUserAccessInvitation): + create (google.ads.googleads.v23.resources.types.CustomerUserAccessInvitation): Create operation: No resource name is expected for the new access invitation. @@ -104,7 +104,7 @@ class MutateCustomerUserAccessInvitationResponse(proto.Message): r"""Response message for access invitation mutate. Attributes: - result (google.ads.googleads.v19.services.types.MutateCustomerUserAccessInvitationResult): + result (google.ads.googleads.v23.services.types.MutateCustomerUserAccessInvitationResult): Result for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/customer_user_access_service.py b/google/ads/googleads/v23/services/types/customer_user_access_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/customer_user_access_service.py rename to google/ads/googleads/v23/services/types/customer_user_access_service.py index e38b03310..e68dbf13c 100644 --- a/google/ads/googleads/v19/services/types/customer_user_access_service.py +++ b/google/ads/googleads/v23/services/types/customer_user_access_service.py @@ -18,13 +18,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import customer_user_access +from google.ads.googleads.v23.resources.types import customer_user_access from google.protobuf import field_mask_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomerUserAccessRequest", "CustomerUserAccessOperation", @@ -36,13 +36,13 @@ class MutateCustomerUserAccessRequest(proto.Message): r"""Mutate Request for - [CustomerUserAccessService.MutateCustomerUserAccess][google.ads.googleads.v19.services.CustomerUserAccessService.MutateCustomerUserAccess]. + [CustomerUserAccessService.MutateCustomerUserAccess][google.ads.googleads.v23.services.CustomerUserAccessService.MutateCustomerUserAccess]. Attributes: customer_id (str): Required. The ID of the customer being modified. - operation (google.ads.googleads.v19.services.types.CustomerUserAccessOperation): + operation (google.ads.googleads.v23.services.types.CustomerUserAccessOperation): Required. The operation to perform on the customer """ @@ -72,7 +72,7 @@ class CustomerUserAccessOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - update (google.ads.googleads.v19.resources.types.CustomerUserAccess): + update (google.ads.googleads.v23.resources.types.CustomerUserAccess): Update operation: The customer user access is expected to have a valid resource name. @@ -108,7 +108,7 @@ class MutateCustomerUserAccessResponse(proto.Message): r"""Response message for customer user access mutate. Attributes: - result (google.ads.googleads.v19.services.types.MutateCustomerUserAccessResult): + result (google.ads.googleads.v23.services.types.MutateCustomerUserAccessResult): Result for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/customizer_attribute_service.py b/google/ads/googleads/v23/services/types/customizer_attribute_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/customizer_attribute_service.py rename to google/ads/googleads/v23/services/types/customizer_attribute_service.py index c442bd60b..72771ebf7 100644 --- a/google/ads/googleads/v19/services/types/customizer_attribute_service.py +++ b/google/ads/googleads/v23/services/types/customizer_attribute_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customizer_attribute as gagr_customizer_attribute, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateCustomizerAttributesRequest", "CustomizerAttributeOperation", @@ -43,13 +43,13 @@ class MutateCustomizerAttributesRequest(proto.Message): r"""Request message for - [CustomizerAttributeService.MutateCustomizerAttributes][google.ads.googleads.v19.services.CustomizerAttributeService.MutateCustomizerAttributes]. + [CustomizerAttributeService.MutateCustomizerAttributes][google.ads.googleads.v23.services.CustomizerAttributeService.MutateCustomizerAttributes]. Attributes: customer_id (str): Required. The ID of the customer whose customizer attributes are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.CustomizerAttributeOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.CustomizerAttributeOperation]): Required. The list of operations to perform on individual customizer attributes. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateCustomizerAttributesRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -110,7 +110,7 @@ class CustomizerAttributeOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.CustomizerAttribute): + create (google.ads.googleads.v23.resources.types.CustomizerAttribute): Create operation: No resource name is expected for the new customizer attribute @@ -145,7 +145,7 @@ class MutateCustomizerAttributesResponse(proto.Message): r"""Response message for a customizer attribute mutate. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateCustomizerAttributeResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateCustomizerAttributeResult]): All results for the mutate. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -175,7 +175,7 @@ class MutateCustomizerAttributeResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - customizer_attribute (google.ads.googleads.v19.resources.types.CustomizerAttribute): + customizer_attribute (google.ads.googleads.v23.resources.types.CustomizerAttribute): The mutated CustomizerAttribute with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/data_link_service.py b/google/ads/googleads/v23/services/types/data_link_service.py similarity index 84% rename from google/ads/googleads/v19/services/types/data_link_service.py rename to google/ads/googleads/v23/services/types/data_link_service.py index 1c47caa9a..3d5c42cf0 100644 --- a/google/ads/googleads/v19/services/types/data_link_service.py +++ b/google/ads/googleads/v23/services/types/data_link_service.py @@ -18,15 +18,15 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( data_link_status as gage_data_link_status, ) -from google.ads.googleads.v19.resources.types import data_link as gagr_data_link +from google.ads.googleads.v23.resources.types import data_link as gagr_data_link __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "CreateDataLinkRequest", "CreateDataLinkResponse", @@ -40,13 +40,13 @@ class CreateDataLinkRequest(proto.Message): r"""Request message for - [DataLinkService.CreateDataLink][google.ads.googleads.v19.services.DataLinkService.CreateDataLink]. + [DataLinkService.CreateDataLink][google.ads.googleads.v23.services.DataLinkService.CreateDataLink]. Attributes: customer_id (str): Required. The ID of the customer for which the data link is created. - data_link (google.ads.googleads.v19.resources.types.DataLink): + data_link (google.ads.googleads.v23.resources.types.DataLink): Required. The data link to be created. """ @@ -63,7 +63,7 @@ class CreateDataLinkRequest(proto.Message): class CreateDataLinkResponse(proto.Message): r"""Response message for - [DataLinkService.CreateDataLink][google.ads.googleads.v19.services.DataLinkService.CreateDataLink]. + [DataLinkService.CreateDataLink][google.ads.googleads.v23.services.DataLinkService.CreateDataLink]. Attributes: resource_name (str): @@ -79,7 +79,7 @@ class CreateDataLinkResponse(proto.Message): class RemoveDataLinkRequest(proto.Message): r"""Request message for - [DataLinkService.RemoveDataLink][google.ads.googleads.v19.services.DataLinkService.RemoveDataLink]. + [DataLinkService.RemoveDataLink][google.ads.googleads.v23.services.DataLinkService.RemoveDataLink]. Attributes: customer_id (str): @@ -102,7 +102,7 @@ class RemoveDataLinkRequest(proto.Message): class RemoveDataLinkResponse(proto.Message): r"""Response message for - [DataLinkService.RemoveDataLink][google.ads.googleads.v19.services.DataLinkService.RemoveDataLink]. + [DataLinkService.RemoveDataLink][google.ads.googleads.v23.services.DataLinkService.RemoveDataLink]. Attributes: resource_name (str): @@ -117,13 +117,13 @@ class RemoveDataLinkResponse(proto.Message): class UpdateDataLinkRequest(proto.Message): r"""Request message for - [DataLinkService.UpdateDataLink][google.ads.googleads.v19.services.DataLinkService.UpdateDataLink]. + [DataLinkService.UpdateDataLink][google.ads.googleads.v23.services.DataLinkService.UpdateDataLink]. Attributes: customer_id (str): Required. The ID of the customer for which the data link is created. - data_link_status (google.ads.googleads.v19.enums.types.DataLinkStatusEnum.DataLinkStatus): + data_link_status (google.ads.googleads.v23.enums.types.DataLinkStatusEnum.DataLinkStatus): Required. The data link status to be updated to. resource_name (str): @@ -150,7 +150,7 @@ class UpdateDataLinkRequest(proto.Message): class UpdateDataLinkResponse(proto.Message): r"""Response message for - [DataLinkService.UpdateDataLink][google.ads.googleads.v19.services.DataLinkService.UpdateDataLink]. + [DataLinkService.UpdateDataLink][google.ads.googleads.v23.services.DataLinkService.UpdateDataLink]. Attributes: resource_name (str): diff --git a/google/ads/googleads/v19/services/types/experiment_arm_service.py b/google/ads/googleads/v23/services/types/experiment_arm_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/experiment_arm_service.py rename to google/ads/googleads/v23/services/types/experiment_arm_service.py index b76931b3e..070a68f41 100644 --- a/google/ads/googleads/v19/services/types/experiment_arm_service.py +++ b/google/ads/googleads/v23/services/types/experiment_arm_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( experiment_arm as gagr_experiment_arm, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateExperimentArmsRequest", "ExperimentArmOperation", @@ -43,13 +43,13 @@ class MutateExperimentArmsRequest(proto.Message): r"""Request message for - [ExperimentArmService.MutateExperimentArms][google.ads.googleads.v19.services.ExperimentArmService.MutateExperimentArms]. + [ExperimentArmService.MutateExperimentArms][google.ads.googleads.v23.services.ExperimentArmService.MutateExperimentArms]. Attributes: customer_id (str): Required. The ID of the customer whose experiments are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.ExperimentArmOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.ExperimentArmOperation]): Required. The list of operations to perform on individual experiment arm. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateExperimentArmsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -107,11 +107,11 @@ class ExperimentArmOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.ExperimentArm): + create (google.ads.googleads.v23.resources.types.ExperimentArm): Create operation This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.ExperimentArm): + update (google.ads.googleads.v23.resources.types.ExperimentArm): Update operation: The experiment arm is expected to have a valid resource name. @@ -159,7 +159,7 @@ class MutateExperimentArmsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateExperimentArmResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateExperimentArmResult]): All results for the mutate. """ @@ -181,7 +181,7 @@ class MutateExperimentArmResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - experiment_arm (google.ads.googleads.v19.resources.types.ExperimentArm): + experiment_arm (google.ads.googleads.v23.resources.types.ExperimentArm): The mutated experiment arm with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/experiment_service.py b/google/ads/googleads/v23/services/types/experiment_service.py similarity index 93% rename from google/ads/googleads/v19/services/types/experiment_service.py rename to google/ads/googleads/v23/services/types/experiment_service.py index 9f376f831..be237f5c8 100644 --- a/google/ads/googleads/v19/services/types/experiment_service.py +++ b/google/ads/googleads/v23/services/types/experiment_service.py @@ -19,7 +19,7 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( experiment as gagr_experiment, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -27,8 +27,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateExperimentsRequest", "ExperimentOperation", @@ -49,13 +49,13 @@ class MutateExperimentsRequest(proto.Message): r"""Request message for - [ExperimentService.MutateExperiments][google.ads.googleads.v19.services.ExperimentService.MutateExperiments]. + [ExperimentService.MutateExperiments][google.ads.googleads.v23.services.ExperimentService.MutateExperiments]. Attributes: customer_id (str): Required. The ID of the customer whose experiments are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.ExperimentOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.ExperimentOperation]): Required. The list of operations to perform on individual experiments. partial_failure (bool): @@ -102,11 +102,11 @@ class ExperimentOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.Experiment): + create (google.ads.googleads.v23.resources.types.Experiment): Create operation This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.Experiment): + update (google.ads.googleads.v23.resources.types.Experiment): Update operation: The experiment is expected to have a valid resource name. @@ -154,7 +154,7 @@ class MutateExperimentsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateExperimentResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateExperimentResult]): All results for the mutate. """ @@ -186,7 +186,7 @@ class MutateExperimentResult(proto.Message): class EndExperimentRequest(proto.Message): r"""Request message for - [ExperimentService.EndExperiment][google.ads.googleads.v19.services.ExperimentService.EndExperiment]. + [ExperimentService.EndExperiment][google.ads.googleads.v23.services.ExperimentService.EndExperiment]. Attributes: experiment (str): @@ -209,7 +209,7 @@ class EndExperimentRequest(proto.Message): class ListExperimentAsyncErrorsRequest(proto.Message): r"""Request message for - [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v19.services.ExperimentService.ListExperimentAsyncErrors]. + [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v23.services.ExperimentService.ListExperimentAsyncErrors]. Attributes: resource_name (str): @@ -244,7 +244,7 @@ class ListExperimentAsyncErrorsRequest(proto.Message): class ListExperimentAsyncErrorsResponse(proto.Message): r"""Response message for - [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v19.services.ExperimentService.ListExperimentAsyncErrors]. + [ExperimentService.ListExperimentAsyncErrors][google.ads.googleads.v23.services.ExperimentService.ListExperimentAsyncErrors]. Attributes: errors (MutableSequence[google.rpc.status_pb2.Status]): @@ -274,12 +274,12 @@ def raw_page(self): class GraduateExperimentRequest(proto.Message): r"""Request message for - [ExperimentService.GraduateExperiment][google.ads.googleads.v19.services.ExperimentService.GraduateExperiment]. + [ExperimentService.GraduateExperiment][google.ads.googleads.v23.services.ExperimentService.GraduateExperiment]. Attributes: experiment (str): Required. The experiment to be graduated. - campaign_budget_mappings (MutableSequence[google.ads.googleads.v19.services.types.CampaignBudgetMapping]): + campaign_budget_mappings (MutableSequence[google.ads.googleads.v23.services.types.CampaignBudgetMapping]): Required. List of campaign budget mappings for graduation. Each campaign that appears here will graduate, and will be assigned a new budget @@ -332,7 +332,7 @@ class CampaignBudgetMapping(proto.Message): class ScheduleExperimentRequest(proto.Message): r"""Request message for - [ExperimentService.ScheduleExperiment][google.ads.googleads.v19.services.ExperimentService.ScheduleExperiment]. + [ExperimentService.ScheduleExperiment][google.ads.googleads.v23.services.ExperimentService.ScheduleExperiment]. Attributes: resource_name (str): @@ -368,7 +368,7 @@ class ScheduleExperimentMetadata(proto.Message): class PromoteExperimentRequest(proto.Message): r"""Request message for - [ExperimentService.PromoteExperiment][google.ads.googleads.v19.services.ExperimentService.PromoteExperiment]. + [ExperimentService.PromoteExperiment][google.ads.googleads.v23.services.ExperimentService.PromoteExperiment]. Attributes: resource_name (str): diff --git a/google/ads/googleads/v19/services/types/geo_target_constant_service.py b/google/ads/googleads/v23/services/types/geo_target_constant_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/geo_target_constant_service.py rename to google/ads/googleads/v23/services/types/geo_target_constant_service.py index da59056e3..0b7bf4c6b 100644 --- a/google/ads/googleads/v19/services/types/geo_target_constant_service.py +++ b/google/ads/googleads/v23/services/types/geo_target_constant_service.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( geo_target_constant as gagr_geo_target_constant, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "SuggestGeoTargetConstantsRequest", "SuggestGeoTargetConstantsResponse", @@ -37,7 +37,7 @@ class SuggestGeoTargetConstantsRequest(proto.Message): r"""Request message for - [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v19.services.GeoTargetConstantService.SuggestGeoTargetConstants]. + [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v23.services.GeoTargetConstantService.SuggestGeoTargetConstants]. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -59,12 +59,12 @@ class SuggestGeoTargetConstantsRequest(proto.Message): country code. This field is a member of `oneof`_ ``_country_code``. - location_names (google.ads.googleads.v19.services.types.SuggestGeoTargetConstantsRequest.LocationNames): + location_names (google.ads.googleads.v23.services.types.SuggestGeoTargetConstantsRequest.LocationNames): The location names to search by. At most 25 names can be set. This field is a member of `oneof`_ ``query``. - geo_targets (google.ads.googleads.v19.services.types.SuggestGeoTargetConstantsRequest.GeoTargets): + geo_targets (google.ads.googleads.v23.services.types.SuggestGeoTargetConstantsRequest.GeoTargets): The geo target constant resource names to filter by. @@ -123,10 +123,10 @@ class GeoTargets(proto.Message): class SuggestGeoTargetConstantsResponse(proto.Message): r"""Response message for - [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v19.services.GeoTargetConstantService.SuggestGeoTargetConstants]. + [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v23.services.GeoTargetConstantService.SuggestGeoTargetConstants]. Attributes: - geo_target_constant_suggestions (MutableSequence[google.ads.googleads.v19.services.types.GeoTargetConstantSuggestion]): + geo_target_constant_suggestions (MutableSequence[google.ads.googleads.v23.services.types.GeoTargetConstantSuggestion]): Geo target constant suggestions. """ @@ -166,9 +166,9 @@ class GeoTargetConstantSuggestion(proto.Message): target. This field is a member of `oneof`_ ``_search_term``. - geo_target_constant (google.ads.googleads.v19.resources.types.GeoTargetConstant): + geo_target_constant (google.ads.googleads.v23.resources.types.GeoTargetConstant): The GeoTargetConstant result. - geo_target_constant_parents (MutableSequence[google.ads.googleads.v19.resources.types.GeoTargetConstant]): + geo_target_constant_parents (MutableSequence[google.ads.googleads.v23.resources.types.GeoTargetConstant]): The list of parents of the geo target constant. """ diff --git a/google/ads/googleads/v23/services/types/goal_service.py b/google/ads/googleads/v23/services/types/goal_service.py new file mode 100644 index 000000000..dd426ec5b --- /dev/null +++ b/google/ads/googleads/v23/services/types/goal_service.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.resources.types import goal +from google.protobuf import field_mask_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", + manifest={ + "MutateGoalsRequest", + "GoalOperation", + "MutateGoalsResponse", + "MutateGoalResult", + }, +) + + +class MutateGoalsRequest(proto.Message): + r"""Request message for + [GoalService.MutateGoals][google.ads.googleads.v23.services.GoalService.MutateGoals]. + + Attributes: + customer_id (str): + Required. The ID of the customer whose goals + are being modified. + operations (MutableSequence[google.ads.googleads.v23.services.types.GoalOperation]): + Required. The list of operations to perform + on the goals. + partial_failure (bool): + Optional. If true, successful operations will + be carried out and invalid operations will + return errors. If false, all operations will be + carried out in one transaction if and only if + they are all valid. Default is false. + validate_only (bool): + Optional. If true, the request is validated + but not executed. Only errors are returned, not + results. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + operations: MutableSequence["GoalOperation"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="GoalOperation", + ) + partial_failure: bool = proto.Field( + proto.BOOL, + number=3, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class GoalOperation(proto.Message): + r"""A single mutate operation on the goal. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + update_mask (google.protobuf.field_mask_pb2.FieldMask): + FieldMask that determines which resource + fields are modified in an update. + create (google.ads.googleads.v23.resources.types.Goal): + Create a new goal. + + This field is a member of `oneof`_ ``operation``. + update (google.ads.googleads.v23.resources.types.Goal): + Update an existing goal. + + This field is a member of `oneof`_ ``operation``. + """ + + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=3, + message=field_mask_pb2.FieldMask, + ) + create: goal.Goal = proto.Field( + proto.MESSAGE, + number=1, + oneof="operation", + message=goal.Goal, + ) + update: goal.Goal = proto.Field( + proto.MESSAGE, + number=2, + oneof="operation", + message=goal.Goal, + ) + + +class MutateGoalsResponse(proto.Message): + r"""Response message for a goal mutate. + + Attributes: + partial_failure_error (google.rpc.status_pb2.Status): + Errors that pertain to operation failures in + the partial failure mode. + results (MutableSequence[google.ads.googleads.v23.services.types.MutateGoalResult]): + All results for the mutate. + """ + + partial_failure_error: status_pb2.Status = proto.Field( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + results: MutableSequence["MutateGoalResult"] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message="MutateGoalResult", + ) + + +class MutateGoalResult(proto.Message): + r"""The result for the goal mutate. + + Attributes: + resource_name (str): + Returned for successful operations. + """ + + resource_name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/google_ads_field_service.py b/google/ads/googleads/v23/services/types/google_ads_field_service.py similarity index 89% rename from google/ads/googleads/v19/services/types/google_ads_field_service.py rename to google/ads/googleads/v23/services/types/google_ads_field_service.py index 9887defc3..24443c803 100644 --- a/google/ads/googleads/v19/services/types/google_ads_field_service.py +++ b/google/ads/googleads/v23/services/types/google_ads_field_service.py @@ -19,12 +19,12 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import google_ads_field +from google.ads.googleads.v23.resources.types import google_ads_field __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "GetGoogleAdsFieldRequest", "SearchGoogleAdsFieldsRequest", @@ -35,7 +35,7 @@ class GetGoogleAdsFieldRequest(proto.Message): r"""Request message for - [GoogleAdsFieldService.GetGoogleAdsField][google.ads.googleads.v19.services.GoogleAdsFieldService.GetGoogleAdsField]. + [GoogleAdsFieldService.GetGoogleAdsField][google.ads.googleads.v23.services.GoogleAdsFieldService.GetGoogleAdsField]. Attributes: resource_name (str): @@ -51,7 +51,7 @@ class GetGoogleAdsFieldRequest(proto.Message): class SearchGoogleAdsFieldsRequest(proto.Message): r"""Request message for - [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v19.services.GoogleAdsFieldService.SearchGoogleAdsFields]. + [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v23.services.GoogleAdsFieldService.SearchGoogleAdsFields]. Attributes: query (str): @@ -84,10 +84,10 @@ class SearchGoogleAdsFieldsRequest(proto.Message): class SearchGoogleAdsFieldsResponse(proto.Message): r"""Response message for - [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v19.services.GoogleAdsFieldService.SearchGoogleAdsFields]. + [GoogleAdsFieldService.SearchGoogleAdsFields][google.ads.googleads.v23.services.GoogleAdsFieldService.SearchGoogleAdsFields]. Attributes: - results (MutableSequence[google.ads.googleads.v19.resources.types.GoogleAdsField]): + results (MutableSequence[google.ads.googleads.v23.resources.types.GoogleAdsField]): The list of fields that matched the query. next_page_token (str): Pagination token used to retrieve the next page of results. diff --git a/google/ads/googleads/v19/services/types/google_ads_service.py b/google/ads/googleads/v23/services/types/google_ads_service.py similarity index 75% rename from google/ads/googleads/v19/services/types/google_ads_service.py rename to google/ads/googleads/v23/services/types/google_ads_service.py index 17b4f01a7..2b9d6ffa6 100644 --- a/google/ads/googleads/v19/services/types/google_ads_service.py +++ b/google/ads/googleads/v23/services/types/google_ads_service.py @@ -19,600 +19,631 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import metrics as gagc_metrics -from google.ads.googleads.v19.common.types import segments as gagc_segments -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import metrics as gagc_metrics +from google.ads.googleads.v23.common.types import segments as gagc_segments +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( summary_row_setting as gage_summary_row_setting, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( accessible_bidding_strategy as gagr_accessible_bidding_strategy, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( account_budget as gagr_account_budget, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( account_budget_proposal as gagr_account_budget_proposal, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( account_link as gagr_account_link, ) -from google.ads.googleads.v19.resources.types import ad as gagr_ad -from google.ads.googleads.v19.resources.types import ad_group as gagr_ad_group -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ad as gagr_ad +from google.ads.googleads.v23.resources.types import ad_group as gagr_ad_group +from google.ads.googleads.v23.resources.types import ( ad_group_ad as gagr_ad_group_ad, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_ad_asset_combination_view as gagr_ad_group_ad_asset_combination_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_ad_asset_view as gagr_ad_group_ad_asset_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_ad_label as gagr_ad_group_ad_label, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_asset as gagr_ad_group_asset, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_asset_set as gagr_ad_group_asset_set, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_audience_view as gagr_ad_group_audience_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_bid_modifier as gagr_ad_group_bid_modifier, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_criterion as gagr_ad_group_criterion, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_criterion_customizer as gagr_ad_group_criterion_customizer, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_criterion_label as gagr_ad_group_criterion_label, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_criterion_simulation as gagr_ad_group_criterion_simulation, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_customizer as gagr_ad_group_customizer, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_label as gagr_ad_group_label, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_group_simulation as gagr_ad_group_simulation, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_parameter as gagr_ad_parameter, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( ad_schedule_view as gagr_ad_schedule_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( age_range_view as gagr_age_range_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( + ai_max_search_term_ad_combination_view as gagr_ai_max_search_term_ad_combination_view, +) +from google.ads.googleads.v23.resources.types import ( android_privacy_shared_key_google_ad_group as gagr_android_privacy_shared_key_google_ad_group, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( android_privacy_shared_key_google_campaign as gagr_android_privacy_shared_key_google_campaign, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( android_privacy_shared_key_google_network_type as gagr_android_privacy_shared_key_google_network_type, ) -from google.ads.googleads.v19.resources.types import asset as gagr_asset -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( + applied_incentive as gagr_applied_incentive, +) +from google.ads.googleads.v23.resources.types import asset as gagr_asset +from google.ads.googleads.v23.resources.types import ( asset_field_type_view as gagr_asset_field_type_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( asset_group as gagr_asset_group, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( asset_group_asset as gagr_asset_group_asset, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( asset_group_listing_group_filter as gagr_asset_group_listing_group_filter, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( asset_group_product_group_view as gagr_asset_group_product_group_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( asset_group_signal as gagr_asset_group_signal, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( asset_group_top_combination_view as gagr_asset_group_top_combination_view, ) -from google.ads.googleads.v19.resources.types import asset_set as gagr_asset_set -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import asset_set as gagr_asset_set +from google.ads.googleads.v23.resources.types import ( asset_set_asset as gagr_asset_set_asset, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( asset_set_type_view as gagr_asset_set_type_view, ) -from google.ads.googleads.v19.resources.types import audience as gagr_audience -from google.ads.googleads.v19.resources.types import batch_job as gagr_batch_job -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import audience as gagr_audience +from google.ads.googleads.v23.resources.types import batch_job as gagr_batch_job +from google.ads.googleads.v23.resources.types import ( bidding_data_exclusion as gagr_bidding_data_exclusion, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( bidding_seasonality_adjustment as gagr_bidding_seasonality_adjustment, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( bidding_strategy as gagr_bidding_strategy, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( bidding_strategy_simulation as gagr_bidding_strategy_simulation, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( billing_setup as gagr_billing_setup, ) -from google.ads.googleads.v19.resources.types import call_view as gagr_call_view -from google.ads.googleads.v19.resources.types import campaign as gagr_campaign -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import call_view as gagr_call_view +from google.ads.googleads.v23.resources.types import campaign as gagr_campaign +from google.ads.googleads.v23.resources.types import ( campaign_aggregate_asset_view as gagr_campaign_aggregate_asset_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_asset as gagr_campaign_asset, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_asset_set as gagr_campaign_asset_set, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_audience_view as gagr_campaign_audience_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_bid_modifier as gagr_campaign_bid_modifier, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_budget as gagr_campaign_budget, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_conversion_goal as gagr_campaign_conversion_goal, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_criterion as gagr_campaign_criterion, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_customizer as gagr_campaign_customizer, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_draft as gagr_campaign_draft, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( + campaign_goal_config as gagr_campaign_goal_config, +) +from google.ads.googleads.v23.resources.types import ( campaign_group as gagr_campaign_group, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_label as gagr_campaign_label, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_lifecycle_goal as gagr_campaign_lifecycle_goal, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_search_term_insight as gagr_campaign_search_term_insight, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( + campaign_search_term_view as gagr_campaign_search_term_view, +) +from google.ads.googleads.v23.resources.types import ( campaign_shared_set as gagr_campaign_shared_set, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( campaign_simulation as gagr_campaign_simulation, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( carrier_constant as gagr_carrier_constant, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( change_event as gagr_change_event, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( change_status as gagr_change_status, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( channel_aggregate_asset_view as gagr_channel_aggregate_asset_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( click_view as gagr_click_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( combined_audience as gagr_combined_audience, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( content_criterion_view as gagr_content_criterion_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( conversion_action as gagr_conversion_action, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( conversion_custom_variable as gagr_conversion_custom_variable, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( conversion_goal_campaign_config as gagr_conversion_goal_campaign_config, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( conversion_value_rule as gagr_conversion_value_rule, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( conversion_value_rule_set as gagr_conversion_value_rule_set, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( currency_constant as gagr_currency_constant, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( custom_audience as gagr_custom_audience, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( custom_conversion_goal as gagr_custom_conversion_goal, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( custom_interest as gagr_custom_interest, ) -from google.ads.googleads.v19.resources.types import customer as gagr_customer -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import customer as gagr_customer +from google.ads.googleads.v23.resources.types import ( customer_asset as gagr_customer_asset, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_asset_set as gagr_customer_asset_set, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_client as gagr_customer_client, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_client_link as gagr_customer_client_link, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_conversion_goal as gagr_customer_conversion_goal, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_customizer as gagr_customer_customizer, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_label as gagr_customer_label, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_lifecycle_goal as gagr_customer_lifecycle_goal, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_manager_link as gagr_customer_manager_link, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_negative_criterion as gagr_customer_negative_criterion, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_search_term_insight as gagr_customer_search_term_insight, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_user_access as gagr_customer_user_access, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customer_user_access_invitation as gagr_customer_user_access_invitation, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( customizer_attribute as gagr_customizer_attribute, ) -from google.ads.googleads.v19.resources.types import data_link as gagr_data_link -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import data_link as gagr_data_link +from google.ads.googleads.v23.resources.types import ( + detail_content_suitability_placement_view as gagr_detail_content_suitability_placement_view, +) +from google.ads.googleads.v23.resources.types import ( detail_placement_view as gagr_detail_placement_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( detailed_demographic as gagr_detailed_demographic, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( display_keyword_view as gagr_display_keyword_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( distance_view as gagr_distance_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( domain_category as gagr_domain_category, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( dynamic_search_ads_search_term_view as gagr_dynamic_search_ads_search_term_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( expanded_landing_page_view as gagr_expanded_landing_page_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( experiment as gagr_experiment, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( experiment_arm as gagr_experiment_arm, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( + final_url_expansion_asset_view as gagr_final_url_expansion_asset_view, +) +from google.ads.googleads.v23.resources.types import ( gender_view as gagr_gender_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( geo_target_constant as gagr_geo_target_constant, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( geographic_view as gagr_geographic_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import goal as gagr_goal +from google.ads.googleads.v23.resources.types import ( + group_content_suitability_placement_view as gagr_group_content_suitability_placement_view, +) +from google.ads.googleads.v23.resources.types import ( group_placement_view as gagr_group_placement_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( hotel_group_view as gagr_hotel_group_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( hotel_performance_view as gagr_hotel_performance_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( hotel_reconciliation as gagr_hotel_reconciliation, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( income_range_view as gagr_income_range_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( keyword_plan as gagr_keyword_plan, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( keyword_plan_ad_group as gagr_keyword_plan_ad_group, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( keyword_plan_ad_group_keyword as gagr_keyword_plan_ad_group_keyword, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( keyword_plan_campaign as gagr_keyword_plan_campaign, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( keyword_plan_campaign_keyword as gagr_keyword_plan_campaign_keyword, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( keyword_theme_constant as gagr_keyword_theme_constant, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( keyword_view as gagr_keyword_view, ) -from google.ads.googleads.v19.resources.types import label as gagr_label -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import label as gagr_label +from google.ads.googleads.v23.resources.types import ( landing_page_view as gagr_landing_page_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( language_constant as gagr_language_constant, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( lead_form_submission_data as gagr_lead_form_submission_data, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( life_event as gagr_life_event, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( local_services_employee as gagr_local_services_employee, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( local_services_lead as gagr_local_services_lead, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( local_services_lead_conversation as gagr_local_services_lead_conversation, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( local_services_verification_artifact as gagr_local_services_verification_artifact, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( + location_interest_view as gagr_location_interest_view, +) +from google.ads.googleads.v23.resources.types import ( location_view as gagr_location_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( managed_placement_view as gagr_managed_placement_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( + matched_location_interest_view as gagr_matched_location_interest_view, +) +from google.ads.googleads.v23.resources.types import ( media_file as gagr_media_file, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( mobile_app_category_constant as gagr_mobile_app_category_constant, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( mobile_device_constant as gagr_mobile_device_constant, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( offline_conversion_upload_client_summary as gagr_offline_conversion_upload_client_summary, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( offline_conversion_upload_conversion_action_summary as gagr_offline_conversion_upload_conversion_action_summary, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( offline_user_data_job as gagr_offline_user_data_job, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( operating_system_version_constant as gagr_operating_system_version_constant, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( paid_organic_search_term_view as gagr_paid_organic_search_term_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( parental_status_view as gagr_parental_status_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( per_store_view as gagr_per_store_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( performance_max_placement_view as gagr_performance_max_placement_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( product_category_constant as gagr_product_category_constant, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( product_group_view as gagr_product_group_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( product_link as gagr_product_link, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( product_link_invitation as gagr_product_link_invitation, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( qualifying_question as gagr_qualifying_question, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( recommendation as gagr_recommendation, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( recommendation_subscription as gagr_recommendation_subscription, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( remarketing_action as gagr_remarketing_action, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( search_term_view as gagr_search_term_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( shared_criterion as gagr_shared_criterion, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( shared_set as gagr_shared_set, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( shopping_performance_view as gagr_shopping_performance_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( shopping_product as gagr_shopping_product, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( smart_campaign_search_term_view as gagr_smart_campaign_search_term_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( smart_campaign_setting as gagr_smart_campaign_setting, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( + targeting_expansion_view as gagr_targeting_expansion_view, +) +from google.ads.googleads.v23.resources.types import ( third_party_app_analytics_link as gagr_third_party_app_analytics_link, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( topic_constant as gagr_topic_constant, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( topic_view as gagr_topic_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( travel_activity_group_view as gagr_travel_activity_group_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( travel_activity_performance_view as gagr_travel_activity_performance_view, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( user_interest as gagr_user_interest, ) -from google.ads.googleads.v19.resources.types import user_list as gagr_user_list -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import user_list as gagr_user_list +from google.ads.googleads.v23.resources.types import ( user_list_customer_type as gagr_user_list_customer_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( user_location_view as gagr_user_location_view, ) -from google.ads.googleads.v19.resources.types import video as gagr_video -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import video as gagr_video +from google.ads.googleads.v23.resources.types import ( webpage_view as gagr_webpage_view, ) -from google.ads.googleads.v19.services.types import ad_group_ad_label_service -from google.ads.googleads.v19.services.types import ad_group_ad_service -from google.ads.googleads.v19.services.types import ad_group_asset_service -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ad_group_ad_label_service +from google.ads.googleads.v23.services.types import ad_group_ad_service +from google.ads.googleads.v23.services.types import ad_group_asset_service +from google.ads.googleads.v23.services.types import ( ad_group_bid_modifier_service, ) -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ( ad_group_criterion_customizer_service, ) -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ( ad_group_criterion_label_service, ) -from google.ads.googleads.v19.services.types import ad_group_criterion_service -from google.ads.googleads.v19.services.types import ad_group_customizer_service -from google.ads.googleads.v19.services.types import ad_group_label_service -from google.ads.googleads.v19.services.types import ad_group_service -from google.ads.googleads.v19.services.types import ad_parameter_service -from google.ads.googleads.v19.services.types import ad_service -from google.ads.googleads.v19.services.types import asset_group_asset_service -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ad_group_criterion_service +from google.ads.googleads.v23.services.types import ad_group_customizer_service +from google.ads.googleads.v23.services.types import ad_group_label_service +from google.ads.googleads.v23.services.types import ad_group_service +from google.ads.googleads.v23.services.types import ad_parameter_service +from google.ads.googleads.v23.services.types import ad_service +from google.ads.googleads.v23.services.types import asset_group_asset_service +from google.ads.googleads.v23.services.types import ( asset_group_listing_group_filter_service, ) -from google.ads.googleads.v19.services.types import asset_group_service -from google.ads.googleads.v19.services.types import asset_group_signal_service -from google.ads.googleads.v19.services.types import asset_service -from google.ads.googleads.v19.services.types import asset_set_asset_service -from google.ads.googleads.v19.services.types import asset_set_service -from google.ads.googleads.v19.services.types import audience_service -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import asset_group_service +from google.ads.googleads.v23.services.types import asset_group_signal_service +from google.ads.googleads.v23.services.types import asset_service +from google.ads.googleads.v23.services.types import asset_set_asset_service +from google.ads.googleads.v23.services.types import asset_set_service +from google.ads.googleads.v23.services.types import audience_service +from google.ads.googleads.v23.services.types import ( bidding_data_exclusion_service, ) -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ( bidding_seasonality_adjustment_service, ) -from google.ads.googleads.v19.services.types import bidding_strategy_service -from google.ads.googleads.v19.services.types import campaign_asset_service -from google.ads.googleads.v19.services.types import campaign_asset_set_service -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import bidding_strategy_service +from google.ads.googleads.v23.services.types import campaign_asset_service +from google.ads.googleads.v23.services.types import campaign_asset_set_service +from google.ads.googleads.v23.services.types import ( campaign_bid_modifier_service, ) -from google.ads.googleads.v19.services.types import campaign_budget_service -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import campaign_budget_service +from google.ads.googleads.v23.services.types import ( campaign_conversion_goal_service, ) -from google.ads.googleads.v19.services.types import campaign_criterion_service -from google.ads.googleads.v19.services.types import campaign_customizer_service -from google.ads.googleads.v19.services.types import campaign_draft_service -from google.ads.googleads.v19.services.types import campaign_group_service -from google.ads.googleads.v19.services.types import campaign_label_service -from google.ads.googleads.v19.services.types import campaign_service -from google.ads.googleads.v19.services.types import campaign_shared_set_service -from google.ads.googleads.v19.services.types import conversion_action_service -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import campaign_criterion_service +from google.ads.googleads.v23.services.types import campaign_customizer_service +from google.ads.googleads.v23.services.types import campaign_draft_service +from google.ads.googleads.v23.services.types import campaign_group_service +from google.ads.googleads.v23.services.types import campaign_label_service +from google.ads.googleads.v23.services.types import campaign_service +from google.ads.googleads.v23.services.types import campaign_shared_set_service +from google.ads.googleads.v23.services.types import conversion_action_service +from google.ads.googleads.v23.services.types import ( conversion_custom_variable_service, ) -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ( conversion_goal_campaign_config_service, ) -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ( conversion_value_rule_service, ) -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ( conversion_value_rule_set_service, ) -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ( custom_conversion_goal_service, ) -from google.ads.googleads.v19.services.types import customer_asset_service -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import customer_asset_service +from google.ads.googleads.v23.services.types import ( customer_conversion_goal_service, ) -from google.ads.googleads.v19.services.types import customer_customizer_service -from google.ads.googleads.v19.services.types import customer_label_service -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import customer_customizer_service +from google.ads.googleads.v23.services.types import customer_label_service +from google.ads.googleads.v23.services.types import ( customer_negative_criterion_service, ) -from google.ads.googleads.v19.services.types import customer_service -from google.ads.googleads.v19.services.types import customizer_attribute_service -from google.ads.googleads.v19.services.types import experiment_arm_service -from google.ads.googleads.v19.services.types import experiment_service -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import customer_service +from google.ads.googleads.v23.services.types import customizer_attribute_service +from google.ads.googleads.v23.services.types import experiment_arm_service +from google.ads.googleads.v23.services.types import experiment_service +from google.ads.googleads.v23.services.types import ( keyword_plan_ad_group_keyword_service, ) -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ( keyword_plan_ad_group_service, ) -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ( keyword_plan_campaign_keyword_service, ) -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import ( keyword_plan_campaign_service, ) -from google.ads.googleads.v19.services.types import keyword_plan_service -from google.ads.googleads.v19.services.types import label_service -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import keyword_plan_service +from google.ads.googleads.v23.services.types import label_service +from google.ads.googleads.v23.services.types import ( recommendation_subscription_service, ) -from google.ads.googleads.v19.services.types import remarketing_action_service -from google.ads.googleads.v19.services.types import shared_criterion_service -from google.ads.googleads.v19.services.types import shared_set_service -from google.ads.googleads.v19.services.types import ( +from google.ads.googleads.v23.services.types import remarketing_action_service +from google.ads.googleads.v23.services.types import shared_criterion_service +from google.ads.googleads.v23.services.types import shared_set_service +from google.ads.googleads.v23.services.types import ( smart_campaign_setting_service, ) -from google.ads.googleads.v19.services.types import user_list_service +from google.ads.googleads.v23.services.types import user_list_service from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "SearchGoogleAdsRequest", "SearchGoogleAdsResponse", @@ -624,13 +655,14 @@ "MutateOperation", "MutateOperationResponse", "SearchSettings", + "MetricAttributes", }, ) class SearchGoogleAdsRequest(proto.Message): r"""Request message for - [GoogleAdsService.Search][google.ads.googleads.v19.services.GoogleAdsService.Search]. + [GoogleAdsService.Search][google.ads.googleads.v23.services.GoogleAdsService.Search]. Attributes: customer_id (str): @@ -653,7 +685,7 @@ class SearchGoogleAdsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. - search_settings (google.ads.googleads.v19.services.types.SearchSettings): + search_settings (google.ads.googleads.v23.services.types.SearchSettings): Settings that allow users to specify request count, summary row, and results behavior. """ @@ -687,10 +719,10 @@ class SearchGoogleAdsRequest(proto.Message): class SearchGoogleAdsResponse(proto.Message): r"""Response message for - [GoogleAdsService.Search][google.ads.googleads.v19.services.GoogleAdsService.Search]. + [GoogleAdsService.Search][google.ads.googleads.v23.services.GoogleAdsService.Search]. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.GoogleAdsRow]): + results (MutableSequence[google.ads.googleads.v23.services.types.GoogleAdsRow]): The list of rows that matched the query. next_page_token (str): Pagination token used to retrieve the next page of results. @@ -703,7 +735,7 @@ class SearchGoogleAdsResponse(proto.Message): field_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that represents what fields were requested by the user. - summary_row (google.ads.googleads.v19.services.types.GoogleAdsRow): + summary_row (google.ads.googleads.v23.services.types.GoogleAdsRow): Summary row that contains summary of metrics in results. Summary of metrics means aggregation of metrics across all results, here aggregation @@ -711,6 +743,9 @@ class SearchGoogleAdsResponse(proto.Message): query_resource_consumption (int): The amount of resources consumed to serve the query. + metric_attributes (MutableSequence[google.ads.googleads.v23.services.types.MetricAttributes]): + The metric attributes of the metrics in the + results. """ @property @@ -744,11 +779,18 @@ def raw_page(self): proto.INT64, number=8, ) + metric_attributes: MutableSequence["MetricAttributes"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=13, + message="MetricAttributes", + ) + ) class SearchGoogleAdsStreamRequest(proto.Message): r"""Request message for - [GoogleAdsService.SearchStream][google.ads.googleads.v19.services.GoogleAdsService.SearchStream]. + [GoogleAdsService.SearchStream][google.ads.googleads.v23.services.GoogleAdsService.SearchStream]. Attributes: customer_id (str): @@ -756,7 +798,7 @@ class SearchGoogleAdsStreamRequest(proto.Message): queried. query (str): Required. The query string. - summary_row_setting (google.ads.googleads.v19.enums.types.SummaryRowSettingEnum.SummaryRowSetting): + summary_row_setting (google.ads.googleads.v23.enums.types.SummaryRowSettingEnum.SummaryRowSetting): Determines whether a summary row will be returned. By default, summary row is not returned. If requested, the summary row will be @@ -783,15 +825,15 @@ class SearchGoogleAdsStreamRequest(proto.Message): class SearchGoogleAdsStreamResponse(proto.Message): r"""Response message for - [GoogleAdsService.SearchStream][google.ads.googleads.v19.services.GoogleAdsService.SearchStream]. + [GoogleAdsService.SearchStream][google.ads.googleads.v23.services.GoogleAdsService.SearchStream]. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.GoogleAdsRow]): + results (MutableSequence[google.ads.googleads.v23.services.types.GoogleAdsRow]): The list of rows that matched the query. field_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that represents what fields were requested by the user. - summary_row (google.ads.googleads.v19.services.types.GoogleAdsRow): + summary_row (google.ads.googleads.v23.services.types.GoogleAdsRow): Summary row that contains summary of metrics in results. Summary of metrics means aggregation of metrics across all results, here aggregation @@ -805,6 +847,9 @@ class SearchGoogleAdsStreamResponse(proto.Message): non-Summary responses are returned separately in their respective rows. query_resource_consumption for non-Summary responses is returned in the final batch of results. + metric_attributes (MutableSequence[google.ads.googleads.v23.services.types.MetricAttributes]): + The metric attributes of the metrics in the + results. """ results: MutableSequence["GoogleAdsRow"] = proto.RepeatedField( @@ -830,445 +875,484 @@ class SearchGoogleAdsStreamResponse(proto.Message): proto.INT64, number=6, ) + metric_attributes: MutableSequence["MetricAttributes"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=11, + message="MetricAttributes", + ) + ) class GoogleAdsRow(proto.Message): r"""A returned row from the query. Attributes: - account_budget (google.ads.googleads.v19.resources.types.AccountBudget): + account_budget (google.ads.googleads.v23.resources.types.AccountBudget): The account budget in the query. - account_budget_proposal (google.ads.googleads.v19.resources.types.AccountBudgetProposal): + account_budget_proposal (google.ads.googleads.v23.resources.types.AccountBudgetProposal): The account budget proposal referenced in the query. - account_link (google.ads.googleads.v19.resources.types.AccountLink): + account_link (google.ads.googleads.v23.resources.types.AccountLink): The AccountLink referenced in the query. - ad (google.ads.googleads.v19.resources.types.Ad): + ad (google.ads.googleads.v23.resources.types.Ad): The Ad referenced in the query. - ad_group (google.ads.googleads.v19.resources.types.AdGroup): + ad_group (google.ads.googleads.v23.resources.types.AdGroup): The ad group referenced in the query. - ad_group_ad (google.ads.googleads.v19.resources.types.AdGroupAd): + ad_group_ad (google.ads.googleads.v23.resources.types.AdGroupAd): The ad referenced in the query. - ad_group_ad_asset_combination_view (google.ads.googleads.v19.resources.types.AdGroupAdAssetCombinationView): + ad_group_ad_asset_combination_view (google.ads.googleads.v23.resources.types.AdGroupAdAssetCombinationView): The ad group ad asset combination view in the query. - ad_group_ad_asset_view (google.ads.googleads.v19.resources.types.AdGroupAdAssetView): + ad_group_ad_asset_view (google.ads.googleads.v23.resources.types.AdGroupAdAssetView): The ad group ad asset view in the query. - ad_group_ad_label (google.ads.googleads.v19.resources.types.AdGroupAdLabel): + ad_group_ad_label (google.ads.googleads.v23.resources.types.AdGroupAdLabel): The ad group ad label referenced in the query. - ad_group_asset (google.ads.googleads.v19.resources.types.AdGroupAsset): + ad_group_asset (google.ads.googleads.v23.resources.types.AdGroupAsset): The ad group asset referenced in the query. - ad_group_asset_set (google.ads.googleads.v19.resources.types.AdGroupAssetSet): + ad_group_asset_set (google.ads.googleads.v23.resources.types.AdGroupAssetSet): The ad group asset set referenced in the query. - ad_group_audience_view (google.ads.googleads.v19.resources.types.AdGroupAudienceView): + ad_group_audience_view (google.ads.googleads.v23.resources.types.AdGroupAudienceView): The ad group audience view referenced in the query. - ad_group_bid_modifier (google.ads.googleads.v19.resources.types.AdGroupBidModifier): + ad_group_bid_modifier (google.ads.googleads.v23.resources.types.AdGroupBidModifier): The bid modifier referenced in the query. - ad_group_criterion (google.ads.googleads.v19.resources.types.AdGroupCriterion): + ad_group_criterion (google.ads.googleads.v23.resources.types.AdGroupCriterion): The criterion referenced in the query. - ad_group_criterion_customizer (google.ads.googleads.v19.resources.types.AdGroupCriterionCustomizer): + ad_group_criterion_customizer (google.ads.googleads.v23.resources.types.AdGroupCriterionCustomizer): The ad group criterion customizer referenced in the query. - ad_group_criterion_label (google.ads.googleads.v19.resources.types.AdGroupCriterionLabel): + ad_group_criterion_label (google.ads.googleads.v23.resources.types.AdGroupCriterionLabel): The ad group criterion label referenced in the query. - ad_group_criterion_simulation (google.ads.googleads.v19.resources.types.AdGroupCriterionSimulation): + ad_group_criterion_simulation (google.ads.googleads.v23.resources.types.AdGroupCriterionSimulation): The ad group criterion simulation referenced in the query. - ad_group_customizer (google.ads.googleads.v19.resources.types.AdGroupCustomizer): + ad_group_customizer (google.ads.googleads.v23.resources.types.AdGroupCustomizer): The ad group customizer referenced in the query. - ad_group_label (google.ads.googleads.v19.resources.types.AdGroupLabel): + ad_group_label (google.ads.googleads.v23.resources.types.AdGroupLabel): The ad group label referenced in the query. - ad_group_simulation (google.ads.googleads.v19.resources.types.AdGroupSimulation): + ad_group_simulation (google.ads.googleads.v23.resources.types.AdGroupSimulation): The ad group simulation referenced in the query. - ad_parameter (google.ads.googleads.v19.resources.types.AdParameter): + ad_parameter (google.ads.googleads.v23.resources.types.AdParameter): The ad parameter referenced in the query. - age_range_view (google.ads.googleads.v19.resources.types.AgeRangeView): + age_range_view (google.ads.googleads.v23.resources.types.AgeRangeView): The age range view referenced in the query. - ad_schedule_view (google.ads.googleads.v19.resources.types.AdScheduleView): + ad_schedule_view (google.ads.googleads.v23.resources.types.AdScheduleView): The ad schedule view referenced in the query. - domain_category (google.ads.googleads.v19.resources.types.DomainCategory): + ai_max_search_term_ad_combination_view (google.ads.googleads.v23.resources.types.AiMaxSearchTermAdCombinationView): + The AI Max search term ad combination view + referenced in the query. + domain_category (google.ads.googleads.v23.resources.types.DomainCategory): The domain category referenced in the query. - asset (google.ads.googleads.v19.resources.types.Asset): + asset (google.ads.googleads.v23.resources.types.Asset): The asset referenced in the query. - asset_field_type_view (google.ads.googleads.v19.resources.types.AssetFieldTypeView): + asset_field_type_view (google.ads.googleads.v23.resources.types.AssetFieldTypeView): The asset field type view referenced in the query. - channel_aggregate_asset_view (google.ads.googleads.v19.resources.types.ChannelAggregateAssetView): + channel_aggregate_asset_view (google.ads.googleads.v23.resources.types.ChannelAggregateAssetView): The channel aggregate asset view referenced in the query. - campaign_aggregate_asset_view (google.ads.googleads.v19.resources.types.CampaignAggregateAssetView): + campaign_aggregate_asset_view (google.ads.googleads.v23.resources.types.CampaignAggregateAssetView): The campaign aggregate asset view referenced in the query. - asset_group_asset (google.ads.googleads.v19.resources.types.AssetGroupAsset): + asset_group_asset (google.ads.googleads.v23.resources.types.AssetGroupAsset): The asset group asset referenced in the query. - asset_group_signal (google.ads.googleads.v19.resources.types.AssetGroupSignal): + asset_group_signal (google.ads.googleads.v23.resources.types.AssetGroupSignal): The asset group signal referenced in the query. - asset_group_listing_group_filter (google.ads.googleads.v19.resources.types.AssetGroupListingGroupFilter): + asset_group_listing_group_filter (google.ads.googleads.v23.resources.types.AssetGroupListingGroupFilter): The asset group listing group filter referenced in the query. - asset_group_product_group_view (google.ads.googleads.v19.resources.types.AssetGroupProductGroupView): + asset_group_product_group_view (google.ads.googleads.v23.resources.types.AssetGroupProductGroupView): The asset group product group view referenced in the query. - asset_group_top_combination_view (google.ads.googleads.v19.resources.types.AssetGroupTopCombinationView): + asset_group_top_combination_view (google.ads.googleads.v23.resources.types.AssetGroupTopCombinationView): The asset group top combination view referenced in the query. - asset_group (google.ads.googleads.v19.resources.types.AssetGroup): + asset_group (google.ads.googleads.v23.resources.types.AssetGroup): The asset group referenced in the query. - asset_set_asset (google.ads.googleads.v19.resources.types.AssetSetAsset): + asset_set_asset (google.ads.googleads.v23.resources.types.AssetSetAsset): The asset set asset referenced in the query. - asset_set (google.ads.googleads.v19.resources.types.AssetSet): + asset_set (google.ads.googleads.v23.resources.types.AssetSet): The asset set referenced in the query. - asset_set_type_view (google.ads.googleads.v19.resources.types.AssetSetTypeView): + asset_set_type_view (google.ads.googleads.v23.resources.types.AssetSetTypeView): The asset set type view referenced in the query. - batch_job (google.ads.googleads.v19.resources.types.BatchJob): + batch_job (google.ads.googleads.v23.resources.types.BatchJob): The batch job referenced in the query. - bidding_data_exclusion (google.ads.googleads.v19.resources.types.BiddingDataExclusion): + bidding_data_exclusion (google.ads.googleads.v23.resources.types.BiddingDataExclusion): The bidding data exclusion referenced in the query. - bidding_seasonality_adjustment (google.ads.googleads.v19.resources.types.BiddingSeasonalityAdjustment): + bidding_seasonality_adjustment (google.ads.googleads.v23.resources.types.BiddingSeasonalityAdjustment): The bidding seasonality adjustment referenced in the query. - bidding_strategy (google.ads.googleads.v19.resources.types.BiddingStrategy): + bidding_strategy (google.ads.googleads.v23.resources.types.BiddingStrategy): The bidding strategy referenced in the query. - bidding_strategy_simulation (google.ads.googleads.v19.resources.types.BiddingStrategySimulation): + bidding_strategy_simulation (google.ads.googleads.v23.resources.types.BiddingStrategySimulation): The bidding strategy simulation referenced in the query. - billing_setup (google.ads.googleads.v19.resources.types.BillingSetup): + billing_setup (google.ads.googleads.v23.resources.types.BillingSetup): The billing setup referenced in the query. - call_view (google.ads.googleads.v19.resources.types.CallView): + call_view (google.ads.googleads.v23.resources.types.CallView): The call view referenced in the query. - campaign_budget (google.ads.googleads.v19.resources.types.CampaignBudget): + campaign_budget (google.ads.googleads.v23.resources.types.CampaignBudget): The campaign budget referenced in the query. - campaign (google.ads.googleads.v19.resources.types.Campaign): + campaign (google.ads.googleads.v23.resources.types.Campaign): The campaign referenced in the query. - campaign_asset (google.ads.googleads.v19.resources.types.CampaignAsset): + campaign_asset (google.ads.googleads.v23.resources.types.CampaignAsset): The campaign asset referenced in the query. - campaign_asset_set (google.ads.googleads.v19.resources.types.CampaignAssetSet): + campaign_asset_set (google.ads.googleads.v23.resources.types.CampaignAssetSet): The campaign asset set referenced in the query. - campaign_audience_view (google.ads.googleads.v19.resources.types.CampaignAudienceView): + campaign_audience_view (google.ads.googleads.v23.resources.types.CampaignAudienceView): The campaign audience view referenced in the query. - campaign_bid_modifier (google.ads.googleads.v19.resources.types.CampaignBidModifier): + campaign_bid_modifier (google.ads.googleads.v23.resources.types.CampaignBidModifier): The campaign bid modifier referenced in the query. - campaign_conversion_goal (google.ads.googleads.v19.resources.types.CampaignConversionGoal): + campaign_conversion_goal (google.ads.googleads.v23.resources.types.CampaignConversionGoal): The CampaignConversionGoal referenced in the query. - campaign_criterion (google.ads.googleads.v19.resources.types.CampaignCriterion): + campaign_criterion (google.ads.googleads.v23.resources.types.CampaignCriterion): The campaign criterion referenced in the query. - campaign_customizer (google.ads.googleads.v19.resources.types.CampaignCustomizer): + campaign_customizer (google.ads.googleads.v23.resources.types.CampaignCustomizer): The campaign customizer referenced in the query. - campaign_draft (google.ads.googleads.v19.resources.types.CampaignDraft): + campaign_draft (google.ads.googleads.v23.resources.types.CampaignDraft): The campaign draft referenced in the query. - campaign_group (google.ads.googleads.v19.resources.types.CampaignGroup): + campaign_group (google.ads.googleads.v23.resources.types.CampaignGroup): Campaign Group referenced in AWQL query. - campaign_label (google.ads.googleads.v19.resources.types.CampaignLabel): + campaign_goal_config (google.ads.googleads.v23.resources.types.CampaignGoalConfig): + The campaign goal config referenced in the + query. + campaign_label (google.ads.googleads.v23.resources.types.CampaignLabel): The campaign label referenced in the query. - campaign_lifecycle_goal (google.ads.googleads.v19.resources.types.CampaignLifecycleGoal): + campaign_lifecycle_goal (google.ads.googleads.v23.resources.types.CampaignLifecycleGoal): The campaign lifecycle goal referenced in the query. - campaign_search_term_insight (google.ads.googleads.v19.resources.types.CampaignSearchTermInsight): + campaign_search_term_insight (google.ads.googleads.v23.resources.types.CampaignSearchTermInsight): The campaign search term insight referenced in the query. - campaign_shared_set (google.ads.googleads.v19.resources.types.CampaignSharedSet): + campaign_search_term_view (google.ads.googleads.v23.resources.types.CampaignSearchTermView): + The campaign-level search term view + referenced in the query. + campaign_shared_set (google.ads.googleads.v23.resources.types.CampaignSharedSet): Campaign Shared Set referenced in AWQL query. - campaign_simulation (google.ads.googleads.v19.resources.types.CampaignSimulation): + campaign_simulation (google.ads.googleads.v23.resources.types.CampaignSimulation): The campaign simulation referenced in the query. - carrier_constant (google.ads.googleads.v19.resources.types.CarrierConstant): + carrier_constant (google.ads.googleads.v23.resources.types.CarrierConstant): The carrier constant referenced in the query. - change_event (google.ads.googleads.v19.resources.types.ChangeEvent): + change_event (google.ads.googleads.v23.resources.types.ChangeEvent): The ChangeEvent referenced in the query. - change_status (google.ads.googleads.v19.resources.types.ChangeStatus): + change_status (google.ads.googleads.v23.resources.types.ChangeStatus): The ChangeStatus referenced in the query. - combined_audience (google.ads.googleads.v19.resources.types.CombinedAudience): + combined_audience (google.ads.googleads.v23.resources.types.CombinedAudience): The CombinedAudience referenced in the query. - audience (google.ads.googleads.v19.resources.types.Audience): + audience (google.ads.googleads.v23.resources.types.Audience): The Audience referenced in the query. - conversion_action (google.ads.googleads.v19.resources.types.ConversionAction): + conversion_action (google.ads.googleads.v23.resources.types.ConversionAction): The conversion action referenced in the query. - conversion_custom_variable (google.ads.googleads.v19.resources.types.ConversionCustomVariable): + conversion_custom_variable (google.ads.googleads.v23.resources.types.ConversionCustomVariable): The conversion custom variable referenced in the query. - conversion_goal_campaign_config (google.ads.googleads.v19.resources.types.ConversionGoalCampaignConfig): + conversion_goal_campaign_config (google.ads.googleads.v23.resources.types.ConversionGoalCampaignConfig): The ConversionGoalCampaignConfig referenced in the query. - conversion_value_rule (google.ads.googleads.v19.resources.types.ConversionValueRule): + conversion_value_rule (google.ads.googleads.v23.resources.types.ConversionValueRule): The conversion value rule referenced in the query. - conversion_value_rule_set (google.ads.googleads.v19.resources.types.ConversionValueRuleSet): + conversion_value_rule_set (google.ads.googleads.v23.resources.types.ConversionValueRuleSet): The conversion value rule set referenced in the query. - click_view (google.ads.googleads.v19.resources.types.ClickView): + click_view (google.ads.googleads.v23.resources.types.ClickView): The ClickView referenced in the query. - currency_constant (google.ads.googleads.v19.resources.types.CurrencyConstant): + currency_constant (google.ads.googleads.v23.resources.types.CurrencyConstant): The currency constant referenced in the query. - custom_audience (google.ads.googleads.v19.resources.types.CustomAudience): + custom_audience (google.ads.googleads.v23.resources.types.CustomAudience): The CustomAudience referenced in the query. - custom_conversion_goal (google.ads.googleads.v19.resources.types.CustomConversionGoal): + custom_conversion_goal (google.ads.googleads.v23.resources.types.CustomConversionGoal): The CustomConversionGoal referenced in the query. - custom_interest (google.ads.googleads.v19.resources.types.CustomInterest): + custom_interest (google.ads.googleads.v23.resources.types.CustomInterest): The CustomInterest referenced in the query. - customer (google.ads.googleads.v19.resources.types.Customer): + customer (google.ads.googleads.v23.resources.types.Customer): The customer referenced in the query. - customer_asset (google.ads.googleads.v19.resources.types.CustomerAsset): + customer_asset (google.ads.googleads.v23.resources.types.CustomerAsset): The customer asset referenced in the query. - customer_asset_set (google.ads.googleads.v19.resources.types.CustomerAssetSet): + customer_asset_set (google.ads.googleads.v23.resources.types.CustomerAssetSet): The customer asset set referenced in the query. - accessible_bidding_strategy (google.ads.googleads.v19.resources.types.AccessibleBiddingStrategy): + accessible_bidding_strategy (google.ads.googleads.v23.resources.types.AccessibleBiddingStrategy): The accessible bidding strategy referenced in the query. - customer_customizer (google.ads.googleads.v19.resources.types.CustomerCustomizer): + customer_customizer (google.ads.googleads.v23.resources.types.CustomerCustomizer): The customer customizer referenced in the query. - customer_manager_link (google.ads.googleads.v19.resources.types.CustomerManagerLink): + customer_manager_link (google.ads.googleads.v23.resources.types.CustomerManagerLink): The CustomerManagerLink referenced in the query. - customer_client_link (google.ads.googleads.v19.resources.types.CustomerClientLink): + customer_client_link (google.ads.googleads.v23.resources.types.CustomerClientLink): The CustomerClientLink referenced in the query. - customer_client (google.ads.googleads.v19.resources.types.CustomerClient): + customer_client (google.ads.googleads.v23.resources.types.CustomerClient): The CustomerClient referenced in the query. - customer_conversion_goal (google.ads.googleads.v19.resources.types.CustomerConversionGoal): + customer_conversion_goal (google.ads.googleads.v23.resources.types.CustomerConversionGoal): The CustomerConversionGoal referenced in the query. - customer_label (google.ads.googleads.v19.resources.types.CustomerLabel): + customer_label (google.ads.googleads.v23.resources.types.CustomerLabel): The customer label referenced in the query. - customer_lifecycle_goal (google.ads.googleads.v19.resources.types.CustomerLifecycleGoal): + customer_lifecycle_goal (google.ads.googleads.v23.resources.types.CustomerLifecycleGoal): The customer lifecycle goal referenced in the query. - customer_negative_criterion (google.ads.googleads.v19.resources.types.CustomerNegativeCriterion): + customer_negative_criterion (google.ads.googleads.v23.resources.types.CustomerNegativeCriterion): The customer negative criterion referenced in the query. - customer_search_term_insight (google.ads.googleads.v19.resources.types.CustomerSearchTermInsight): + customer_search_term_insight (google.ads.googleads.v23.resources.types.CustomerSearchTermInsight): The customer search term insight referenced in the query. - customer_user_access (google.ads.googleads.v19.resources.types.CustomerUserAccess): + customer_user_access (google.ads.googleads.v23.resources.types.CustomerUserAccess): The CustomerUserAccess referenced in the query. - customer_user_access_invitation (google.ads.googleads.v19.resources.types.CustomerUserAccessInvitation): + customer_user_access_invitation (google.ads.googleads.v23.resources.types.CustomerUserAccessInvitation): The CustomerUserAccessInvitation referenced in the query. - customizer_attribute (google.ads.googleads.v19.resources.types.CustomizerAttribute): + customizer_attribute (google.ads.googleads.v23.resources.types.CustomizerAttribute): The customizer attribute referenced in the query. - data_link (google.ads.googleads.v19.resources.types.DataLink): + data_link (google.ads.googleads.v23.resources.types.DataLink): The data link referenced in the query. - detail_placement_view (google.ads.googleads.v19.resources.types.DetailPlacementView): + detail_content_suitability_placement_view (google.ads.googleads.v23.resources.types.DetailContentSuitabilityPlacementView): + The detail content suitability placement view + referenced in the query. + detail_placement_view (google.ads.googleads.v23.resources.types.DetailPlacementView): The detail placement view referenced in the query. - detailed_demographic (google.ads.googleads.v19.resources.types.DetailedDemographic): + detailed_demographic (google.ads.googleads.v23.resources.types.DetailedDemographic): The detailed demographic referenced in the query. - display_keyword_view (google.ads.googleads.v19.resources.types.DisplayKeywordView): + display_keyword_view (google.ads.googleads.v23.resources.types.DisplayKeywordView): The display keyword view referenced in the query. - distance_view (google.ads.googleads.v19.resources.types.DistanceView): + distance_view (google.ads.googleads.v23.resources.types.DistanceView): The distance view referenced in the query. - dynamic_search_ads_search_term_view (google.ads.googleads.v19.resources.types.DynamicSearchAdsSearchTermView): + dynamic_search_ads_search_term_view (google.ads.googleads.v23.resources.types.DynamicSearchAdsSearchTermView): The dynamic search ads search term view referenced in the query. - expanded_landing_page_view (google.ads.googleads.v19.resources.types.ExpandedLandingPageView): + expanded_landing_page_view (google.ads.googleads.v23.resources.types.ExpandedLandingPageView): The expanded landing page view referenced in the query. - gender_view (google.ads.googleads.v19.resources.types.GenderView): + final_url_expansion_asset_view (google.ads.googleads.v23.resources.types.FinalUrlExpansionAssetView): + The final url expansion asset view referenced + in the query. + gender_view (google.ads.googleads.v23.resources.types.GenderView): The gender view referenced in the query. - geo_target_constant (google.ads.googleads.v19.resources.types.GeoTargetConstant): + geo_target_constant (google.ads.googleads.v23.resources.types.GeoTargetConstant): The geo target constant referenced in the query. - geographic_view (google.ads.googleads.v19.resources.types.GeographicView): + geographic_view (google.ads.googleads.v23.resources.types.GeographicView): The geographic view referenced in the query. - group_placement_view (google.ads.googleads.v19.resources.types.GroupPlacementView): + goal (google.ads.googleads.v23.resources.types.Goal): + The goal in the query. + group_content_suitability_placement_view (google.ads.googleads.v23.resources.types.GroupContentSuitabilityPlacementView): + The group content suitability placement view + referenced in the query. + group_placement_view (google.ads.googleads.v23.resources.types.GroupPlacementView): The group placement view referenced in the query. - hotel_group_view (google.ads.googleads.v19.resources.types.HotelGroupView): + hotel_group_view (google.ads.googleads.v23.resources.types.HotelGroupView): The hotel group view referenced in the query. - hotel_performance_view (google.ads.googleads.v19.resources.types.HotelPerformanceView): + hotel_performance_view (google.ads.googleads.v23.resources.types.HotelPerformanceView): The hotel performance view referenced in the query. - hotel_reconciliation (google.ads.googleads.v19.resources.types.HotelReconciliation): + hotel_reconciliation (google.ads.googleads.v23.resources.types.HotelReconciliation): The hotel reconciliation referenced in the query. - income_range_view (google.ads.googleads.v19.resources.types.IncomeRangeView): + income_range_view (google.ads.googleads.v23.resources.types.IncomeRangeView): The income range view referenced in the query. - keyword_view (google.ads.googleads.v19.resources.types.KeywordView): + keyword_view (google.ads.googleads.v23.resources.types.KeywordView): The keyword view referenced in the query. - keyword_plan (google.ads.googleads.v19.resources.types.KeywordPlan): + keyword_plan (google.ads.googleads.v23.resources.types.KeywordPlan): The keyword plan referenced in the query. - keyword_plan_campaign (google.ads.googleads.v19.resources.types.KeywordPlanCampaign): + keyword_plan_campaign (google.ads.googleads.v23.resources.types.KeywordPlanCampaign): The keyword plan campaign referenced in the query. - keyword_plan_campaign_keyword (google.ads.googleads.v19.resources.types.KeywordPlanCampaignKeyword): + keyword_plan_campaign_keyword (google.ads.googleads.v23.resources.types.KeywordPlanCampaignKeyword): The keyword plan campaign keyword referenced in the query. - keyword_plan_ad_group (google.ads.googleads.v19.resources.types.KeywordPlanAdGroup): + keyword_plan_ad_group (google.ads.googleads.v23.resources.types.KeywordPlanAdGroup): The keyword plan ad group referenced in the query. - keyword_plan_ad_group_keyword (google.ads.googleads.v19.resources.types.KeywordPlanAdGroupKeyword): + keyword_plan_ad_group_keyword (google.ads.googleads.v23.resources.types.KeywordPlanAdGroupKeyword): The keyword plan ad group referenced in the query. - keyword_theme_constant (google.ads.googleads.v19.resources.types.KeywordThemeConstant): + keyword_theme_constant (google.ads.googleads.v23.resources.types.KeywordThemeConstant): The keyword theme constant referenced in the query. - label (google.ads.googleads.v19.resources.types.Label): + label (google.ads.googleads.v23.resources.types.Label): The label referenced in the query. - landing_page_view (google.ads.googleads.v19.resources.types.LandingPageView): + landing_page_view (google.ads.googleads.v23.resources.types.LandingPageView): The landing page view referenced in the query. - language_constant (google.ads.googleads.v19.resources.types.LanguageConstant): + language_constant (google.ads.googleads.v23.resources.types.LanguageConstant): The language constant referenced in the query. - location_view (google.ads.googleads.v19.resources.types.LocationView): + location_view (google.ads.googleads.v23.resources.types.LocationView): The location view referenced in the query. - managed_placement_view (google.ads.googleads.v19.resources.types.ManagedPlacementView): + location_interest_view (google.ads.googleads.v23.resources.types.LocationInterestView): + The location interest view referenced in the + query. + managed_placement_view (google.ads.googleads.v23.resources.types.ManagedPlacementView): The managed placement view referenced in the query. - content_criterion_view (google.ads.googleads.v19.resources.types.ContentCriterionView): + matched_location_interest_view (google.ads.googleads.v23.resources.types.MatchedLocationInterestView): + The matched location interest view referenced + in the query. + content_criterion_view (google.ads.googleads.v23.resources.types.ContentCriterionView): The content criterion view referenced in the query. - media_file (google.ads.googleads.v19.resources.types.MediaFile): + media_file (google.ads.googleads.v23.resources.types.MediaFile): The media file referenced in the query. - local_services_employee (google.ads.googleads.v19.resources.types.LocalServicesEmployee): + local_services_employee (google.ads.googleads.v23.resources.types.LocalServicesEmployee): The local services employee referenced in the query. - local_services_verification_artifact (google.ads.googleads.v19.resources.types.LocalServicesVerificationArtifact): + local_services_verification_artifact (google.ads.googleads.v23.resources.types.LocalServicesVerificationArtifact): The local services verification artifact referenced in the query. - mobile_app_category_constant (google.ads.googleads.v19.resources.types.MobileAppCategoryConstant): + mobile_app_category_constant (google.ads.googleads.v23.resources.types.MobileAppCategoryConstant): The mobile app category constant referenced in the query. - mobile_device_constant (google.ads.googleads.v19.resources.types.MobileDeviceConstant): + mobile_device_constant (google.ads.googleads.v23.resources.types.MobileDeviceConstant): The mobile device constant referenced in the query. - offline_conversion_upload_client_summary (google.ads.googleads.v19.resources.types.OfflineConversionUploadClientSummary): + offline_conversion_upload_client_summary (google.ads.googleads.v23.resources.types.OfflineConversionUploadClientSummary): Offline conversion upload summary at customer level. - offline_conversion_upload_conversion_action_summary (google.ads.googleads.v19.resources.types.OfflineConversionUploadConversionActionSummary): + offline_conversion_upload_conversion_action_summary (google.ads.googleads.v23.resources.types.OfflineConversionUploadConversionActionSummary): Offline conversion upload summary at conversion type level. - offline_user_data_job (google.ads.googleads.v19.resources.types.OfflineUserDataJob): + offline_user_data_job (google.ads.googleads.v23.resources.types.OfflineUserDataJob): The offline user data job referenced in the query. - operating_system_version_constant (google.ads.googleads.v19.resources.types.OperatingSystemVersionConstant): + operating_system_version_constant (google.ads.googleads.v23.resources.types.OperatingSystemVersionConstant): The operating system version constant referenced in the query. - paid_organic_search_term_view (google.ads.googleads.v19.resources.types.PaidOrganicSearchTermView): + paid_organic_search_term_view (google.ads.googleads.v23.resources.types.PaidOrganicSearchTermView): The paid organic search term view referenced in the query. - qualifying_question (google.ads.googleads.v19.resources.types.QualifyingQuestion): + qualifying_question (google.ads.googleads.v23.resources.types.QualifyingQuestion): The qualifying question referenced in the query. - parental_status_view (google.ads.googleads.v19.resources.types.ParentalStatusView): + parental_status_view (google.ads.googleads.v23.resources.types.ParentalStatusView): The parental status view referenced in the query. - per_store_view (google.ads.googleads.v19.resources.types.PerStoreView): + per_store_view (google.ads.googleads.v23.resources.types.PerStoreView): The per store view referenced in the query. - performance_max_placement_view (google.ads.googleads.v19.resources.types.PerformanceMaxPlacementView): + performance_max_placement_view (google.ads.googleads.v23.resources.types.PerformanceMaxPlacementView): The performance max placement view referenced in the query. - product_category_constant (google.ads.googleads.v19.resources.types.ProductCategoryConstant): + product_category_constant (google.ads.googleads.v23.resources.types.ProductCategoryConstant): The product category referenced in the query. - product_group_view (google.ads.googleads.v19.resources.types.ProductGroupView): + product_group_view (google.ads.googleads.v23.resources.types.ProductGroupView): The product group view referenced in the query. - product_link (google.ads.googleads.v19.resources.types.ProductLink): + product_link (google.ads.googleads.v23.resources.types.ProductLink): The product link referenced in the query. - product_link_invitation (google.ads.googleads.v19.resources.types.ProductLinkInvitation): + product_link_invitation (google.ads.googleads.v23.resources.types.ProductLinkInvitation): The product link invitation in the query. - recommendation (google.ads.googleads.v19.resources.types.Recommendation): + recommendation (google.ads.googleads.v23.resources.types.Recommendation): The recommendation referenced in the query. - recommendation_subscription (google.ads.googleads.v19.resources.types.RecommendationSubscription): + recommendation_subscription (google.ads.googleads.v23.resources.types.RecommendationSubscription): The recommendation subscription referenced in the query. - search_term_view (google.ads.googleads.v19.resources.types.SearchTermView): + search_term_view (google.ads.googleads.v23.resources.types.SearchTermView): The search term view referenced in the query. - shared_criterion (google.ads.googleads.v19.resources.types.SharedCriterion): + shared_criterion (google.ads.googleads.v23.resources.types.SharedCriterion): The shared set referenced in the query. - shared_set (google.ads.googleads.v19.resources.types.SharedSet): + shared_set (google.ads.googleads.v23.resources.types.SharedSet): The shared set referenced in the query. - smart_campaign_setting (google.ads.googleads.v19.resources.types.SmartCampaignSetting): + smart_campaign_setting (google.ads.googleads.v23.resources.types.SmartCampaignSetting): The Smart campaign setting referenced in the query. - shopping_performance_view (google.ads.googleads.v19.resources.types.ShoppingPerformanceView): + shopping_performance_view (google.ads.googleads.v23.resources.types.ShoppingPerformanceView): The shopping performance view referenced in the query. - shopping_product (google.ads.googleads.v19.resources.types.ShoppingProduct): + shopping_product (google.ads.googleads.v23.resources.types.ShoppingProduct): The shopping product referenced in the query. - smart_campaign_search_term_view (google.ads.googleads.v19.resources.types.SmartCampaignSearchTermView): + smart_campaign_search_term_view (google.ads.googleads.v23.resources.types.SmartCampaignSearchTermView): The Smart campaign search term view referenced in the query. - third_party_app_analytics_link (google.ads.googleads.v19.resources.types.ThirdPartyAppAnalyticsLink): + targeting_expansion_view (google.ads.googleads.v23.resources.types.TargetingExpansionView): + The Targeting expansion view referenced in + the query. + third_party_app_analytics_link (google.ads.googleads.v23.resources.types.ThirdPartyAppAnalyticsLink): The AccountLink referenced in the query. - topic_view (google.ads.googleads.v19.resources.types.TopicView): + topic_view (google.ads.googleads.v23.resources.types.TopicView): The topic view referenced in the query. - travel_activity_group_view (google.ads.googleads.v19.resources.types.TravelActivityGroupView): + travel_activity_group_view (google.ads.googleads.v23.resources.types.TravelActivityGroupView): The travel activity group view referenced in the query. - travel_activity_performance_view (google.ads.googleads.v19.resources.types.TravelActivityPerformanceView): + travel_activity_performance_view (google.ads.googleads.v23.resources.types.TravelActivityPerformanceView): The travel activity performance view referenced in the query. - experiment (google.ads.googleads.v19.resources.types.Experiment): + experiment (google.ads.googleads.v23.resources.types.Experiment): The experiment referenced in the query. - experiment_arm (google.ads.googleads.v19.resources.types.ExperimentArm): + experiment_arm (google.ads.googleads.v23.resources.types.ExperimentArm): The experiment arm referenced in the query. - user_interest (google.ads.googleads.v19.resources.types.UserInterest): + user_interest (google.ads.googleads.v23.resources.types.UserInterest): The user interest referenced in the query. - life_event (google.ads.googleads.v19.resources.types.LifeEvent): + life_event (google.ads.googleads.v23.resources.types.LifeEvent): The life event referenced in the query. - user_list (google.ads.googleads.v19.resources.types.UserList): + user_list (google.ads.googleads.v23.resources.types.UserList): The user list referenced in the query. - user_list_customer_type (google.ads.googleads.v19.resources.types.UserListCustomerType): + user_list_customer_type (google.ads.googleads.v23.resources.types.UserListCustomerType): The user list customer type in the query. - user_location_view (google.ads.googleads.v19.resources.types.UserLocationView): + user_location_view (google.ads.googleads.v23.resources.types.UserLocationView): The user location view referenced in the query. - remarketing_action (google.ads.googleads.v19.resources.types.RemarketingAction): + remarketing_action (google.ads.googleads.v23.resources.types.RemarketingAction): The remarketing action referenced in the query. - topic_constant (google.ads.googleads.v19.resources.types.TopicConstant): + topic_constant (google.ads.googleads.v23.resources.types.TopicConstant): The topic constant referenced in the query. - video (google.ads.googleads.v19.resources.types.Video): + video (google.ads.googleads.v23.resources.types.Video): The video referenced in the query. - webpage_view (google.ads.googleads.v19.resources.types.WebpageView): + webpage_view (google.ads.googleads.v23.resources.types.WebpageView): The webpage view referenced in the query. - lead_form_submission_data (google.ads.googleads.v19.resources.types.LeadFormSubmissionData): + lead_form_submission_data (google.ads.googleads.v23.resources.types.LeadFormSubmissionData): The lead form user submission referenced in the query. - local_services_lead (google.ads.googleads.v19.resources.types.LocalServicesLead): + local_services_lead (google.ads.googleads.v23.resources.types.LocalServicesLead): The local services lead referenced in the query. - local_services_lead_conversation (google.ads.googleads.v19.resources.types.LocalServicesLeadConversation): + local_services_lead_conversation (google.ads.googleads.v23.resources.types.LocalServicesLeadConversation): The local services lead conversationreferenced in the query. - android_privacy_shared_key_google_ad_group (google.ads.googleads.v19.resources.types.AndroidPrivacySharedKeyGoogleAdGroup): + android_privacy_shared_key_google_ad_group (google.ads.googleads.v23.resources.types.AndroidPrivacySharedKeyGoogleAdGroup): The android privacy shared key google ad group referenced in the query. - android_privacy_shared_key_google_campaign (google.ads.googleads.v19.resources.types.AndroidPrivacySharedKeyGoogleCampaign): + android_privacy_shared_key_google_campaign (google.ads.googleads.v23.resources.types.AndroidPrivacySharedKeyGoogleCampaign): The android privacy shared key google campaign referenced in the query. - android_privacy_shared_key_google_network_type (google.ads.googleads.v19.resources.types.AndroidPrivacySharedKeyGoogleNetworkType): + android_privacy_shared_key_google_network_type (google.ads.googleads.v23.resources.types.AndroidPrivacySharedKeyGoogleNetworkType): The android privacy shared key google network type referenced in the query. - metrics (google.ads.googleads.v19.common.types.Metrics): + applied_incentive (google.ads.googleads.v23.resources.types.AppliedIncentive): + The applied incentive referenced in the + query. + metrics (google.ads.googleads.v23.common.types.Metrics): The metrics. - segments (google.ads.googleads.v19.common.types.Segments): + segments (google.ads.googleads.v23.common.types.Segments): The segments. """ @@ -1407,6 +1491,13 @@ class GoogleAdsRow(proto.Message): number=89, message=gagr_ad_schedule_view.AdScheduleView, ) + ai_max_search_term_ad_combination_view: ( + gagr_ai_max_search_term_ad_combination_view.AiMaxSearchTermAdCombinationView + ) = proto.Field( + proto.MESSAGE, + number=242, + message=gagr_ai_max_search_term_ad_combination_view.AiMaxSearchTermAdCombinationView, + ) domain_category: gagr_domain_category.DomainCategory = proto.Field( proto.MESSAGE, number=91, @@ -1595,6 +1686,13 @@ class GoogleAdsRow(proto.Message): number=25, message=gagr_campaign_group.CampaignGroup, ) + campaign_goal_config: gagr_campaign_goal_config.CampaignGoalConfig = ( + proto.Field( + proto.MESSAGE, + number=236, + message=gagr_campaign_goal_config.CampaignGoalConfig, + ) + ) campaign_label: gagr_campaign_label.CampaignLabel = proto.Field( proto.MESSAGE, number=108, @@ -1614,6 +1712,13 @@ class GoogleAdsRow(proto.Message): number=204, message=gagr_campaign_search_term_insight.CampaignSearchTermInsight, ) + campaign_search_term_view: ( + gagr_campaign_search_term_view.CampaignSearchTermView + ) = proto.Field( + proto.MESSAGE, + number=243, + message=gagr_campaign_search_term_view.CampaignSearchTermView, + ) campaign_shared_set: gagr_campaign_shared_set.CampaignSharedSet = ( proto.Field( proto.MESSAGE, @@ -1820,6 +1925,13 @@ class GoogleAdsRow(proto.Message): number=230, message=gagr_data_link.DataLink, ) + detail_content_suitability_placement_view: ( + gagr_detail_content_suitability_placement_view.DetailContentSuitabilityPlacementView + ) = proto.Field( + proto.MESSAGE, + number=238, + message=gagr_detail_content_suitability_placement_view.DetailContentSuitabilityPlacementView, + ) detail_placement_view: gagr_detail_placement_view.DetailPlacementView = ( proto.Field( proto.MESSAGE, @@ -1860,6 +1972,13 @@ class GoogleAdsRow(proto.Message): number=128, message=gagr_expanded_landing_page_view.ExpandedLandingPageView, ) + final_url_expansion_asset_view: ( + gagr_final_url_expansion_asset_view.FinalUrlExpansionAssetView + ) = proto.Field( + proto.MESSAGE, + number=240, + message=gagr_final_url_expansion_asset_view.FinalUrlExpansionAssetView, + ) gender_view: gagr_gender_view.GenderView = proto.Field( proto.MESSAGE, number=40, @@ -1877,6 +1996,18 @@ class GoogleAdsRow(proto.Message): number=125, message=gagr_geographic_view.GeographicView, ) + goal: gagr_goal.Goal = proto.Field( + proto.MESSAGE, + number=237, + message=gagr_goal.Goal, + ) + group_content_suitability_placement_view: ( + gagr_group_content_suitability_placement_view.GroupContentSuitabilityPlacementView + ) = proto.Field( + proto.MESSAGE, + number=239, + message=gagr_group_content_suitability_placement_view.GroupContentSuitabilityPlacementView, + ) group_placement_view: gagr_group_placement_view.GroupPlacementView = ( proto.Field( proto.MESSAGE, @@ -1973,6 +2104,13 @@ class GoogleAdsRow(proto.Message): number=123, message=gagr_location_view.LocationView, ) + location_interest_view: gagr_location_interest_view.LocationInterestView = ( + proto.Field( + proto.MESSAGE, + number=241, + message=gagr_location_interest_view.LocationInterestView, + ) + ) managed_placement_view: gagr_managed_placement_view.ManagedPlacementView = ( proto.Field( proto.MESSAGE, @@ -1980,6 +2118,13 @@ class GoogleAdsRow(proto.Message): message=gagr_managed_placement_view.ManagedPlacementView, ) ) + matched_location_interest_view: ( + gagr_matched_location_interest_view.MatchedLocationInterestView + ) = proto.Field( + proto.MESSAGE, + number=248, + message=gagr_matched_location_interest_view.MatchedLocationInterestView, + ) content_criterion_view: gagr_content_criterion_view.ContentCriterionView = ( proto.Field( proto.MESSAGE, @@ -2158,6 +2303,13 @@ class GoogleAdsRow(proto.Message): number=170, message=gagr_smart_campaign_search_term_view.SmartCampaignSearchTermView, ) + targeting_expansion_view: ( + gagr_targeting_expansion_view.TargetingExpansionView + ) = proto.Field( + proto.MESSAGE, + number=244, + message=gagr_targeting_expansion_view.TargetingExpansionView, + ) third_party_app_analytics_link: ( gagr_third_party_app_analytics_link.ThirdPartyAppAnalyticsLink ) = proto.Field( @@ -2283,6 +2435,11 @@ class GoogleAdsRow(proto.Message): number=219, message=gagr_android_privacy_shared_key_google_network_type.AndroidPrivacySharedKeyGoogleNetworkType, ) + applied_incentive: gagr_applied_incentive.AppliedIncentive = proto.Field( + proto.MESSAGE, + number=246, + message=gagr_applied_incentive.AppliedIncentive, + ) metrics: gagc_metrics.Metrics = proto.Field( proto.MESSAGE, number=4, @@ -2297,13 +2454,13 @@ class GoogleAdsRow(proto.Message): class MutateGoogleAdsRequest(proto.Message): r"""Request message for - [GoogleAdsService.Mutate][google.ads.googleads.v19.services.GoogleAdsService.Mutate]. + [GoogleAdsService.Mutate][google.ads.googleads.v23.services.GoogleAdsService.Mutate]. Attributes: customer_id (str): Required. The ID of the customer whose resources are being modified. - mutate_operations (MutableSequence[google.ads.googleads.v19.services.types.MutateOperation]): + mutate_operations (MutableSequence[google.ads.googleads.v23.services.types.MutateOperation]): Required. The list of operations to perform on individual resources. partial_failure (bool): @@ -2315,7 +2472,7 @@ class MutateGoogleAdsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -2352,7 +2509,7 @@ class MutateGoogleAdsRequest(proto.Message): class MutateGoogleAdsResponse(proto.Message): r"""Response message for - [GoogleAdsService.Mutate][google.ads.googleads.v19.services.GoogleAdsService.Mutate]. + [GoogleAdsService.Mutate][google.ads.googleads.v23.services.GoogleAdsService.Mutate]. Attributes: partial_failure_error (google.rpc.status_pb2.Status): @@ -2361,7 +2518,7 @@ class MutateGoogleAdsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - mutate_operation_responses (MutableSequence[google.ads.googleads.v19.services.types.MutateOperationResponse]): + mutate_operation_responses (MutableSequence[google.ads.googleads.v23.services.types.MutateOperationResponse]): All responses for the mutate. """ @@ -2390,258 +2547,258 @@ class MutateOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - ad_group_ad_label_operation (google.ads.googleads.v19.services.types.AdGroupAdLabelOperation): + ad_group_ad_label_operation (google.ads.googleads.v23.services.types.AdGroupAdLabelOperation): An ad group ad label mutate operation. This field is a member of `oneof`_ ``operation``. - ad_group_ad_operation (google.ads.googleads.v19.services.types.AdGroupAdOperation): + ad_group_ad_operation (google.ads.googleads.v23.services.types.AdGroupAdOperation): An ad group ad mutate operation. This field is a member of `oneof`_ ``operation``. - ad_group_asset_operation (google.ads.googleads.v19.services.types.AdGroupAssetOperation): + ad_group_asset_operation (google.ads.googleads.v23.services.types.AdGroupAssetOperation): An ad group asset mutate operation. This field is a member of `oneof`_ ``operation``. - ad_group_bid_modifier_operation (google.ads.googleads.v19.services.types.AdGroupBidModifierOperation): + ad_group_bid_modifier_operation (google.ads.googleads.v23.services.types.AdGroupBidModifierOperation): An ad group bid modifier mutate operation. This field is a member of `oneof`_ ``operation``. - ad_group_criterion_customizer_operation (google.ads.googleads.v19.services.types.AdGroupCriterionCustomizerOperation): + ad_group_criterion_customizer_operation (google.ads.googleads.v23.services.types.AdGroupCriterionCustomizerOperation): An ad group criterion customizer mutate operation. This field is a member of `oneof`_ ``operation``. - ad_group_criterion_label_operation (google.ads.googleads.v19.services.types.AdGroupCriterionLabelOperation): + ad_group_criterion_label_operation (google.ads.googleads.v23.services.types.AdGroupCriterionLabelOperation): An ad group criterion label mutate operation. This field is a member of `oneof`_ ``operation``. - ad_group_criterion_operation (google.ads.googleads.v19.services.types.AdGroupCriterionOperation): + ad_group_criterion_operation (google.ads.googleads.v23.services.types.AdGroupCriterionOperation): An ad group criterion mutate operation. This field is a member of `oneof`_ ``operation``. - ad_group_customizer_operation (google.ads.googleads.v19.services.types.AdGroupCustomizerOperation): + ad_group_customizer_operation (google.ads.googleads.v23.services.types.AdGroupCustomizerOperation): An ad group customizer mutate operation. This field is a member of `oneof`_ ``operation``. - ad_group_label_operation (google.ads.googleads.v19.services.types.AdGroupLabelOperation): + ad_group_label_operation (google.ads.googleads.v23.services.types.AdGroupLabelOperation): An ad group label mutate operation. This field is a member of `oneof`_ ``operation``. - ad_group_operation (google.ads.googleads.v19.services.types.AdGroupOperation): + ad_group_operation (google.ads.googleads.v23.services.types.AdGroupOperation): An ad group mutate operation. This field is a member of `oneof`_ ``operation``. - ad_operation (google.ads.googleads.v19.services.types.AdOperation): + ad_operation (google.ads.googleads.v23.services.types.AdOperation): An ad mutate operation. This field is a member of `oneof`_ ``operation``. - ad_parameter_operation (google.ads.googleads.v19.services.types.AdParameterOperation): + ad_parameter_operation (google.ads.googleads.v23.services.types.AdParameterOperation): An ad parameter mutate operation. This field is a member of `oneof`_ ``operation``. - asset_operation (google.ads.googleads.v19.services.types.AssetOperation): + asset_operation (google.ads.googleads.v23.services.types.AssetOperation): An asset mutate operation. This field is a member of `oneof`_ ``operation``. - asset_group_asset_operation (google.ads.googleads.v19.services.types.AssetGroupAssetOperation): + asset_group_asset_operation (google.ads.googleads.v23.services.types.AssetGroupAssetOperation): An asset group asset mutate operation. This field is a member of `oneof`_ ``operation``. - asset_group_listing_group_filter_operation (google.ads.googleads.v19.services.types.AssetGroupListingGroupFilterOperation): + asset_group_listing_group_filter_operation (google.ads.googleads.v23.services.types.AssetGroupListingGroupFilterOperation): An asset group listing group filter mutate operation. This field is a member of `oneof`_ ``operation``. - asset_group_signal_operation (google.ads.googleads.v19.services.types.AssetGroupSignalOperation): + asset_group_signal_operation (google.ads.googleads.v23.services.types.AssetGroupSignalOperation): An asset group signal mutate operation. This field is a member of `oneof`_ ``operation``. - asset_group_operation (google.ads.googleads.v19.services.types.AssetGroupOperation): + asset_group_operation (google.ads.googleads.v23.services.types.AssetGroupOperation): An asset group mutate operation. This field is a member of `oneof`_ ``operation``. - asset_set_asset_operation (google.ads.googleads.v19.services.types.AssetSetAssetOperation): + asset_set_asset_operation (google.ads.googleads.v23.services.types.AssetSetAssetOperation): An asset set asset mutate operation. This field is a member of `oneof`_ ``operation``. - asset_set_operation (google.ads.googleads.v19.services.types.AssetSetOperation): + asset_set_operation (google.ads.googleads.v23.services.types.AssetSetOperation): An asset set mutate operation. This field is a member of `oneof`_ ``operation``. - audience_operation (google.ads.googleads.v19.services.types.AudienceOperation): + audience_operation (google.ads.googleads.v23.services.types.AudienceOperation): An audience mutate operation. This field is a member of `oneof`_ ``operation``. - bidding_data_exclusion_operation (google.ads.googleads.v19.services.types.BiddingDataExclusionOperation): + bidding_data_exclusion_operation (google.ads.googleads.v23.services.types.BiddingDataExclusionOperation): A bidding data exclusion mutate operation. This field is a member of `oneof`_ ``operation``. - bidding_seasonality_adjustment_operation (google.ads.googleads.v19.services.types.BiddingSeasonalityAdjustmentOperation): + bidding_seasonality_adjustment_operation (google.ads.googleads.v23.services.types.BiddingSeasonalityAdjustmentOperation): A bidding seasonality adjustment mutate operation. This field is a member of `oneof`_ ``operation``. - bidding_strategy_operation (google.ads.googleads.v19.services.types.BiddingStrategyOperation): + bidding_strategy_operation (google.ads.googleads.v23.services.types.BiddingStrategyOperation): A bidding strategy mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_asset_operation (google.ads.googleads.v19.services.types.CampaignAssetOperation): + campaign_asset_operation (google.ads.googleads.v23.services.types.CampaignAssetOperation): A campaign asset mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_asset_set_operation (google.ads.googleads.v19.services.types.CampaignAssetSetOperation): + campaign_asset_set_operation (google.ads.googleads.v23.services.types.CampaignAssetSetOperation): A campaign asset mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_bid_modifier_operation (google.ads.googleads.v19.services.types.CampaignBidModifierOperation): + campaign_bid_modifier_operation (google.ads.googleads.v23.services.types.CampaignBidModifierOperation): A campaign bid modifier mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_budget_operation (google.ads.googleads.v19.services.types.CampaignBudgetOperation): + campaign_budget_operation (google.ads.googleads.v23.services.types.CampaignBudgetOperation): A campaign budget mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_conversion_goal_operation (google.ads.googleads.v19.services.types.CampaignConversionGoalOperation): + campaign_conversion_goal_operation (google.ads.googleads.v23.services.types.CampaignConversionGoalOperation): A campaign conversion goal mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_criterion_operation (google.ads.googleads.v19.services.types.CampaignCriterionOperation): + campaign_criterion_operation (google.ads.googleads.v23.services.types.CampaignCriterionOperation): A campaign criterion mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_customizer_operation (google.ads.googleads.v19.services.types.CampaignCustomizerOperation): + campaign_customizer_operation (google.ads.googleads.v23.services.types.CampaignCustomizerOperation): A campaign customizer mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_draft_operation (google.ads.googleads.v19.services.types.CampaignDraftOperation): + campaign_draft_operation (google.ads.googleads.v23.services.types.CampaignDraftOperation): A campaign draft mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_group_operation (google.ads.googleads.v19.services.types.CampaignGroupOperation): + campaign_group_operation (google.ads.googleads.v23.services.types.CampaignGroupOperation): A campaign group mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_label_operation (google.ads.googleads.v19.services.types.CampaignLabelOperation): + campaign_label_operation (google.ads.googleads.v23.services.types.CampaignLabelOperation): A campaign label mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_operation (google.ads.googleads.v19.services.types.CampaignOperation): + campaign_operation (google.ads.googleads.v23.services.types.CampaignOperation): A campaign mutate operation. This field is a member of `oneof`_ ``operation``. - campaign_shared_set_operation (google.ads.googleads.v19.services.types.CampaignSharedSetOperation): + campaign_shared_set_operation (google.ads.googleads.v23.services.types.CampaignSharedSetOperation): A campaign shared set mutate operation. This field is a member of `oneof`_ ``operation``. - conversion_action_operation (google.ads.googleads.v19.services.types.ConversionActionOperation): + conversion_action_operation (google.ads.googleads.v23.services.types.ConversionActionOperation): A conversion action mutate operation. This field is a member of `oneof`_ ``operation``. - conversion_custom_variable_operation (google.ads.googleads.v19.services.types.ConversionCustomVariableOperation): + conversion_custom_variable_operation (google.ads.googleads.v23.services.types.ConversionCustomVariableOperation): A conversion custom variable mutate operation. This field is a member of `oneof`_ ``operation``. - conversion_goal_campaign_config_operation (google.ads.googleads.v19.services.types.ConversionGoalCampaignConfigOperation): + conversion_goal_campaign_config_operation (google.ads.googleads.v23.services.types.ConversionGoalCampaignConfigOperation): A conversion goal campaign config mutate operation. This field is a member of `oneof`_ ``operation``. - conversion_value_rule_operation (google.ads.googleads.v19.services.types.ConversionValueRuleOperation): + conversion_value_rule_operation (google.ads.googleads.v23.services.types.ConversionValueRuleOperation): A conversion value rule mutate operation. This field is a member of `oneof`_ ``operation``. - conversion_value_rule_set_operation (google.ads.googleads.v19.services.types.ConversionValueRuleSetOperation): + conversion_value_rule_set_operation (google.ads.googleads.v23.services.types.ConversionValueRuleSetOperation): A conversion value rule set mutate operation. This field is a member of `oneof`_ ``operation``. - custom_conversion_goal_operation (google.ads.googleads.v19.services.types.CustomConversionGoalOperation): + custom_conversion_goal_operation (google.ads.googleads.v23.services.types.CustomConversionGoalOperation): A custom conversion goal mutate operation. This field is a member of `oneof`_ ``operation``. - customer_asset_operation (google.ads.googleads.v19.services.types.CustomerAssetOperation): + customer_asset_operation (google.ads.googleads.v23.services.types.CustomerAssetOperation): A customer asset mutate operation. This field is a member of `oneof`_ ``operation``. - customer_conversion_goal_operation (google.ads.googleads.v19.services.types.CustomerConversionGoalOperation): + customer_conversion_goal_operation (google.ads.googleads.v23.services.types.CustomerConversionGoalOperation): A customer conversion goal mutate operation. This field is a member of `oneof`_ ``operation``. - customer_customizer_operation (google.ads.googleads.v19.services.types.CustomerCustomizerOperation): + customer_customizer_operation (google.ads.googleads.v23.services.types.CustomerCustomizerOperation): A customer customizer mutate operation. This field is a member of `oneof`_ ``operation``. - customer_label_operation (google.ads.googleads.v19.services.types.CustomerLabelOperation): + customer_label_operation (google.ads.googleads.v23.services.types.CustomerLabelOperation): A customer label mutate operation. This field is a member of `oneof`_ ``operation``. - customer_negative_criterion_operation (google.ads.googleads.v19.services.types.CustomerNegativeCriterionOperation): + customer_negative_criterion_operation (google.ads.googleads.v23.services.types.CustomerNegativeCriterionOperation): A customer negative criterion mutate operation. This field is a member of `oneof`_ ``operation``. - customer_operation (google.ads.googleads.v19.services.types.CustomerOperation): + customer_operation (google.ads.googleads.v23.services.types.CustomerOperation): A customer mutate operation. This field is a member of `oneof`_ ``operation``. - customizer_attribute_operation (google.ads.googleads.v19.services.types.CustomizerAttributeOperation): + customizer_attribute_operation (google.ads.googleads.v23.services.types.CustomizerAttributeOperation): A customizer attribute mutate operation. This field is a member of `oneof`_ ``operation``. - experiment_operation (google.ads.googleads.v19.services.types.ExperimentOperation): + experiment_operation (google.ads.googleads.v23.services.types.ExperimentOperation): An experiment mutate operation. This field is a member of `oneof`_ ``operation``. - experiment_arm_operation (google.ads.googleads.v19.services.types.ExperimentArmOperation): + experiment_arm_operation (google.ads.googleads.v23.services.types.ExperimentArmOperation): An experiment arm mutate operation. This field is a member of `oneof`_ ``operation``. - keyword_plan_ad_group_operation (google.ads.googleads.v19.services.types.KeywordPlanAdGroupOperation): + keyword_plan_ad_group_operation (google.ads.googleads.v23.services.types.KeywordPlanAdGroupOperation): A keyword plan ad group operation. This field is a member of `oneof`_ ``operation``. - keyword_plan_ad_group_keyword_operation (google.ads.googleads.v19.services.types.KeywordPlanAdGroupKeywordOperation): + keyword_plan_ad_group_keyword_operation (google.ads.googleads.v23.services.types.KeywordPlanAdGroupKeywordOperation): A keyword plan ad group keyword operation. This field is a member of `oneof`_ ``operation``. - keyword_plan_campaign_keyword_operation (google.ads.googleads.v19.services.types.KeywordPlanCampaignKeywordOperation): + keyword_plan_campaign_keyword_operation (google.ads.googleads.v23.services.types.KeywordPlanCampaignKeywordOperation): A keyword plan campaign keyword operation. This field is a member of `oneof`_ ``operation``. - keyword_plan_campaign_operation (google.ads.googleads.v19.services.types.KeywordPlanCampaignOperation): + keyword_plan_campaign_operation (google.ads.googleads.v23.services.types.KeywordPlanCampaignOperation): A keyword plan campaign operation. This field is a member of `oneof`_ ``operation``. - keyword_plan_operation (google.ads.googleads.v19.services.types.KeywordPlanOperation): + keyword_plan_operation (google.ads.googleads.v23.services.types.KeywordPlanOperation): A keyword plan operation. This field is a member of `oneof`_ ``operation``. - label_operation (google.ads.googleads.v19.services.types.LabelOperation): + label_operation (google.ads.googleads.v23.services.types.LabelOperation): A label mutate operation. This field is a member of `oneof`_ ``operation``. - recommendation_subscription_operation (google.ads.googleads.v19.services.types.RecommendationSubscriptionOperation): + recommendation_subscription_operation (google.ads.googleads.v23.services.types.RecommendationSubscriptionOperation): A recommendation subscription mutate operation. This field is a member of `oneof`_ ``operation``. - remarketing_action_operation (google.ads.googleads.v19.services.types.RemarketingActionOperation): + remarketing_action_operation (google.ads.googleads.v23.services.types.RemarketingActionOperation): A remarketing action mutate operation. This field is a member of `oneof`_ ``operation``. - shared_criterion_operation (google.ads.googleads.v19.services.types.SharedCriterionOperation): + shared_criterion_operation (google.ads.googleads.v23.services.types.SharedCriterionOperation): A shared criterion mutate operation. This field is a member of `oneof`_ ``operation``. - shared_set_operation (google.ads.googleads.v19.services.types.SharedSetOperation): + shared_set_operation (google.ads.googleads.v23.services.types.SharedSetOperation): A shared set mutate operation. This field is a member of `oneof`_ ``operation``. - smart_campaign_setting_operation (google.ads.googleads.v19.services.types.SmartCampaignSettingOperation): + smart_campaign_setting_operation (google.ads.googleads.v23.services.types.SmartCampaignSettingOperation): A Smart campaign setting mutate operation. This field is a member of `oneof`_ ``operation``. - user_list_operation (google.ads.googleads.v19.services.types.UserListOperation): + user_list_operation (google.ads.googleads.v23.services.types.UserListOperation): A user list mutate operation. This field is a member of `oneof`_ ``operation``. @@ -3132,277 +3289,277 @@ class MutateOperationResponse(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - ad_group_ad_label_result (google.ads.googleads.v19.services.types.MutateAdGroupAdLabelResult): + ad_group_ad_label_result (google.ads.googleads.v23.services.types.MutateAdGroupAdLabelResult): The result for the ad group ad label mutate. This field is a member of `oneof`_ ``response``. - ad_group_ad_result (google.ads.googleads.v19.services.types.MutateAdGroupAdResult): + ad_group_ad_result (google.ads.googleads.v23.services.types.MutateAdGroupAdResult): The result for the ad group ad mutate. This field is a member of `oneof`_ ``response``. - ad_group_asset_result (google.ads.googleads.v19.services.types.MutateAdGroupAssetResult): + ad_group_asset_result (google.ads.googleads.v23.services.types.MutateAdGroupAssetResult): The result for the ad group asset mutate. This field is a member of `oneof`_ ``response``. - ad_group_bid_modifier_result (google.ads.googleads.v19.services.types.MutateAdGroupBidModifierResult): + ad_group_bid_modifier_result (google.ads.googleads.v23.services.types.MutateAdGroupBidModifierResult): The result for the ad group bid modifier mutate. This field is a member of `oneof`_ ``response``. - ad_group_criterion_customizer_result (google.ads.googleads.v19.services.types.MutateAdGroupCriterionCustomizerResult): + ad_group_criterion_customizer_result (google.ads.googleads.v23.services.types.MutateAdGroupCriterionCustomizerResult): The result for the ad group criterion customizer mutate. This field is a member of `oneof`_ ``response``. - ad_group_criterion_label_result (google.ads.googleads.v19.services.types.MutateAdGroupCriterionLabelResult): + ad_group_criterion_label_result (google.ads.googleads.v23.services.types.MutateAdGroupCriterionLabelResult): The result for the ad group criterion label mutate. This field is a member of `oneof`_ ``response``. - ad_group_criterion_result (google.ads.googleads.v19.services.types.MutateAdGroupCriterionResult): + ad_group_criterion_result (google.ads.googleads.v23.services.types.MutateAdGroupCriterionResult): The result for the ad group criterion mutate. This field is a member of `oneof`_ ``response``. - ad_group_customizer_result (google.ads.googleads.v19.services.types.MutateAdGroupCustomizerResult): + ad_group_customizer_result (google.ads.googleads.v23.services.types.MutateAdGroupCustomizerResult): The result for the ad group customizer mutate. This field is a member of `oneof`_ ``response``. - ad_group_label_result (google.ads.googleads.v19.services.types.MutateAdGroupLabelResult): + ad_group_label_result (google.ads.googleads.v23.services.types.MutateAdGroupLabelResult): The result for the ad group label mutate. This field is a member of `oneof`_ ``response``. - ad_group_result (google.ads.googleads.v19.services.types.MutateAdGroupResult): + ad_group_result (google.ads.googleads.v23.services.types.MutateAdGroupResult): The result for the ad group mutate. This field is a member of `oneof`_ ``response``. - ad_parameter_result (google.ads.googleads.v19.services.types.MutateAdParameterResult): + ad_parameter_result (google.ads.googleads.v23.services.types.MutateAdParameterResult): The result for the ad parameter mutate. This field is a member of `oneof`_ ``response``. - ad_result (google.ads.googleads.v19.services.types.MutateAdResult): + ad_result (google.ads.googleads.v23.services.types.MutateAdResult): The result for the ad mutate. This field is a member of `oneof`_ ``response``. - asset_result (google.ads.googleads.v19.services.types.MutateAssetResult): + asset_result (google.ads.googleads.v23.services.types.MutateAssetResult): The result for the asset mutate. This field is a member of `oneof`_ ``response``. - asset_group_asset_result (google.ads.googleads.v19.services.types.MutateAssetGroupAssetResult): + asset_group_asset_result (google.ads.googleads.v23.services.types.MutateAssetGroupAssetResult): The result for the asset group asset mutate. This field is a member of `oneof`_ ``response``. - asset_group_listing_group_filter_result (google.ads.googleads.v19.services.types.MutateAssetGroupListingGroupFilterResult): + asset_group_listing_group_filter_result (google.ads.googleads.v23.services.types.MutateAssetGroupListingGroupFilterResult): The result for the asset group listing group filter mutate. This field is a member of `oneof`_ ``response``. - asset_group_signal_result (google.ads.googleads.v19.services.types.MutateAssetGroupSignalResult): + asset_group_signal_result (google.ads.googleads.v23.services.types.MutateAssetGroupSignalResult): The result for the asset group signal mutate. This field is a member of `oneof`_ ``response``. - asset_group_result (google.ads.googleads.v19.services.types.MutateAssetGroupResult): + asset_group_result (google.ads.googleads.v23.services.types.MutateAssetGroupResult): The result for the asset group mutate. This field is a member of `oneof`_ ``response``. - asset_set_asset_result (google.ads.googleads.v19.services.types.MutateAssetSetAssetResult): + asset_set_asset_result (google.ads.googleads.v23.services.types.MutateAssetSetAssetResult): The result for the asset set asset mutate. This field is a member of `oneof`_ ``response``. - asset_set_result (google.ads.googleads.v19.services.types.MutateAssetSetResult): + asset_set_result (google.ads.googleads.v23.services.types.MutateAssetSetResult): The result for the asset set mutate. This field is a member of `oneof`_ ``response``. - audience_result (google.ads.googleads.v19.services.types.MutateAudienceResult): + audience_result (google.ads.googleads.v23.services.types.MutateAudienceResult): The result for the audience mutate. This field is a member of `oneof`_ ``response``. - bidding_data_exclusion_result (google.ads.googleads.v19.services.types.MutateBiddingDataExclusionsResult): + bidding_data_exclusion_result (google.ads.googleads.v23.services.types.MutateBiddingDataExclusionsResult): The result for the bidding data exclusion mutate. This field is a member of `oneof`_ ``response``. - bidding_seasonality_adjustment_result (google.ads.googleads.v19.services.types.MutateBiddingSeasonalityAdjustmentsResult): + bidding_seasonality_adjustment_result (google.ads.googleads.v23.services.types.MutateBiddingSeasonalityAdjustmentsResult): The result for the bidding seasonality adjustment mutate. This field is a member of `oneof`_ ``response``. - bidding_strategy_result (google.ads.googleads.v19.services.types.MutateBiddingStrategyResult): + bidding_strategy_result (google.ads.googleads.v23.services.types.MutateBiddingStrategyResult): The result for the bidding strategy mutate. This field is a member of `oneof`_ ``response``. - campaign_asset_result (google.ads.googleads.v19.services.types.MutateCampaignAssetResult): + campaign_asset_result (google.ads.googleads.v23.services.types.MutateCampaignAssetResult): The result for the campaign asset mutate. This field is a member of `oneof`_ ``response``. - campaign_asset_set_result (google.ads.googleads.v19.services.types.MutateCampaignAssetSetResult): + campaign_asset_set_result (google.ads.googleads.v23.services.types.MutateCampaignAssetSetResult): The result for the campaign asset set mutate. This field is a member of `oneof`_ ``response``. - campaign_bid_modifier_result (google.ads.googleads.v19.services.types.MutateCampaignBidModifierResult): + campaign_bid_modifier_result (google.ads.googleads.v23.services.types.MutateCampaignBidModifierResult): The result for the campaign bid modifier mutate. This field is a member of `oneof`_ ``response``. - campaign_budget_result (google.ads.googleads.v19.services.types.MutateCampaignBudgetResult): + campaign_budget_result (google.ads.googleads.v23.services.types.MutateCampaignBudgetResult): The result for the campaign budget mutate. This field is a member of `oneof`_ ``response``. - campaign_conversion_goal_result (google.ads.googleads.v19.services.types.MutateCampaignConversionGoalResult): + campaign_conversion_goal_result (google.ads.googleads.v23.services.types.MutateCampaignConversionGoalResult): The result for the campaign conversion goal mutate. This field is a member of `oneof`_ ``response``. - campaign_criterion_result (google.ads.googleads.v19.services.types.MutateCampaignCriterionResult): + campaign_criterion_result (google.ads.googleads.v23.services.types.MutateCampaignCriterionResult): The result for the campaign criterion mutate. This field is a member of `oneof`_ ``response``. - campaign_customizer_result (google.ads.googleads.v19.services.types.MutateCampaignCustomizerResult): + campaign_customizer_result (google.ads.googleads.v23.services.types.MutateCampaignCustomizerResult): The result for the campaign customizer mutate. This field is a member of `oneof`_ ``response``. - campaign_draft_result (google.ads.googleads.v19.services.types.MutateCampaignDraftResult): + campaign_draft_result (google.ads.googleads.v23.services.types.MutateCampaignDraftResult): The result for the campaign draft mutate. This field is a member of `oneof`_ ``response``. - campaign_group_result (google.ads.googleads.v19.services.types.MutateCampaignGroupResult): + campaign_group_result (google.ads.googleads.v23.services.types.MutateCampaignGroupResult): The result for the campaign group mutate. This field is a member of `oneof`_ ``response``. - campaign_label_result (google.ads.googleads.v19.services.types.MutateCampaignLabelResult): + campaign_label_result (google.ads.googleads.v23.services.types.MutateCampaignLabelResult): The result for the campaign label mutate. This field is a member of `oneof`_ ``response``. - campaign_result (google.ads.googleads.v19.services.types.MutateCampaignResult): + campaign_result (google.ads.googleads.v23.services.types.MutateCampaignResult): The result for the campaign mutate. This field is a member of `oneof`_ ``response``. - campaign_shared_set_result (google.ads.googleads.v19.services.types.MutateCampaignSharedSetResult): + campaign_shared_set_result (google.ads.googleads.v23.services.types.MutateCampaignSharedSetResult): The result for the campaign shared set mutate. This field is a member of `oneof`_ ``response``. - conversion_action_result (google.ads.googleads.v19.services.types.MutateConversionActionResult): + conversion_action_result (google.ads.googleads.v23.services.types.MutateConversionActionResult): The result for the conversion action mutate. This field is a member of `oneof`_ ``response``. - conversion_custom_variable_result (google.ads.googleads.v19.services.types.MutateConversionCustomVariableResult): + conversion_custom_variable_result (google.ads.googleads.v23.services.types.MutateConversionCustomVariableResult): The result for the conversion custom variable mutate. This field is a member of `oneof`_ ``response``. - conversion_goal_campaign_config_result (google.ads.googleads.v19.services.types.MutateConversionGoalCampaignConfigResult): + conversion_goal_campaign_config_result (google.ads.googleads.v23.services.types.MutateConversionGoalCampaignConfigResult): The result for the conversion goal campaign config mutate. This field is a member of `oneof`_ ``response``. - conversion_value_rule_result (google.ads.googleads.v19.services.types.MutateConversionValueRuleResult): + conversion_value_rule_result (google.ads.googleads.v23.services.types.MutateConversionValueRuleResult): The result for the conversion value rule mutate. This field is a member of `oneof`_ ``response``. - conversion_value_rule_set_result (google.ads.googleads.v19.services.types.MutateConversionValueRuleSetResult): + conversion_value_rule_set_result (google.ads.googleads.v23.services.types.MutateConversionValueRuleSetResult): The result for the conversion value rule set mutate. This field is a member of `oneof`_ ``response``. - custom_conversion_goal_result (google.ads.googleads.v19.services.types.MutateCustomConversionGoalResult): + custom_conversion_goal_result (google.ads.googleads.v23.services.types.MutateCustomConversionGoalResult): The result for the custom conversion goal mutate. This field is a member of `oneof`_ ``response``. - customer_asset_result (google.ads.googleads.v19.services.types.MutateCustomerAssetResult): + customer_asset_result (google.ads.googleads.v23.services.types.MutateCustomerAssetResult): The result for the customer asset mutate. This field is a member of `oneof`_ ``response``. - customer_conversion_goal_result (google.ads.googleads.v19.services.types.MutateCustomerConversionGoalResult): + customer_conversion_goal_result (google.ads.googleads.v23.services.types.MutateCustomerConversionGoalResult): The result for the customer conversion goal mutate. This field is a member of `oneof`_ ``response``. - customer_customizer_result (google.ads.googleads.v19.services.types.MutateCustomerCustomizerResult): + customer_customizer_result (google.ads.googleads.v23.services.types.MutateCustomerCustomizerResult): The result for the customer customizer mutate. This field is a member of `oneof`_ ``response``. - customer_label_result (google.ads.googleads.v19.services.types.MutateCustomerLabelResult): + customer_label_result (google.ads.googleads.v23.services.types.MutateCustomerLabelResult): The result for the customer label mutate. This field is a member of `oneof`_ ``response``. - customer_negative_criterion_result (google.ads.googleads.v19.services.types.MutateCustomerNegativeCriteriaResult): + customer_negative_criterion_result (google.ads.googleads.v23.services.types.MutateCustomerNegativeCriteriaResult): The result for the customer negative criterion mutate. This field is a member of `oneof`_ ``response``. - customer_result (google.ads.googleads.v19.services.types.MutateCustomerResult): + customer_result (google.ads.googleads.v23.services.types.MutateCustomerResult): The result for the customer mutate. This field is a member of `oneof`_ ``response``. - customizer_attribute_result (google.ads.googleads.v19.services.types.MutateCustomizerAttributeResult): + customizer_attribute_result (google.ads.googleads.v23.services.types.MutateCustomizerAttributeResult): The result for the customizer attribute mutate. This field is a member of `oneof`_ ``response``. - experiment_result (google.ads.googleads.v19.services.types.MutateExperimentResult): + experiment_result (google.ads.googleads.v23.services.types.MutateExperimentResult): The result for the experiment mutate. This field is a member of `oneof`_ ``response``. - experiment_arm_result (google.ads.googleads.v19.services.types.MutateExperimentArmResult): + experiment_arm_result (google.ads.googleads.v23.services.types.MutateExperimentArmResult): The result for the experiment arm mutate. This field is a member of `oneof`_ ``response``. - keyword_plan_ad_group_result (google.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupResult): + keyword_plan_ad_group_result (google.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupResult): The result for the keyword plan ad group mutate. This field is a member of `oneof`_ ``response``. - keyword_plan_campaign_result (google.ads.googleads.v19.services.types.MutateKeywordPlanCampaignResult): + keyword_plan_campaign_result (google.ads.googleads.v23.services.types.MutateKeywordPlanCampaignResult): The result for the keyword plan campaign mutate. This field is a member of `oneof`_ ``response``. - keyword_plan_ad_group_keyword_result (google.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupKeywordResult): + keyword_plan_ad_group_keyword_result (google.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupKeywordResult): The result for the keyword plan ad group keyword mutate. This field is a member of `oneof`_ ``response``. - keyword_plan_campaign_keyword_result (google.ads.googleads.v19.services.types.MutateKeywordPlanCampaignKeywordResult): + keyword_plan_campaign_keyword_result (google.ads.googleads.v23.services.types.MutateKeywordPlanCampaignKeywordResult): The result for the keyword plan campaign keyword mutate. This field is a member of `oneof`_ ``response``. - keyword_plan_result (google.ads.googleads.v19.services.types.MutateKeywordPlansResult): + keyword_plan_result (google.ads.googleads.v23.services.types.MutateKeywordPlansResult): The result for the keyword plan mutate. This field is a member of `oneof`_ ``response``. - label_result (google.ads.googleads.v19.services.types.MutateLabelResult): + label_result (google.ads.googleads.v23.services.types.MutateLabelResult): The result for the label mutate. This field is a member of `oneof`_ ``response``. - recommendation_subscription_result (google.ads.googleads.v19.services.types.MutateRecommendationSubscriptionResult): + recommendation_subscription_result (google.ads.googleads.v23.services.types.MutateRecommendationSubscriptionResult): The result for the recommendation subscription mutate. This field is a member of `oneof`_ ``response``. - remarketing_action_result (google.ads.googleads.v19.services.types.MutateRemarketingActionResult): + remarketing_action_result (google.ads.googleads.v23.services.types.MutateRemarketingActionResult): The result for the remarketing action mutate. This field is a member of `oneof`_ ``response``. - shared_criterion_result (google.ads.googleads.v19.services.types.MutateSharedCriterionResult): + shared_criterion_result (google.ads.googleads.v23.services.types.MutateSharedCriterionResult): The result for the shared criterion mutate. This field is a member of `oneof`_ ``response``. - shared_set_result (google.ads.googleads.v19.services.types.MutateSharedSetResult): + shared_set_result (google.ads.googleads.v23.services.types.MutateSharedSetResult): The result for the shared set mutate. This field is a member of `oneof`_ ``response``. - smart_campaign_setting_result (google.ads.googleads.v19.services.types.MutateSmartCampaignSettingResult): + smart_campaign_setting_result (google.ads.googleads.v23.services.types.MutateSmartCampaignSettingResult): The result for the Smart campaign setting mutate. This field is a member of `oneof`_ ``response``. - user_list_result (google.ads.googleads.v19.services.types.MutateUserListResult): + user_list_result (google.ads.googleads.v23.services.types.MutateUserListResult): The result for the user list mutate. This field is a member of `oneof`_ ``response``. @@ -3915,4 +4072,44 @@ class SearchSettings(proto.Message): ) +class MetricAttributes(proto.Message): + r"""Indicates the attributes of metrics. + + Attributes: + name (str): + The name of the metric. + attributes (MutableSequence[google.ads.googleads.v23.services.types.MetricAttributes.Attribute]): + The attributes of the metric. + """ + + class Attribute(proto.Message): + r"""The attribute of the metric in key value pair format. + + Attributes: + key (str): + The key of the attribute. + value (str): + The value of the attribute. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + value: str = proto.Field( + proto.STRING, + number=2, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + attributes: MutableSequence[Attribute] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=Attribute, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/identity_verification_service.py b/google/ads/googleads/v23/services/types/identity_verification_service.py similarity index 86% rename from google/ads/googleads/v19/services/types/identity_verification_service.py rename to google/ads/googleads/v23/services/types/identity_verification_service.py index 4aacd048b..c57471d9b 100644 --- a/google/ads/googleads/v19/services/types/identity_verification_service.py +++ b/google/ads/googleads/v23/services/types/identity_verification_service.py @@ -19,15 +19,15 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import identity_verification_program -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import identity_verification_program +from google.ads.googleads.v23.enums.types import ( identity_verification_program_status, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "StartIdentityVerificationRequest", "GetIdentityVerificationRequest", @@ -41,13 +41,13 @@ class StartIdentityVerificationRequest(proto.Message): r"""Request message for - [IdentityVerificationService.StartIdentityVerification]. + [StartIdentityVerification][google.ads.googleads.v23.services.IdentityVerificationService.StartIdentityVerification]. Attributes: customer_id (str): Required. The Id of the customer for whom we are creating this verification. - verification_program (google.ads.googleads.v19.enums.types.IdentityVerificationProgramEnum.IdentityVerificationProgram): + verification_program (google.ads.googleads.v23.enums.types.IdentityVerificationProgramEnum.IdentityVerificationProgram): Required. The verification program type for which we want to start the verification. """ @@ -67,7 +67,7 @@ class StartIdentityVerificationRequest(proto.Message): class GetIdentityVerificationRequest(proto.Message): r"""Request message for - [IdentityVerificationService.GetIdentityVerification]. + [GetIdentityVerification][google.ads.googleads.v23.services.IdentityVerificationService.GetIdentityVerification]. Attributes: customer_id (str): @@ -83,10 +83,10 @@ class GetIdentityVerificationRequest(proto.Message): class GetIdentityVerificationResponse(proto.Message): r"""Response message for - [IdentityVerificationService.GetIdentityVerification]. + [GetIdentityVerification][google.ads.googleads.v23.services.IdentityVerificationService.GetIdentityVerification]. Attributes: - identity_verification (MutableSequence[google.ads.googleads.v19.services.types.IdentityVerification]): + identity_verification (MutableSequence[google.ads.googleads.v23.services.types.IdentityVerification]): List of identity verifications for the customer. """ @@ -106,14 +106,14 @@ class IdentityVerification(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - verification_program (google.ads.googleads.v19.enums.types.IdentityVerificationProgramEnum.IdentityVerificationProgram): + verification_program (google.ads.googleads.v23.enums.types.IdentityVerificationProgramEnum.IdentityVerificationProgram): The verification program type. - identity_verification_requirement (google.ads.googleads.v19.services.types.IdentityVerificationRequirement): + identity_verification_requirement (google.ads.googleads.v23.services.types.IdentityVerificationRequirement): The verification requirement for this verification program for this customer. This field is a member of `oneof`_ ``_identity_verification_requirement``. - verification_progress (google.ads.googleads.v19.services.types.IdentityVerificationProgress): + verification_progress (google.ads.googleads.v23.services.types.IdentityVerificationProgress): Information regarding progress for this verification program for this customer. @@ -148,7 +148,7 @@ class IdentityVerificationProgress(proto.Message): verification program type. Attributes: - program_status (google.ads.googleads.v19.enums.types.IdentityVerificationProgramStatusEnum.IdentityVerificationProgramStatus): + program_status (google.ads.googleads.v23.enums.types.IdentityVerificationProgramStatusEnum.IdentityVerificationProgramStatus): Current Status (PENDING_USER_ACTION, SUCCESS, FAILURE etc) invitation_link_expiration_time (str): The timestamp when the action url will expire diff --git a/google/ads/googleads/v23/services/types/incentive_service.py b/google/ads/googleads/v23/services/types/incentive_service.py new file mode 100644 index 000000000..86e3b3b7b --- /dev/null +++ b/google/ads/googleads/v23/services/types/incentive_service.py @@ -0,0 +1,434 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + + +import proto # type: ignore + +from google.type import money_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", + manifest={ + "FetchIncentiveRequest", + "Incentive", + "CyoIncentives", + "IncentiveOffer", + "FetchIncentiveResponse", + "ApplyIncentiveRequest", + "ApplyIncentiveResponse", + }, +) + + +class FetchIncentiveRequest(proto.Message): + r"""Request for getting the acquisition incentive for a user. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + language_code (str): + Optional. User's language code. + If not provided, the server will default to + "en". Possible language codes: + + https://developers.google.com/google-ads/api/data/codes-formats#languages + + This field is a member of `oneof`_ ``_language_code``. + country_code (str): + Optional. User's country code. If not provided, the server + will default to "US". Possible country codes: + https://developers.google.com/google-ads/api/data/codes-formats#country_codes + + This field is a member of `oneof`_ ``_country_code``. + email (str): + Optional. Email of the user that the + requested incentive is meant for. Will be used + for channel partners who do NOT use OAuth to + authenticate on behalf of user. + + This field is a member of `oneof`_ ``_email``. + type_ (google.ads.googleads.v23.services.types.FetchIncentiveRequest.IncentiveType): + Optional. The type of incentive to get. + Defaults to ACQUISITION. + + This field is a member of `oneof`_ ``_type``. + """ + + class IncentiveType(proto.Enum): + r"""Types of incentives offered + + Values: + UNSPECIFIED (0): + Not specified. + UNKNOWN (1): + Unknown incentive type. Should not be used as + a value explicitly. + ACQUISITION (2): + An acquisition incentive. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + ACQUISITION = 2 + + language_code: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + country_code: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + email: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + type_: IncentiveType = proto.Field( + proto.ENUM, + number=4, + optional=True, + enum=IncentiveType, + ) + + +class Incentive(proto.Message): + r"""An incentive that a user can claim for their account. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + incentive_id (int): + The incentive ID of this incentive. This is + used to identify which incentive is selected by + the user in the CYO flow. + + This field is a member of `oneof`_ ``_incentive_id``. + requirement (google.ads.googleads.v23.services.types.Incentive.Requirement): + The requirement for this incentive. + + This field is a member of `oneof`_ ``_requirement``. + incentive_terms_and_conditions_url (str): + The URL of the terms and conditions for THIS incentive offer + ONLY. + + This is different from the terms_and_conditions_url field in + AcquisitionIncentiveOffer which is a combination of all the + Incentive offers in a CYO offer. + + This field is a member of `oneof`_ ``_incentive_terms_and_conditions_url``. + type_ (google.ads.googleads.v23.services.types.FetchIncentiveRequest.IncentiveType): + The type of the incentive. + + This field is a member of `oneof`_ ``_type``. + """ + + class Requirement(proto.Message): + r"""Requirement for an incentive. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + spend (google.ads.googleads.v23.services.types.Incentive.Requirement.Spend): + Optional. Spend requirement for an incentive. + + This field is a member of `oneof`_ ``requirement``. + """ + + class Spend(proto.Message): + r"""Spend requirements for an incentive. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + award_amount (google.type.money_pb2.Money): + Required. Amount in free spend that user will + be granted after spending target amount. + Denominated in the currency of the country + passed in the get request. + + This field is a member of `oneof`_ ``_award_amount``. + required_amount (google.type.money_pb2.Money): + Required. Amount that user must spend to + receive the award amount. Denominated in the + currency of the country passed in the get + request. + + This field is a member of `oneof`_ ``_required_amount``. + """ + + award_amount: money_pb2.Money = proto.Field( + proto.MESSAGE, + number=1, + optional=True, + message=money_pb2.Money, + ) + required_amount: money_pb2.Money = proto.Field( + proto.MESSAGE, + number=2, + optional=True, + message=money_pb2.Money, + ) + + spend: "Incentive.Requirement.Spend" = proto.Field( + proto.MESSAGE, + number=1, + oneof="requirement", + message="Incentive.Requirement.Spend", + ) + + incentive_id: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + requirement: Requirement = proto.Field( + proto.MESSAGE, + number=2, + optional=True, + message=Requirement, + ) + incentive_terms_and_conditions_url: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + type_: "FetchIncentiveRequest.IncentiveType" = proto.Field( + proto.ENUM, + number=4, + optional=True, + enum="FetchIncentiveRequest.IncentiveType", + ) + + +class CyoIncentives(proto.Message): + r"""An incentive offer in the Choose-Your-Own Incentive feature + where a user can select from a set of incentives with different + money amounts. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + low_offer (google.ads.googleads.v23.services.types.Incentive): + Required. The CYO incentive with low target + and award amounts. + + This field is a member of `oneof`_ ``_low_offer``. + medium_offer (google.ads.googleads.v23.services.types.Incentive): + Required. The CYO incentive with medium + target and award amounts. + + This field is a member of `oneof`_ ``_medium_offer``. + high_offer (google.ads.googleads.v23.services.types.Incentive): + Required. The CYO incentive with high target + and award amounts. + + This field is a member of `oneof`_ ``_high_offer``. + """ + + low_offer: "Incentive" = proto.Field( + proto.MESSAGE, + number=1, + optional=True, + message="Incentive", + ) + medium_offer: "Incentive" = proto.Field( + proto.MESSAGE, + number=2, + optional=True, + message="Incentive", + ) + high_offer: "Incentive" = proto.Field( + proto.MESSAGE, + number=3, + optional=True, + message="Incentive", + ) + + +class IncentiveOffer(proto.Message): + r"""An acquisition incentive offer for a user. An offer means how + the user is treated. An offer can have no incentive or multiple + incentives. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + type_ (google.ads.googleads.v23.services.types.IncentiveOffer.OfferType): + Required. The type of this acquisition + incentive offer. + + This field is a member of `oneof`_ ``_type``. + consolidated_terms_and_conditions_url (str): + Optional. The URL of the terms and conditions + for the incentive offer. + + This field is a member of `oneof`_ ``_consolidated_terms_and_conditions_url``. + cyo_incentives (google.ads.googleads.v23.services.types.CyoIncentives): + CYO incentives. Set when type is CYO_INCENTIVE. + + This field is a member of `oneof`_ ``incentive_details``. + """ + + class OfferType(proto.Enum): + r"""Types of acquisition incentive offers. + + Values: + UNSPECIFIED (0): + Unknown offer type. Should not be used as a + value explicitly. + UNKNOWN (1): + Unknown offer type. + NO_INCENTIVE (2): + An offer with no incentive. + CYO_INCENTIVE (3): + A CYO (Choose-Your-Own) offer with multiple + incentives to choose from. + """ + + UNSPECIFIED = 0 + UNKNOWN = 1 + NO_INCENTIVE = 2 + CYO_INCENTIVE = 3 + + type_: OfferType = proto.Field( + proto.ENUM, + number=1, + optional=True, + enum=OfferType, + ) + consolidated_terms_and_conditions_url: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + cyo_incentives: "CyoIncentives" = proto.Field( + proto.MESSAGE, + number=3, + oneof="incentive_details", + message="CyoIncentives", + ) + + +class FetchIncentiveResponse(proto.Message): + r"""Response from getting the acquisition incentive for a user + when they visit a specific marketing page. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + incentive_offer (google.ads.googleads.v23.services.types.IncentiveOffer): + Required. The acquisition incentive offer for + the user. + + This field is a member of `oneof`_ ``_incentive_offer``. + """ + + incentive_offer: "IncentiveOffer" = proto.Field( + proto.MESSAGE, + number=1, + optional=True, + message="IncentiveOffer", + ) + + +class ApplyIncentiveRequest(proto.Message): + r"""Request message for applying an incentive. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + selected_incentive_id (int): + The incentive ID of this incentive. This is + used to identify which incentive is selected by + the user in the CYO flow. + + This field is a member of `oneof`_ ``_selected_incentive_id``. + customer_id (str): + The customer ID of the account that the + incentive is being applied to. + + This field is a member of `oneof`_ ``_customer_id``. + country_code (str): + Required. User's country code. Required. This field must be + equal to the Google Ads account's billing country. Incentive + eligibility, terms of service, and reward values are often + country-specific. This country code is used to ensure the + selected incentive is applicable to the user. Possible + country codes: + https://developers.google.com/google-ads/api/data/codes-formats#country_codes + + This field is a member of `oneof`_ ``_country_code``. + """ + + selected_incentive_id: int = proto.Field( + proto.INT64, + number=1, + optional=True, + ) + customer_id: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + country_code: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + + +class ApplyIncentiveResponse(proto.Message): + r"""Response for applying an incentive. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + coupon_code (str): + The coupon code of the applied incentive. A globally unique + identifier of the applied incentive. This code is separate + and distinct from the selected_incentive_id in the request. + + This field is a member of `oneof`_ ``_coupon_code``. + creation_time (str): + The timestamp when this incentive was + applied. The timestamp is in UTC timezone and in + "yyyy-MM-dd HH:mm:ss" format. + + This field is a member of `oneof`_ ``_creation_time``. + """ + + coupon_code: str = proto.Field( + proto.STRING, + number=1, + optional=True, + ) + creation_time: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v23/services/types/invoice_service.py b/google/ads/googleads/v23/services/types/invoice_service.py new file mode 100644 index 000000000..49d58a422 --- /dev/null +++ b/google/ads/googleads/v23/services/types/invoice_service.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.enums.types import month_of_year +from google.ads.googleads.v23.resources.types import invoice + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", + manifest={ + "ListInvoicesRequest", + "ListInvoicesResponse", + }, +) + + +class ListInvoicesRequest(proto.Message): + r"""Request message for fetching the invoices of a given billing + setup that were issued during a given month. + + Attributes: + customer_id (str): + Required. The ID of the customer to fetch + invoices for. + billing_setup (str): + Required. The billing setup resource name of the requested + invoices. + + ``customers/{customer_id}/billingSetups/{billing_setup_id}`` + issue_year (str): + Required. The issue year to retrieve + invoices, in yyyy format. Only invoices issued + in 2019 or later can be retrieved. + issue_month (google.ads.googleads.v23.enums.types.MonthOfYearEnum.MonthOfYear): + Required. The issue month to retrieve + invoices. + include_granular_level_invoice_details (bool): + Optional. When true, the response will + include more granular level invoice details such + as campaign level cost breakdown, itemized + regulatory costs and adjustments. The default + value is false. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + billing_setup: str = proto.Field( + proto.STRING, + number=2, + ) + issue_year: str = proto.Field( + proto.STRING, + number=3, + ) + issue_month: month_of_year.MonthOfYearEnum.MonthOfYear = proto.Field( + proto.ENUM, + number=4, + enum=month_of_year.MonthOfYearEnum.MonthOfYear, + ) + include_granular_level_invoice_details: bool = proto.Field( + proto.BOOL, + number=5, + ) + + +class ListInvoicesResponse(proto.Message): + r"""Response message for + [InvoiceService.ListInvoices][google.ads.googleads.v23.services.InvoiceService.ListInvoices]. + + Attributes: + invoices (MutableSequence[google.ads.googleads.v23.resources.types.Invoice]): + The list of invoices that match the billing + setup and time period. + """ + + invoices: MutableSequence[invoice.Invoice] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=invoice.Invoice, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/keyword_plan_ad_group_keyword_service.py b/google/ads/googleads/v23/services/types/keyword_plan_ad_group_keyword_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/keyword_plan_ad_group_keyword_service.py rename to google/ads/googleads/v23/services/types/keyword_plan_ad_group_keyword_service.py index 62bd8993b..57ca5070b 100644 --- a/google/ads/googleads/v19/services/types/keyword_plan_ad_group_keyword_service.py +++ b/google/ads/googleads/v23/services/types/keyword_plan_ad_group_keyword_service.py @@ -19,7 +19,7 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( keyword_plan_ad_group_keyword, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -27,8 +27,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateKeywordPlanAdGroupKeywordsRequest", "KeywordPlanAdGroupKeywordOperation", @@ -40,14 +40,14 @@ class MutateKeywordPlanAdGroupKeywordsRequest(proto.Message): r"""Request message for - [KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords][google.ads.googleads.v19.services.KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords]. + [KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords][google.ads.googleads.v23.services.KeywordPlanAdGroupKeywordService.MutateKeywordPlanAdGroupKeywords]. Attributes: customer_id (str): Required. The ID of the customer whose Keyword Plan ad group keywords are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanAdGroupKeywordOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanAdGroupKeywordOperation]): Required. The list of operations to perform on individual Keyword Plan ad group keywords. partial_failure (bool): @@ -97,13 +97,13 @@ class KeywordPlanAdGroupKeywordOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): The FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.KeywordPlanAdGroupKeyword): + create (google.ads.googleads.v23.resources.types.KeywordPlanAdGroupKeyword): Create operation: No resource name is expected for the new Keyword Plan ad group keyword. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.KeywordPlanAdGroupKeyword): + update (google.ads.googleads.v23.resources.types.KeywordPlanAdGroupKeyword): Update operation: The Keyword Plan ad group keyword is expected to have a valid resource name. @@ -156,7 +156,7 @@ class MutateKeywordPlanAdGroupKeywordsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupKeywordResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupKeywordResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/keyword_plan_ad_group_service.py b/google/ads/googleads/v23/services/types/keyword_plan_ad_group_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/keyword_plan_ad_group_service.py rename to google/ads/googleads/v23/services/types/keyword_plan_ad_group_service.py index dc76814c3..d07450767 100644 --- a/google/ads/googleads/v19/services/types/keyword_plan_ad_group_service.py +++ b/google/ads/googleads/v23/services/types/keyword_plan_ad_group_service.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import keyword_plan_ad_group +from google.ads.googleads.v23.resources.types import keyword_plan_ad_group from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateKeywordPlanAdGroupsRequest", "KeywordPlanAdGroupOperation", @@ -38,13 +38,13 @@ class MutateKeywordPlanAdGroupsRequest(proto.Message): r"""Request message for - [KeywordPlanAdGroupService.MutateKeywordPlanAdGroups][google.ads.googleads.v19.services.KeywordPlanAdGroupService.MutateKeywordPlanAdGroups]. + [KeywordPlanAdGroupService.MutateKeywordPlanAdGroups][google.ads.googleads.v23.services.KeywordPlanAdGroupService.MutateKeywordPlanAdGroups]. Attributes: customer_id (str): Required. The ID of the customer whose Keyword Plan ad groups are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanAdGroupOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanAdGroupOperation]): Required. The list of operations to perform on individual Keyword Plan ad groups. partial_failure (bool): @@ -94,12 +94,12 @@ class KeywordPlanAdGroupOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): The FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.KeywordPlanAdGroup): + create (google.ads.googleads.v23.resources.types.KeywordPlanAdGroup): Create operation: No resource name is expected for the new Keyword Plan ad group. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.KeywordPlanAdGroup): + update (google.ads.googleads.v23.resources.types.KeywordPlanAdGroup): Update operation: The Keyword Plan ad group is expected to have a valid resource name. @@ -147,7 +147,7 @@ class MutateKeywordPlanAdGroupsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateKeywordPlanAdGroupResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateKeywordPlanAdGroupResult]): All results for the mutate. The order of the results is determined by the order of the keywords in the original request. diff --git a/google/ads/googleads/v19/services/types/keyword_plan_campaign_keyword_service.py b/google/ads/googleads/v23/services/types/keyword_plan_campaign_keyword_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/keyword_plan_campaign_keyword_service.py rename to google/ads/googleads/v23/services/types/keyword_plan_campaign_keyword_service.py index 5691f4979..57416cee0 100644 --- a/google/ads/googleads/v19/services/types/keyword_plan_campaign_keyword_service.py +++ b/google/ads/googleads/v23/services/types/keyword_plan_campaign_keyword_service.py @@ -19,7 +19,7 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( keyword_plan_campaign_keyword, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -27,8 +27,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateKeywordPlanCampaignKeywordsRequest", "KeywordPlanCampaignKeywordOperation", @@ -40,13 +40,13 @@ class MutateKeywordPlanCampaignKeywordsRequest(proto.Message): r"""Request message for - [KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords][google.ads.googleads.v19.services.KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords]. + [KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords][google.ads.googleads.v23.services.KeywordPlanCampaignKeywordService.MutateKeywordPlanCampaignKeywords]. Attributes: customer_id (str): Required. The ID of the customer whose campaign keywords are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanCampaignKeywordOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanCampaignKeywordOperation]): Required. The list of operations to perform on individual Keyword Plan campaign keywords. partial_failure (bool): @@ -96,13 +96,13 @@ class KeywordPlanCampaignKeywordOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): The FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.KeywordPlanCampaignKeyword): + create (google.ads.googleads.v23.resources.types.KeywordPlanCampaignKeyword): Create operation: No resource name is expected for the new Keyword Plan campaign keyword. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.KeywordPlanCampaignKeyword): + update (google.ads.googleads.v23.resources.types.KeywordPlanCampaignKeyword): Update operation: The Keyword Plan campaign keyword expected to have a valid resource name. @@ -154,7 +154,7 @@ class MutateKeywordPlanCampaignKeywordsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateKeywordPlanCampaignKeywordResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateKeywordPlanCampaignKeywordResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/keyword_plan_campaign_service.py b/google/ads/googleads/v23/services/types/keyword_plan_campaign_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/keyword_plan_campaign_service.py rename to google/ads/googleads/v23/services/types/keyword_plan_campaign_service.py index 6b6a8cf3f..9b8d9fce9 100644 --- a/google/ads/googleads/v19/services/types/keyword_plan_campaign_service.py +++ b/google/ads/googleads/v23/services/types/keyword_plan_campaign_service.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import keyword_plan_campaign +from google.ads.googleads.v23.resources.types import keyword_plan_campaign from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateKeywordPlanCampaignsRequest", "KeywordPlanCampaignOperation", @@ -38,13 +38,13 @@ class MutateKeywordPlanCampaignsRequest(proto.Message): r"""Request message for - [KeywordPlanCampaignService.MutateKeywordPlanCampaigns][google.ads.googleads.v19.services.KeywordPlanCampaignService.MutateKeywordPlanCampaigns]. + [KeywordPlanCampaignService.MutateKeywordPlanCampaigns][google.ads.googleads.v23.services.KeywordPlanCampaignService.MutateKeywordPlanCampaigns]. Attributes: customer_id (str): Required. The ID of the customer whose Keyword Plan campaigns are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanCampaignOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanCampaignOperation]): Required. The list of operations to perform on individual Keyword Plan campaigns. partial_failure (bool): @@ -94,12 +94,12 @@ class KeywordPlanCampaignOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): The FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.KeywordPlanCampaign): + create (google.ads.googleads.v23.resources.types.KeywordPlanCampaign): Create operation: No resource name is expected for the new Keyword Plan campaign. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.KeywordPlanCampaign): + update (google.ads.googleads.v23.resources.types.KeywordPlanCampaign): Update operation: The Keyword Plan campaign is expected to have a valid resource name. @@ -147,7 +147,7 @@ class MutateKeywordPlanCampaignsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateKeywordPlanCampaignResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateKeywordPlanCampaignResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/keyword_plan_idea_service.py b/google/ads/googleads/v23/services/types/keyword_plan_idea_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/keyword_plan_idea_service.py rename to google/ads/googleads/v23/services/types/keyword_plan_idea_service.py index f8edd57bf..6415620b5 100644 --- a/google/ads/googleads/v19/services/types/keyword_plan_idea_service.py +++ b/google/ads/googleads/v23/services/types/keyword_plan_idea_service.py @@ -19,19 +19,19 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.common.types import dates -from google.ads.googleads.v19.common.types import keyword_plan_common -from google.ads.googleads.v19.enums.types import keyword_match_type -from google.ads.googleads.v19.enums.types import keyword_plan_keyword_annotation -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.common.types import dates +from google.ads.googleads.v23.common.types import keyword_plan_common +from google.ads.googleads.v23.enums.types import keyword_match_type +from google.ads.googleads.v23.enums.types import keyword_plan_keyword_annotation +from google.ads.googleads.v23.enums.types import ( keyword_plan_network as gage_keyword_plan_network, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "GenerateKeywordIdeasRequest", "KeywordAndUrlSeed", @@ -63,7 +63,7 @@ class GenerateKeywordIdeasRequest(proto.Message): r"""Request message for - [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. + [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -105,34 +105,34 @@ class GenerateKeywordIdeasRequest(proto.Message): number of returned resources. If the response contains fewer than 10,000 results it may not be assumed as last page of results. - keyword_plan_network (google.ads.googleads.v19.enums.types.KeywordPlanNetworkEnum.KeywordPlanNetwork): + keyword_plan_network (google.ads.googleads.v23.enums.types.KeywordPlanNetworkEnum.KeywordPlanNetwork): Targeting network. If not set, Google Search And Partners Network will be used. - keyword_annotation (MutableSequence[google.ads.googleads.v19.enums.types.KeywordPlanKeywordAnnotationEnum.KeywordPlanKeywordAnnotation]): + keyword_annotation (MutableSequence[google.ads.googleads.v23.enums.types.KeywordPlanKeywordAnnotationEnum.KeywordPlanKeywordAnnotation]): The keyword annotations to include in response. - aggregate_metrics (google.ads.googleads.v19.common.types.KeywordPlanAggregateMetrics): + aggregate_metrics (google.ads.googleads.v23.common.types.KeywordPlanAggregateMetrics): The aggregate fields to include in response. - historical_metrics_options (google.ads.googleads.v19.common.types.HistoricalMetricsOptions): + historical_metrics_options (google.ads.googleads.v23.common.types.HistoricalMetricsOptions): The options for historical metrics data. - keyword_and_url_seed (google.ads.googleads.v19.services.types.KeywordAndUrlSeed): + keyword_and_url_seed (google.ads.googleads.v23.services.types.KeywordAndUrlSeed): A Keyword and a specific Url to generate ideas from for example, cars, www.example.com/cars. This field is a member of `oneof`_ ``seed``. - keyword_seed (google.ads.googleads.v19.services.types.KeywordSeed): + keyword_seed (google.ads.googleads.v23.services.types.KeywordSeed): A Keyword or phrase to generate ideas from, for example, cars. This field is a member of `oneof`_ ``seed``. - url_seed (google.ads.googleads.v19.services.types.UrlSeed): + url_seed (google.ads.googleads.v23.services.types.UrlSeed): A specific url to generate ideas from, for example, www.example.com/cars. This field is a member of `oneof`_ ``seed``. - site_seed (google.ads.googleads.v19.services.types.SiteSeed): + site_seed (google.ads.googleads.v23.services.types.SiteSeed): The site to generate ideas from, for example, www.example.com. @@ -303,12 +303,12 @@ class UrlSeed(proto.Message): class GenerateKeywordIdeaResponse(proto.Message): r"""Response message for - [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. + [KeywordPlanIdeaService.GenerateKeywordIdeas][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordIdeas]. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.GenerateKeywordIdeaResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.GenerateKeywordIdeaResult]): Results of generating keyword ideas. - aggregate_metric_results (google.ads.googleads.v19.common.types.KeywordPlanAggregateMetricResults): + aggregate_metric_results (google.ads.googleads.v23.common.types.KeywordPlanAggregateMetricResults): The aggregate metrics for all keyword ideas. next_page_token (str): Pagination token used to retrieve the next page of results. @@ -360,9 +360,9 @@ class GenerateKeywordIdeaResult(proto.Message): KeywordPlanService. This field is a member of `oneof`_ ``_text``. - keyword_idea_metrics (google.ads.googleads.v19.common.types.KeywordPlanHistoricalMetrics): + keyword_idea_metrics (google.ads.googleads.v23.common.types.KeywordPlanHistoricalMetrics): The historical metrics for the keyword. - keyword_annotations (google.ads.googleads.v19.common.types.KeywordAnnotations): + keyword_annotations (google.ads.googleads.v23.common.types.KeywordAnnotations): The annotations for the keyword. The annotation data is only provided if requested. @@ -399,7 +399,7 @@ class GenerateKeywordIdeaResult(proto.Message): class GenerateKeywordHistoricalMetricsRequest(proto.Message): r"""Request message for - [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. + [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -430,13 +430,13 @@ class GenerateKeywordHistoricalMetricsRequest(proto.Message): The resource names of the location to target. Maximum is 10. An empty list MAY be used to specify all targeting geos. - keyword_plan_network (google.ads.googleads.v19.enums.types.KeywordPlanNetworkEnum.KeywordPlanNetwork): + keyword_plan_network (google.ads.googleads.v23.enums.types.KeywordPlanNetworkEnum.KeywordPlanNetwork): Targeting network. If not set, Google Search And Partners Network will be used. - aggregate_metrics (google.ads.googleads.v19.common.types.KeywordPlanAggregateMetrics): + aggregate_metrics (google.ads.googleads.v23.common.types.KeywordPlanAggregateMetrics): The aggregate fields to include in response. - historical_metrics_options (google.ads.googleads.v19.common.types.HistoricalMetricsOptions): + historical_metrics_options (google.ads.googleads.v23.common.types.HistoricalMetricsOptions): The options for historical metrics data. """ @@ -486,13 +486,13 @@ class GenerateKeywordHistoricalMetricsRequest(proto.Message): class GenerateKeywordHistoricalMetricsResponse(proto.Message): r"""Response message for - [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. + [KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordHistoricalMetrics]. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.GenerateKeywordHistoricalMetricsResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.GenerateKeywordHistoricalMetricsResult]): List of keywords and their historical metrics. - aggregate_metric_results (google.ads.googleads.v19.common.types.KeywordPlanAggregateMetricResults): + aggregate_metric_results (google.ads.googleads.v23.common.types.KeywordPlanAggregateMetricResults): The aggregate metrics for all keywords. """ @@ -532,7 +532,7 @@ class GenerateKeywordHistoricalMetricsResult(proto.Message): The list of close variants from the requested keywords whose stats are combined into this GenerateKeywordHistoricalMetricsResult. - keyword_metrics (google.ads.googleads.v19.common.types.KeywordPlanHistoricalMetrics): + keyword_metrics (google.ads.googleads.v23.common.types.KeywordPlanHistoricalMetrics): The historical metrics for text and its close variants """ @@ -557,7 +557,7 @@ class GenerateKeywordHistoricalMetricsResult(proto.Message): class GenerateAdGroupThemesRequest(proto.Message): r"""Request message for - [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. + [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. Attributes: customer_id (str): @@ -587,12 +587,12 @@ class GenerateAdGroupThemesRequest(proto.Message): class GenerateAdGroupThemesResponse(proto.Message): r"""Response message for - [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v19.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. + [KeywordPlanIdeaService.GenerateAdGroupThemes][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateAdGroupThemes]. Attributes: - ad_group_keyword_suggestions (MutableSequence[google.ads.googleads.v19.services.types.AdGroupKeywordSuggestion]): + ad_group_keyword_suggestions (MutableSequence[google.ads.googleads.v23.services.types.AdGroupKeywordSuggestion]): A list of suggested AdGroup/keyword pairings. - unusable_ad_groups (MutableSequence[google.ads.googleads.v19.services.types.UnusableAdGroup]): + unusable_ad_groups (MutableSequence[google.ads.googleads.v23.services.types.UnusableAdGroup]): A list of provided AdGroups that could not be used as suggestions. """ @@ -623,7 +623,7 @@ class AdGroupKeywordSuggestion(proto.Message): suggested_keyword_text (str): The normalized version of keyword_text for BROAD/EXACT/PHRASE suggestions. - suggested_match_type (google.ads.googleads.v19.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + suggested_match_type (google.ads.googleads.v23.enums.types.KeywordMatchTypeEnum.KeywordMatchType): The suggested keyword match type. suggested_ad_group (str): The suggested AdGroup for the keyword. Resource name format: @@ -664,8 +664,8 @@ class UnusableAdGroup(proto.Message): AdGroups may not be usable if the AdGroup - - belongs to a Campaign that is not ENABLED or PAUSED - - is itself not ENABLED + - belongs to a Campaign that is not ENABLED or PAUSED + - is itself not ENABLED Attributes: ad_group (str): @@ -688,7 +688,7 @@ class UnusableAdGroup(proto.Message): class GenerateKeywordForecastMetricsRequest(proto.Message): r"""Request message for - [KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. + [KeywordPlanIdeaService.GenerateKeywordForecastMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -705,7 +705,7 @@ class GenerateKeywordForecastMetricsRequest(proto.Message): https://developers.google.com/google-ads/api/data/codes-formats#currency-codes. This field is a member of `oneof`_ ``_currency_code``. - forecast_period (google.ads.googleads.v19.common.types.DateRange): + forecast_period (google.ads.googleads.v23.common.types.DateRange): The date range for the forecast. The start date must be in the future and end date must be within 1 year from today. The reference timezone @@ -713,7 +713,7 @@ class GenerateKeywordForecastMetricsRequest(proto.Message): belonging to the customer. If not set, a default date range from next Sunday to the following Saturday will be used. - campaign (google.ads.googleads.v19.services.types.CampaignToForecast): + campaign (google.ads.googleads.v23.services.types.CampaignToForecast): Required. The campaign used in the forecast. """ @@ -750,15 +750,15 @@ class CampaignToForecast(proto.Message): "languageConstants/{criterion_id}". See https://developers.google.com/google-ads/api/data/codes-formats#languages for the list of language criterion codes. - geo_modifiers (MutableSequence[google.ads.googleads.v19.services.types.CriterionBidModifier]): + geo_modifiers (MutableSequence[google.ads.googleads.v23.services.types.CriterionBidModifier]): Locations to be targeted. Locations must be unique. - keyword_plan_network (google.ads.googleads.v19.enums.types.KeywordPlanNetworkEnum.KeywordPlanNetwork): + keyword_plan_network (google.ads.googleads.v23.enums.types.KeywordPlanNetworkEnum.KeywordPlanNetwork): Required. The network used for targeting. - negative_keywords (MutableSequence[google.ads.googleads.v19.common.types.KeywordInfo]): + negative_keywords (MutableSequence[google.ads.googleads.v23.common.types.KeywordInfo]): The list of negative keywords to be used in the campaign when doing the forecast. - bidding_strategy (google.ads.googleads.v19.services.types.CampaignToForecast.CampaignBiddingStrategy): + bidding_strategy (google.ads.googleads.v23.services.types.CampaignToForecast.CampaignBiddingStrategy): Required. The bidding strategy for the campaign. conversion_rate (float): @@ -771,7 +771,7 @@ class CampaignToForecast(proto.Message): used. This field is a member of `oneof`_ ``_conversion_rate``. - ad_groups (MutableSequence[google.ads.googleads.v19.services.types.ForecastAdGroup]): + ad_groups (MutableSequence[google.ads.googleads.v23.services.types.ForecastAdGroup]): The ad groups in the new campaign to forecast. """ @@ -787,17 +787,17 @@ class CampaignBiddingStrategy(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - manual_cpc_bidding_strategy (google.ads.googleads.v19.services.types.ManualCpcBiddingStrategy): + manual_cpc_bidding_strategy (google.ads.googleads.v23.services.types.ManualCpcBiddingStrategy): Use manual CPC bidding strategy for forecasting. This field is a member of `oneof`_ ``bidding_strategy``. - maximize_clicks_bidding_strategy (google.ads.googleads.v19.services.types.MaximizeClicksBiddingStrategy): + maximize_clicks_bidding_strategy (google.ads.googleads.v23.services.types.MaximizeClicksBiddingStrategy): Use maximize clicks bidding strategy for forecasting. This field is a member of `oneof`_ ``bidding_strategy``. - maximize_conversions_bidding_strategy (google.ads.googleads.v19.services.types.MaximizeConversionsBiddingStrategy): + maximize_conversions_bidding_strategy (google.ads.googleads.v23.services.types.MaximizeConversionsBiddingStrategy): Use maximize conversions bidding strategy for forecasting. @@ -883,11 +883,11 @@ class ForecastAdGroup(proto.Message): strategies that max cpc values. This field is a member of `oneof`_ ``_max_cpc_bid_micros``. - biddable_keywords (MutableSequence[google.ads.googleads.v19.services.types.BiddableKeyword]): + biddable_keywords (MutableSequence[google.ads.googleads.v23.services.types.BiddableKeyword]): Required. The list of biddable keywords to be used in the ad group when doing the forecast. Requires at least one keyword. - negative_keywords (MutableSequence[google.ads.googleads.v19.common.types.KeywordInfo]): + negative_keywords (MutableSequence[google.ads.googleads.v23.common.types.KeywordInfo]): The details of the keyword. You should specify both the keyword text and match type. """ @@ -917,7 +917,7 @@ class BiddableKeyword(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - keyword (google.ads.googleads.v19.common.types.KeywordInfo): + keyword (google.ads.googleads.v23.common.types.KeywordInfo): Required. Keyword. Must have text and match type. max_cpc_bid_micros (int): @@ -1049,13 +1049,13 @@ class MaximizeConversionsBiddingStrategy(proto.Message): class GenerateKeywordForecastMetricsResponse(proto.Message): r"""Response message for - [KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. + [KeywordPlanIdeaService.GenerateKeywordForecastMetrics][google.ads.googleads.v23.services.KeywordPlanIdeaService.GenerateKeywordForecastMetrics]. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - campaign_forecast_metrics (google.ads.googleads.v19.services.types.KeywordForecastMetrics): + campaign_forecast_metrics (google.ads.googleads.v23.services.types.KeywordForecastMetrics): Results of the campaign forecast. This field is a member of `oneof`_ ``_campaign_forecast_metrics``. diff --git a/google/ads/googleads/v19/services/types/keyword_plan_service.py b/google/ads/googleads/v23/services/types/keyword_plan_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/keyword_plan_service.py rename to google/ads/googleads/v23/services/types/keyword_plan_service.py index 0e84f928f..7c2578865 100644 --- a/google/ads/googleads/v19/services/types/keyword_plan_service.py +++ b/google/ads/googleads/v23/services/types/keyword_plan_service.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import keyword_plan +from google.ads.googleads.v23.resources.types import keyword_plan from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateKeywordPlansRequest", "KeywordPlanOperation", @@ -38,13 +38,13 @@ class MutateKeywordPlansRequest(proto.Message): r"""Request message for - [KeywordPlanService.MutateKeywordPlans][google.ads.googleads.v19.services.KeywordPlanService.MutateKeywordPlans]. + [KeywordPlanService.MutateKeywordPlans][google.ads.googleads.v23.services.KeywordPlanService.MutateKeywordPlans]. Attributes: customer_id (str): Required. The ID of the customer whose keyword plans are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.KeywordPlanOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.KeywordPlanOperation]): Required. The list of operations to perform on individual keyword plans. partial_failure (bool): @@ -92,12 +92,12 @@ class KeywordPlanOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): The FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.KeywordPlan): + create (google.ads.googleads.v23.resources.types.KeywordPlan): Create operation: No resource name is expected for the new keyword plan. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.KeywordPlan): + update (google.ads.googleads.v23.resources.types.KeywordPlan): Update operation: The keyword plan is expected to have a valid resource name. @@ -145,7 +145,7 @@ class MutateKeywordPlansResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateKeywordPlansResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateKeywordPlansResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/keyword_theme_constant_service.py b/google/ads/googleads/v23/services/types/keyword_theme_constant_service.py similarity index 88% rename from google/ads/googleads/v19/services/types/keyword_theme_constant_service.py rename to google/ads/googleads/v23/services/types/keyword_theme_constant_service.py index 2c8c37e95..fde0bea75 100644 --- a/google/ads/googleads/v19/services/types/keyword_theme_constant_service.py +++ b/google/ads/googleads/v23/services/types/keyword_theme_constant_service.py @@ -19,12 +19,12 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import keyword_theme_constant +from google.ads.googleads.v23.resources.types import keyword_theme_constant __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "SuggestKeywordThemeConstantsRequest", "SuggestKeywordThemeConstantsResponse", @@ -34,7 +34,7 @@ class SuggestKeywordThemeConstantsRequest(proto.Message): r"""Request message for - [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v19.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. + [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v23.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. Attributes: query_text (str): @@ -67,10 +67,10 @@ class SuggestKeywordThemeConstantsRequest(proto.Message): class SuggestKeywordThemeConstantsResponse(proto.Message): r"""Response message for - [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v19.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. + [KeywordThemeConstantService.SuggestKeywordThemeConstants][google.ads.googleads.v23.services.KeywordThemeConstantService.SuggestKeywordThemeConstants]. Attributes: - keyword_theme_constants (MutableSequence[google.ads.googleads.v19.resources.types.KeywordThemeConstant]): + keyword_theme_constants (MutableSequence[google.ads.googleads.v23.resources.types.KeywordThemeConstant]): Smart Campaign keyword theme suggestions. """ diff --git a/google/ads/googleads/v19/services/types/label_service.py b/google/ads/googleads/v23/services/types/label_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/label_service.py rename to google/ads/googleads/v23/services/types/label_service.py index cf68929ed..be8fdb9f5 100644 --- a/google/ads/googleads/v19/services/types/label_service.py +++ b/google/ads/googleads/v23/services/types/label_service.py @@ -19,17 +19,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import label as gagr_label +from google.ads.googleads.v23.resources.types import label as gagr_label from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateLabelsRequest", "LabelOperation", @@ -41,13 +41,13 @@ class MutateLabelsRequest(proto.Message): r"""Request message for - [LabelService.MutateLabels][google.ads.googleads.v19.services.LabelService.MutateLabels]. + [LabelService.MutateLabels][google.ads.googleads.v23.services.LabelService.MutateLabels]. Attributes: customer_id (str): Required. ID of the customer whose labels are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.LabelOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.LabelOperation]): Required. The list of operations to perform on labels. partial_failure (bool): @@ -59,7 +59,7 @@ class MutateLabelsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -105,12 +105,12 @@ class LabelOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.Label): + create (google.ads.googleads.v23.resources.types.Label): Create operation: No resource name is expected for the new label. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.Label): + update (google.ads.googleads.v23.resources.types.Label): Update operation: The label is expected to have a valid resource name. @@ -158,7 +158,7 @@ class MutateLabelsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateLabelResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateLabelResult]): All results for the mutate. """ @@ -180,7 +180,7 @@ class MutateLabelResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - label (google.ads.googleads.v19.resources.types.Label): + label (google.ads.googleads.v23.resources.types.Label): The mutated label with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/local_services_lead_service.py b/google/ads/googleads/v23/services/types/local_services_lead_service.py similarity index 89% rename from google/ads/googleads/v19/services/types/local_services_lead_service.py rename to google/ads/googleads/v23/services/types/local_services_lead_service.py index 394453fc7..3af804ca1 100644 --- a/google/ads/googleads/v19/services/types/local_services_lead_service.py +++ b/google/ads/googleads/v23/services/types/local_services_lead_service.py @@ -19,24 +19,24 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( local_services_lead_credit_issuance_decision, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( local_services_lead_survey_answer, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( local_services_lead_survey_dissatisfied_reason, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( local_services_lead_survey_satisfied_reason, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "AppendLeadConversationRequest", "AppendLeadConversationResponse", @@ -52,14 +52,14 @@ class AppendLeadConversationRequest(proto.Message): r"""Request message for - [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v19.services.LocalServicesLeadService.AppendLeadConversation]. + [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v23.services.LocalServicesLeadService.AppendLeadConversation]. Attributes: customer_id (str): Required. The Id of the customer which owns the leads onto which the conversations will be appended. - conversations (MutableSequence[google.ads.googleads.v19.services.types.Conversation]): + conversations (MutableSequence[google.ads.googleads.v23.services.types.Conversation]): Required. Conversations that are being appended. """ @@ -77,10 +77,10 @@ class AppendLeadConversationRequest(proto.Message): class AppendLeadConversationResponse(proto.Message): r"""Response message for - [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v19.services.LocalServicesLeadService.AppendLeadConversation]. + [LocalServicesLeadService.AppendLeadConversation][google.ads.googleads.v23.services.LocalServicesLeadService.AppendLeadConversation]. Attributes: - responses (MutableSequence[google.ads.googleads.v19.services.types.ConversationOrError]): + responses (MutableSequence[google.ads.googleads.v23.services.types.ConversationOrError]): Required. List of append conversation operation results. """ @@ -156,7 +156,7 @@ class SurveySatisfied(proto.Message): lead. Attributes: - survey_satisfied_reason (google.ads.googleads.v19.enums.types.LocalServicesLeadSurveySatisfiedReasonEnum.SurveySatisfiedReason): + survey_satisfied_reason (google.ads.googleads.v23.enums.types.LocalServicesLeadSurveySatisfiedReasonEnum.SurveySatisfiedReason): Required. Provider's reason for being satisfied with the lead. other_reason_comment (str): @@ -183,7 +183,7 @@ class SurveyDissatisfied(proto.Message): the lead. Attributes: - survey_dissatisfied_reason (google.ads.googleads.v19.enums.types.LocalServicesLeadSurveyDissatisfiedReasonEnum.SurveyDissatisfiedReason): + survey_dissatisfied_reason (google.ads.googleads.v23.enums.types.LocalServicesLeadSurveyDissatisfiedReasonEnum.SurveyDissatisfiedReason): Required. Provider's reason for not being satisfied with the lead. other_reason_comment (str): @@ -207,7 +207,7 @@ class SurveyDissatisfied(proto.Message): class ProvideLeadFeedbackRequest(proto.Message): r"""Request message for - [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v19.services.LocalServicesLeadService.ProvideLeadFeedback]. + [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v23.services.LocalServicesLeadService.ProvideLeadFeedback]. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -221,15 +221,15 @@ class ProvideLeadFeedbackRequest(proto.Message): Required. The resource name of the local services lead that for which the feedback is being provided. - survey_answer (google.ads.googleads.v19.enums.types.LocalServicesLeadSurveyAnswerEnum.SurveyAnswer): + survey_answer (google.ads.googleads.v23.enums.types.LocalServicesLeadSurveyAnswerEnum.SurveyAnswer): Required. Survey answer for Local Services Ads Lead. - survey_satisfied (google.ads.googleads.v19.services.types.SurveySatisfied): + survey_satisfied (google.ads.googleads.v23.services.types.SurveySatisfied): Details about various factors for being satisfied with the lead. This field is a member of `oneof`_ ``survey_details``. - survey_dissatisfied (google.ads.googleads.v19.services.types.SurveyDissatisfied): + survey_dissatisfied (google.ads.googleads.v23.services.types.SurveyDissatisfied): Details about various factors for not being satisfied with the lead. @@ -263,10 +263,10 @@ class ProvideLeadFeedbackRequest(proto.Message): class ProvideLeadFeedbackResponse(proto.Message): r"""Response message for - [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v19.services.LocalServicesLeadService.ProvideLeadFeedback]. + [LocalServicesLeadService.ProvideLeadFeedback][google.ads.googleads.v23.services.LocalServicesLeadService.ProvideLeadFeedback]. Attributes: - credit_issuance_decision (google.ads.googleads.v19.enums.types.LocalServicesLeadCreditIssuanceDecisionEnum.CreditIssuanceDecision): + credit_issuance_decision (google.ads.googleads.v23.enums.types.LocalServicesLeadCreditIssuanceDecisionEnum.CreditIssuanceDecision): Required. Decision of bonus credit issued or rejected. If a bonus credit is issued, it will be available for use in about two months. diff --git a/google/ads/googleads/v19/services/types/offline_user_data_job_service.py b/google/ads/googleads/v23/services/types/offline_user_data_job_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/offline_user_data_job_service.py rename to google/ads/googleads/v23/services/types/offline_user_data_job_service.py index 9c1475489..a8e9b8c0e 100644 --- a/google/ads/googleads/v19/services/types/offline_user_data_job_service.py +++ b/google/ads/googleads/v23/services/types/offline_user_data_job_service.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import offline_user_data -from google.ads.googleads.v19.resources.types import offline_user_data_job +from google.ads.googleads.v23.common.types import offline_user_data +from google.ads.googleads.v23.resources.types import offline_user_data_job from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "CreateOfflineUserDataJobRequest", "CreateOfflineUserDataJobResponse", @@ -40,13 +40,13 @@ class CreateOfflineUserDataJobRequest(proto.Message): r"""Request message for - [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v19.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. + [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v23.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. Attributes: customer_id (str): Required. The ID of the customer for which to create an offline user data job. - job (google.ads.googleads.v19.resources.types.OfflineUserDataJob): + job (google.ads.googleads.v23.resources.types.OfflineUserDataJob): Required. The offline user data job to be created. validate_only (bool): @@ -79,7 +79,7 @@ class CreateOfflineUserDataJobRequest(proto.Message): class CreateOfflineUserDataJobResponse(proto.Message): r"""Response message for - [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v19.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. + [OfflineUserDataJobService.CreateOfflineUserDataJob][google.ads.googleads.v23.services.OfflineUserDataJobService.CreateOfflineUserDataJob]. Attributes: resource_name (str): @@ -94,7 +94,7 @@ class CreateOfflineUserDataJobResponse(proto.Message): class RunOfflineUserDataJobRequest(proto.Message): r"""Request message for - [OfflineUserDataJobService.RunOfflineUserDataJob][google.ads.googleads.v19.services.OfflineUserDataJobService.RunOfflineUserDataJob]. + [OfflineUserDataJobService.RunOfflineUserDataJob][google.ads.googleads.v23.services.OfflineUserDataJobService.RunOfflineUserDataJob]. Attributes: resource_name (str): @@ -117,7 +117,7 @@ class RunOfflineUserDataJobRequest(proto.Message): class AddOfflineUserDataJobOperationsRequest(proto.Message): r"""Request message for - [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v19.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. + [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v23.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -139,7 +139,7 @@ class AddOfflineUserDataJobOperationsRequest(proto.Message): values. This field is a member of `oneof`_ ``_enable_warnings``. - operations (MutableSequence[google.ads.googleads.v19.services.types.OfflineUserDataJobOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.OfflineUserDataJobOperation]): Required. The list of operations to be done. validate_only (bool): If true, the request is validated but not @@ -185,12 +185,12 @@ class OfflineUserDataJobOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.common.types.UserData): + create (google.ads.googleads.v23.common.types.UserData): Add the provided data to the transaction. Data cannot be retrieved after being uploaded. This field is a member of `oneof`_ ``operation``. - remove (google.ads.googleads.v19.common.types.UserData): + remove (google.ads.googleads.v23.common.types.UserData): Remove the provided data from the transaction. Data cannot be retrieved after being uploaded. @@ -224,7 +224,7 @@ class OfflineUserDataJobOperation(proto.Message): class AddOfflineUserDataJobOperationsResponse(proto.Message): r"""Response message for - [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v19.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. + [OfflineUserDataJobService.AddOfflineUserDataJobOperations][google.ads.googleads.v23.services.OfflineUserDataJobService.AddOfflineUserDataJobOperations]. Attributes: partial_failure_error (google.rpc.status_pb2.Status): diff --git a/google/ads/googleads/v19/services/types/payments_account_service.py b/google/ads/googleads/v23/services/types/payments_account_service.py similarity index 87% rename from google/ads/googleads/v19/services/types/payments_account_service.py rename to google/ads/googleads/v23/services/types/payments_account_service.py index ed6664369..af9d69256 100644 --- a/google/ads/googleads/v19/services/types/payments_account_service.py +++ b/google/ads/googleads/v23/services/types/payments_account_service.py @@ -19,12 +19,12 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import payments_account +from google.ads.googleads.v23.resources.types import payments_account __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "ListPaymentsAccountsRequest", "ListPaymentsAccountsResponse", @@ -50,10 +50,10 @@ class ListPaymentsAccountsRequest(proto.Message): class ListPaymentsAccountsResponse(proto.Message): r"""Response message for - [PaymentsAccountService.ListPaymentsAccounts][google.ads.googleads.v19.services.PaymentsAccountService.ListPaymentsAccounts]. + [PaymentsAccountService.ListPaymentsAccounts][google.ads.googleads.v23.services.PaymentsAccountService.ListPaymentsAccounts]. Attributes: - payments_accounts (MutableSequence[google.ads.googleads.v19.resources.types.PaymentsAccount]): + payments_accounts (MutableSequence[google.ads.googleads.v23.resources.types.PaymentsAccount]): The list of accessible payments accounts. """ diff --git a/google/ads/googleads/v19/services/types/product_link_invitation_service.py b/google/ads/googleads/v23/services/types/product_link_invitation_service.py similarity index 86% rename from google/ads/googleads/v19/services/types/product_link_invitation_service.py rename to google/ads/googleads/v23/services/types/product_link_invitation_service.py index 3e3598e52..d7dcb052f 100644 --- a/google/ads/googleads/v19/services/types/product_link_invitation_service.py +++ b/google/ads/googleads/v23/services/types/product_link_invitation_service.py @@ -18,17 +18,17 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( product_link_invitation_status as gage_product_link_invitation_status, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( product_link_invitation as gagr_product_link_invitation, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "CreateProductLinkInvitationRequest", "CreateProductLinkInvitationResponse", @@ -42,13 +42,13 @@ class CreateProductLinkInvitationRequest(proto.Message): r"""Request message for - [ProductLinkInvitationService.CreateProductLinkInvitation][google.ads.googleads.v19.services.ProductLinkInvitationService.CreateProductLinkInvitation]. + [ProductLinkInvitationService.CreateProductLinkInvitation][google.ads.googleads.v23.services.ProductLinkInvitationService.CreateProductLinkInvitation]. Attributes: customer_id (str): Required. The ID of the customer being modified. - product_link_invitation (google.ads.googleads.v19.resources.types.ProductLinkInvitation): + product_link_invitation (google.ads.googleads.v23.resources.types.ProductLinkInvitation): Required. The product link invitation to be created. """ @@ -82,13 +82,13 @@ class CreateProductLinkInvitationResponse(proto.Message): class UpdateProductLinkInvitationRequest(proto.Message): r"""Request message for - [ProductLinkInvitationService.UpdateProductLinkInvitation][google.ads.googleads.v19.services.ProductLinkInvitationService.UpdateProductLinkInvitation]. + [ProductLinkInvitationService.UpdateProductLinkInvitation][google.ads.googleads.v23.services.ProductLinkInvitationService.UpdateProductLinkInvitation]. Attributes: customer_id (str): Required. The ID of the customer being modified. - product_link_invitation_status (google.ads.googleads.v19.enums.types.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus): + product_link_invitation_status (google.ads.googleads.v23.enums.types.ProductLinkInvitationStatusEnum.ProductLinkInvitationStatus): Required. The product link invitation to be created. resource_name (str): @@ -129,7 +129,7 @@ class UpdateProductLinkInvitationResponse(proto.Message): class RemoveProductLinkInvitationRequest(proto.Message): r"""Request message for - [ProductLinkinvitationService.RemoveProductLinkInvitation][]. + [ProductLinkInvitationService.RemoveProductLinkInvitation][google.ads.googleads.v23.services.ProductLinkInvitationService.RemoveProductLinkInvitation]. Attributes: customer_id (str): @@ -139,7 +139,7 @@ class RemoveProductLinkInvitationRequest(proto.Message): Required. The resource name of the product link invitation being removed. expected, in this format: - ```` + ``customers/{customer_id}/productLinkInvitations/{product_link_invitation_id}`` """ customer_id: str = proto.Field( diff --git a/google/ads/googleads/v19/services/types/product_link_service.py b/google/ads/googleads/v23/services/types/product_link_service.py similarity index 89% rename from google/ads/googleads/v19/services/types/product_link_service.py rename to google/ads/googleads/v23/services/types/product_link_service.py index 1ff0b7299..66cae9324 100644 --- a/google/ads/googleads/v19/services/types/product_link_service.py +++ b/google/ads/googleads/v23/services/types/product_link_service.py @@ -18,14 +18,14 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( product_link as gagr_product_link, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "CreateProductLinkRequest", "CreateProductLinkResponse", @@ -37,13 +37,13 @@ class CreateProductLinkRequest(proto.Message): r"""Request message for - [ProductLinkService.CreateProductLink][google.ads.googleads.v19.services.ProductLinkService.CreateProductLink]. + [ProductLinkService.CreateProductLink][google.ads.googleads.v23.services.ProductLinkService.CreateProductLink]. Attributes: customer_id (str): Required. The ID of the customer for which the product link is created. - product_link (google.ads.googleads.v19.resources.types.ProductLink): + product_link (google.ads.googleads.v23.resources.types.ProductLink): Required. The product link to be created. """ @@ -60,7 +60,7 @@ class CreateProductLinkRequest(proto.Message): class CreateProductLinkResponse(proto.Message): r"""Response message for - [ProductLinkService.CreateProductLink][google.ads.googleads.v19.services.ProductLinkService.CreateProductLink]. + [ProductLinkService.CreateProductLink][google.ads.googleads.v23.services.ProductLinkService.CreateProductLink]. Attributes: resource_name (str): @@ -76,7 +76,7 @@ class CreateProductLinkResponse(proto.Message): class RemoveProductLinkRequest(proto.Message): r"""Request message for - [ProductLinkService.RemoveProductLink][google.ads.googleads.v19.services.ProductLinkService.RemoveProductLink]. + [ProductLinkService.RemoveProductLink][google.ads.googleads.v23.services.ProductLinkService.RemoveProductLink]. Attributes: customer_id (str): diff --git a/google/ads/googleads/v23/services/types/reach_plan_service.py b/google/ads/googleads/v23/services/types/reach_plan_service.py new file mode 100644 index 000000000..1a7302109 --- /dev/null +++ b/google/ads/googleads/v23/services/types/reach_plan_service.py @@ -0,0 +1,1776 @@ +# -*- coding: utf-8 -*- +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableSequence + +import proto # type: ignore + +from google.ads.googleads.v23.common.types import additional_application_info +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.common.types import dates +from google.ads.googleads.v23.enums.types import frequency_cap_time_unit +from google.ads.googleads.v23.enums.types import reach_plan_age_range +from google.ads.googleads.v23.enums.types import ( + reach_plan_conversion_rate_model, +) +from google.ads.googleads.v23.enums.types import reach_plan_network +from google.ads.googleads.v23.enums.types import ( + reach_plan_plannable_user_list_status, +) +from google.ads.googleads.v23.enums.types import reach_plan_surface +from google.ads.googleads.v23.enums.types import target_frequency_time_unit +from google.ads.googleads.v23.enums.types import user_interest_taxonomy_type +from google.ads.googleads.v23.enums.types import ( + user_list_crm_data_source_type as gage_user_list_crm_data_source_type, +) +from google.ads.googleads.v23.enums.types import ( + user_list_type as gage_user_list_type, +) + + +__protobuf__ = proto.module( + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", + manifest={ + "GenerateConversionRatesRequest", + "GenerateConversionRatesResponse", + "ConversionRateSuggestion", + "ListPlannableLocationsRequest", + "ListPlannableLocationsResponse", + "PlannableLocation", + "ListPlannableProductsRequest", + "ListPlannableProductsResponse", + "ProductMetadata", + "ListPlannableUserListsRequest", + "ListPlannableUserListsResponse", + "PlannableUserList", + "PlannableUserListMetadata", + "PlannableTargeting", + "ListPlannableUserInterestsRequest", + "ListPlannableUserInterestsResponse", + "PlannableUserInterest", + "GenerateReachForecastRequest", + "EffectiveFrequencyLimit", + "FrequencyCap", + "Targeting", + "CampaignDuration", + "PlannedProduct", + "GenerateReachForecastResponse", + "ReachCurve", + "ReachForecast", + "Forecast", + "PlannedProductReachForecast", + "PlannedProductForecast", + "OnTargetAudienceMetrics", + "EffectiveFrequencyBreakdown", + "ForecastMetricOptions", + "AudienceTargeting", + "AdvancedProductTargeting", + "YouTubeSelectSettings", + "YouTubeSelectLineUp", + "SurfaceTargetingCombinations", + "SurfaceTargeting", + "TargetFrequencySettings", + }, +) + + +class GenerateConversionRatesRequest(proto.Message): + r"""Request message for + [ReachPlanService.GenerateConversionRates][google.ads.googleads.v23.services.ReachPlanService.GenerateConversionRates]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + Required. The ID of the customer. A + conversion rate based on the historical data of + this customer may be suggested. + customer_reach_group (str): + The name of the customer being planned for. + This is a user-defined value. + + This field is a member of `oneof`_ ``_customer_reach_group``. + reach_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + customer_reach_group: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + reach_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=3, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class GenerateConversionRatesResponse(proto.Message): + r"""Response message for + [ReachPlanService.GenerateConversionRates][google.ads.googleads.v23.services.ReachPlanService.GenerateConversionRates], + containing conversion rate suggestions for supported plannable + products. + + Attributes: + conversion_rate_suggestions (MutableSequence[google.ads.googleads.v23.services.types.ConversionRateSuggestion]): + A list containing conversion rate + suggestions. Each repeated element will have an + associated product code. Multiple suggestions + may share the same product code. + """ + + conversion_rate_suggestions: MutableSequence["ConversionRateSuggestion"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="ConversionRateSuggestion", + ) + ) + + +class ConversionRateSuggestion(proto.Message): + r"""A conversion rate suggestion. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + conversion_rate_model (google.ads.googleads.v23.enums.types.ReachPlanConversionRateModelEnum.ReachPlanConversionRateModel): + Model type used to calculate the suggested + conversion rate. + plannable_product_code (str): + The code associated with the plannable product (for example: + DEMAND_GEN). To list all plannable product codes, use + [ReachPlanService.ListPlannableProducts][google.ads.googleads.v23.services.ReachPlanService.ListPlannableProducts]. + surface_targeting (google.ads.googleads.v23.services.types.SurfaceTargeting): + The surfaces associated with the plannable + product. If not present, the conversion rate is + considered surface agnostic for this product. + + This field is a member of `oneof`_ ``_surface_targeting``. + conversion_rate (float): + The suggested conversion rate. The value is + between 0 and 1 (exclusive). + """ + + conversion_rate_model: ( + reach_plan_conversion_rate_model.ReachPlanConversionRateModelEnum.ReachPlanConversionRateModel + ) = proto.Field( + proto.ENUM, + number=1, + enum=reach_plan_conversion_rate_model.ReachPlanConversionRateModelEnum.ReachPlanConversionRateModel, + ) + plannable_product_code: str = proto.Field( + proto.STRING, + number=2, + ) + surface_targeting: "SurfaceTargeting" = proto.Field( + proto.MESSAGE, + number=4, + optional=True, + message="SurfaceTargeting", + ) + conversion_rate: float = proto.Field( + proto.DOUBLE, + number=3, + ) + + +class ListPlannableLocationsRequest(proto.Message): + r"""Request message for + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v23.services.ReachPlanService.ListPlannableLocations]. + + Attributes: + reach_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + reach_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=1, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class ListPlannableLocationsResponse(proto.Message): + r"""The list of plannable locations. + + Attributes: + plannable_locations (MutableSequence[google.ads.googleads.v23.services.types.PlannableLocation]): + The list of locations available for planning. + See + https://developers.google.com/google-ads/api/reference/data/geotargets + for sample locations. + """ + + plannable_locations: MutableSequence["PlannableLocation"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="PlannableLocation", + ) + ) + + +class PlannableLocation(proto.Message): + r"""A plannable location: country, metro region, province, etc. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + id (str): + The location identifier. + + This field is a member of `oneof`_ ``_id``. + name (str): + The unique location name in English. + + This field is a member of `oneof`_ ``_name``. + parent_country_id (int): + The parent country (not present if location is a country). + If present, will always be a GeoTargetConstant ID. + Additional information such as country name is provided by + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v23.services.ReachPlanService.ListPlannableLocations] + or GoogleAdsService.Search/SearchStream. + + This field is a member of `oneof`_ ``_parent_country_id``. + country_code (str): + The ISO-3166-1 alpha-2 country code that is + associated with the location. + + This field is a member of `oneof`_ ``_country_code``. + location_type (str): + The location's type. Location types correspond to + target_type returned by searching location type in + GoogleAdsService.Search/SearchStream. + + This field is a member of `oneof`_ ``_location_type``. + """ + + id: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + name: str = proto.Field( + proto.STRING, + number=5, + optional=True, + ) + parent_country_id: int = proto.Field( + proto.INT64, + number=6, + optional=True, + ) + country_code: str = proto.Field( + proto.STRING, + number=7, + optional=True, + ) + location_type: str = proto.Field( + proto.STRING, + number=8, + optional=True, + ) + + +class ListPlannableProductsRequest(proto.Message): + r"""Request to list available products in a given location. + + Attributes: + plannable_location_id (str): + Required. The ID of the selected location for planning. To + list the available plannable location IDs use + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v23.services.ReachPlanService.ListPlannableLocations]. + reach_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + plannable_location_id: str = proto.Field( + proto.STRING, + number=2, + ) + reach_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=3, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class ListPlannableProductsResponse(proto.Message): + r"""A response with all available products. + + Attributes: + product_metadata (MutableSequence[google.ads.googleads.v23.services.types.ProductMetadata]): + The list of products available for planning + and related targeting metadata. + """ + + product_metadata: MutableSequence["ProductMetadata"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="ProductMetadata", + ) + + +class ProductMetadata(proto.Message): + r"""The metadata associated with an available plannable product. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + plannable_product_code (str): + The code associated with the ad product (for example: + BUMPER, TRUEVIEW_IN_STREAM). To list the available plannable + product codes use + [ReachPlanService.ListPlannableProducts][google.ads.googleads.v23.services.ReachPlanService.ListPlannableProducts]. + + This field is a member of `oneof`_ ``_plannable_product_code``. + plannable_product_name (str): + The name associated with the ad product. + plannable_targeting (google.ads.googleads.v23.services.types.PlannableTargeting): + The allowed plannable targeting for this + product. + """ + + plannable_product_code: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + plannable_product_name: str = proto.Field( + proto.STRING, + number=3, + ) + plannable_targeting: "PlannableTargeting" = proto.Field( + proto.MESSAGE, + number=2, + message="PlannableTargeting", + ) + + +class ListPlannableUserListsRequest(proto.Message): + r"""Request message for + [ReachPlanService.ListPlannableUserLists][google.ads.googleads.v23.services.ReachPlanService.ListPlannableUserLists] + that lists the available user lists for a customer. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + Required. The ID of the customer. + customer_reach_group (str): + The name of the customer being planned for. + This is a user-defined value. + + This field is a member of `oneof`_ ``_customer_reach_group``. + reach_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + customer_reach_group: str = proto.Field( + proto.STRING, + number=2, + optional=True, + ) + reach_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=3, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class ListPlannableUserListsResponse(proto.Message): + r"""A response with all available user lists with their plannable + status. + + Attributes: + plannable_user_lists (MutableSequence[google.ads.googleads.v23.services.types.PlannableUserList]): + The list of user lists available for planning + and related targeting metadata. + """ + + plannable_user_lists: MutableSequence["PlannableUserList"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="PlannableUserList", + ) + ) + + +class PlannableUserList(proto.Message): + r"""A plannable user list. + + Attributes: + user_list_info (google.ads.googleads.v23.common.types.UserListInfo): + The user list ID. + display_name (str): + The name of the user list. + user_list_type (google.ads.googleads.v23.enums.types.UserListTypeEnum.UserListType): + The user list type. + plannable_status (google.ads.googleads.v23.enums.types.ReachPlanPlannableUserListStatusEnum.ReachPlanPlannableUserListStatus): + The plannable status of the user list. + plannable_user_list_metadata (google.ads.googleads.v23.services.types.PlannableUserListMetadata): + The relevant metadata for this user list. + """ + + user_list_info: criteria.UserListInfo = proto.Field( + proto.MESSAGE, + number=1, + message=criteria.UserListInfo, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + user_list_type: gage_user_list_type.UserListTypeEnum.UserListType = ( + proto.Field( + proto.ENUM, + number=3, + enum=gage_user_list_type.UserListTypeEnum.UserListType, + ) + ) + plannable_status: ( + reach_plan_plannable_user_list_status.ReachPlanPlannableUserListStatusEnum.ReachPlanPlannableUserListStatus + ) = proto.Field( + proto.ENUM, + number=4, + enum=reach_plan_plannable_user_list_status.ReachPlanPlannableUserListStatusEnum.ReachPlanPlannableUserListStatus, + ) + plannable_user_list_metadata: "PlannableUserListMetadata" = proto.Field( + proto.MESSAGE, + number=5, + message="PlannableUserListMetadata", + ) + + +class PlannableUserListMetadata(proto.Message): + r"""The metadata associated with a plannable user list. + + Attributes: + user_list_crm_data_source_type (google.ads.googleads.v23.enums.types.UserListCrmDataSourceTypeEnum.UserListCrmDataSourceType): + The data source type of a CRM based user + list. + """ + + user_list_crm_data_source_type: ( + gage_user_list_crm_data_source_type.UserListCrmDataSourceTypeEnum.UserListCrmDataSourceType + ) = proto.Field( + proto.ENUM, + number=1, + enum=gage_user_list_crm_data_source_type.UserListCrmDataSourceTypeEnum.UserListCrmDataSourceType, + ) + + +class PlannableTargeting(proto.Message): + r"""The targeting for which traffic metrics will be reported. + + Attributes: + age_ranges (MutableSequence[google.ads.googleads.v23.enums.types.ReachPlanAgeRangeEnum.ReachPlanAgeRange]): + Allowed plannable age ranges for the product + for which metrics will be reported. Actual + targeting is computed by mapping this age range + onto standard Google common.AgeRangeInfo values. + genders (MutableSequence[google.ads.googleads.v23.common.types.GenderInfo]): + Targetable genders for the ad product. + devices (MutableSequence[google.ads.googleads.v23.common.types.DeviceInfo]): + Targetable devices for the ad product. TABLET device + targeting is automatically applied to reported metrics when + MOBILE targeting is selected for CPM_MASTHEAD, + GOOGLE_PREFERRED_BUMPER, and GOOGLE_PREFERRED_SHORT + products. + networks (MutableSequence[google.ads.googleads.v23.enums.types.ReachPlanNetworkEnum.ReachPlanNetwork]): + Targetable networks for the ad product. + youtube_select_lineups (MutableSequence[google.ads.googleads.v23.services.types.YouTubeSelectLineUp]): + Targetable YouTube Select Lineups for the ad + product. + surface_targeting (google.ads.googleads.v23.services.types.SurfaceTargetingCombinations): + Targetable surface combinations for the ad + product. + """ + + age_ranges: MutableSequence[ + reach_plan_age_range.ReachPlanAgeRangeEnum.ReachPlanAgeRange + ] = proto.RepeatedField( + proto.ENUM, + number=1, + enum=reach_plan_age_range.ReachPlanAgeRangeEnum.ReachPlanAgeRange, + ) + genders: MutableSequence[criteria.GenderInfo] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=criteria.GenderInfo, + ) + devices: MutableSequence[criteria.DeviceInfo] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=criteria.DeviceInfo, + ) + networks: MutableSequence[ + reach_plan_network.ReachPlanNetworkEnum.ReachPlanNetwork + ] = proto.RepeatedField( + proto.ENUM, + number=4, + enum=reach_plan_network.ReachPlanNetworkEnum.ReachPlanNetwork, + ) + youtube_select_lineups: MutableSequence["YouTubeSelectLineUp"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=5, + message="YouTubeSelectLineUp", + ) + ) + surface_targeting: "SurfaceTargetingCombinations" = proto.Field( + proto.MESSAGE, + number=6, + message="SurfaceTargetingCombinations", + ) + + +class ListPlannableUserInterestsRequest(proto.Message): + r"""Request message for + [ReachPlanService.ListPlannableUserInterests][google.ads.googleads.v23.services.ReachPlanService.ListPlannableUserInterests]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + Required. The ID of the customer. + user_interest_taxonomy_types (MutableSequence[google.ads.googleads.v23.enums.types.UserInterestTaxonomyTypeEnum.UserInterestTaxonomyType]): + Optional. A filter by user interest type. If set, only user + interests with a type listed in the filter will be returned. + If not set, user interests of all supported types will be + returned. Supported user interest types are AFFINITY and + IN_MARKET. Each type must be specified at most once. + name_query (str): + A filter by user interest name. If set, only + user interests with a name containing the + literal string (case insensitive) in the filter + will be returned. Maximum length is 200 + characters. + + This field is a member of `oneof`_ ``_name_query``. + path_query (str): + A filter by user interest path. If set, only + user interests with a path containing the + literal string (case insensitive) in the filter + will be returned. Maximum length is 200 + characters. + + This field is a member of `oneof`_ ``_path_query``. + reach_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + user_interest_taxonomy_types: MutableSequence[ + user_interest_taxonomy_type.UserInterestTaxonomyTypeEnum.UserInterestTaxonomyType + ] = proto.RepeatedField( + proto.ENUM, + number=2, + enum=user_interest_taxonomy_type.UserInterestTaxonomyTypeEnum.UserInterestTaxonomyType, + ) + name_query: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + path_query: str = proto.Field( + proto.STRING, + number=4, + optional=True, + ) + reach_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=5, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class ListPlannableUserInterestsResponse(proto.Message): + r"""Response message for + [ReachPlanService.ListPlannableUserInterests][google.ads.googleads.v23.services.ReachPlanService.ListPlannableUserInterests]. + + Attributes: + plannable_user_interests (MutableSequence[google.ads.googleads.v23.services.types.PlannableUserInterest]): + The list of plannable user interests. + """ + + plannable_user_interests: MutableSequence["PlannableUserInterest"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message="PlannableUserInterest", + ) + ) + + +class PlannableUserInterest(proto.Message): + r"""A plannable user interest that can be targeted in a reach forecast + using + [ReachPlanService.GenerateReachForecast][google.ads.googleads.v23.services.ReachPlanService.GenerateReachForecast]. + + Attributes: + user_interest (google.ads.googleads.v23.common.types.UserInterestInfo): + The user interest id. + user_interest_type (google.ads.googleads.v23.enums.types.UserInterestTaxonomyTypeEnum.UserInterestTaxonomyType): + The user interest type. + user_interest_display_name (str): + The user interest display name. + For example, "Autos & Vehicles". + user_interest_path (str): + The user interest path. + For example, "/Autos & Vehicles/Motor + Vehicles/Motor Vehicles by Type/Off-Road + Vehicles". + """ + + user_interest: criteria.UserInterestInfo = proto.Field( + proto.MESSAGE, + number=1, + message=criteria.UserInterestInfo, + ) + user_interest_type: ( + user_interest_taxonomy_type.UserInterestTaxonomyTypeEnum.UserInterestTaxonomyType + ) = proto.Field( + proto.ENUM, + number=2, + enum=user_interest_taxonomy_type.UserInterestTaxonomyTypeEnum.UserInterestTaxonomyType, + ) + user_interest_display_name: str = proto.Field( + proto.STRING, + number=3, + ) + user_interest_path: str = proto.Field( + proto.STRING, + number=4, + ) + + +class GenerateReachForecastRequest(proto.Message): + r"""Request message for + [ReachPlanService.GenerateReachForecast][google.ads.googleads.v23.services.ReachPlanService.GenerateReachForecast]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + customer_id (str): + Required. The ID of the customer. + currency_code (str): + The currency code. + Three-character ISO 4217 currency code. + + This field is a member of `oneof`_ ``_currency_code``. + campaign_duration (google.ads.googleads.v23.services.types.CampaignDuration): + Required. Campaign duration. + cookie_frequency_cap (int): + Chosen cookie frequency cap to be applied to each planned + product. This is equivalent to the frequency cap exposed in + Google Ads when creating a campaign, it represents the + maximum number of times an ad can be shown to the same user. + If not specified, no cap is applied. + + This field is deprecated in v4 and will eventually be + removed. Use cookie_frequency_cap_setting instead. + + This field is a member of `oneof`_ ``_cookie_frequency_cap``. + cookie_frequency_cap_setting (google.ads.googleads.v23.services.types.FrequencyCap): + Chosen cookie frequency cap to be applied to each planned + product. This is equivalent to the frequency cap exposed in + Google Ads when creating a campaign, it represents the + maximum number of times an ad can be shown to the same user + during a specified time interval. If not specified, a + default of 0 (no cap) is applied. + + This field replaces the deprecated cookie_frequency_cap + field. + min_effective_frequency (int): + Chosen minimum effective frequency (the number of times a + person was exposed to the ad) for the reported reach metrics + [1-10]. This won't affect the targeting, but just the + reporting. If not specified, a default of 1 is applied. + + This field cannot be combined with the + effective_frequency_limit field. + + This field is a member of `oneof`_ ``_min_effective_frequency``. + effective_frequency_limit (google.ads.googleads.v23.services.types.EffectiveFrequencyLimit): + The highest minimum effective frequency (the number of times + a person was exposed to the ad) value [1-10] to include in + Forecast.effective_frequency_breakdowns. If not specified, + Forecast.effective_frequency_breakdowns will not be + provided. + + The effective frequency value provided here will also be + used as the minimum effective frequency for the reported + reach metrics. + + This field cannot be combined with the + min_effective_frequency field. + + This field is a member of `oneof`_ ``_effective_frequency_limit``. + targeting (google.ads.googleads.v23.services.types.Targeting): + The targeting to be applied to all products + selected in the product mix. + This is planned targeting: execution details + might vary based on the advertising product, + consult an implementation specialist. + + See specific metrics for details on how + targeting affects them. + planned_products (MutableSequence[google.ads.googleads.v23.services.types.PlannedProduct]): + Required. The products to be forecast. + The max number of allowed planned products is + 15. + forecast_metric_options (google.ads.googleads.v23.services.types.ForecastMetricOptions): + Controls the forecast metrics returned in the + response. + customer_reach_group (str): + The name of the customer being planned for. + This is a user-defined value. + + This field is a member of `oneof`_ ``_customer_reach_group``. + reach_application_info (google.ads.googleads.v23.common.types.AdditionalApplicationInfo): + Optional. Additional information on the + application issuing the request. + """ + + customer_id: str = proto.Field( + proto.STRING, + number=1, + ) + currency_code: str = proto.Field( + proto.STRING, + number=9, + optional=True, + ) + campaign_duration: "CampaignDuration" = proto.Field( + proto.MESSAGE, + number=3, + message="CampaignDuration", + ) + cookie_frequency_cap: int = proto.Field( + proto.INT32, + number=10, + optional=True, + ) + cookie_frequency_cap_setting: "FrequencyCap" = proto.Field( + proto.MESSAGE, + number=8, + message="FrequencyCap", + ) + min_effective_frequency: int = proto.Field( + proto.INT32, + number=11, + optional=True, + ) + effective_frequency_limit: "EffectiveFrequencyLimit" = proto.Field( + proto.MESSAGE, + number=12, + optional=True, + message="EffectiveFrequencyLimit", + ) + targeting: "Targeting" = proto.Field( + proto.MESSAGE, + number=6, + message="Targeting", + ) + planned_products: MutableSequence["PlannedProduct"] = proto.RepeatedField( + proto.MESSAGE, + number=7, + message="PlannedProduct", + ) + forecast_metric_options: "ForecastMetricOptions" = proto.Field( + proto.MESSAGE, + number=13, + message="ForecastMetricOptions", + ) + customer_reach_group: str = proto.Field( + proto.STRING, + number=14, + optional=True, + ) + reach_application_info: ( + additional_application_info.AdditionalApplicationInfo + ) = proto.Field( + proto.MESSAGE, + number=15, + message=additional_application_info.AdditionalApplicationInfo, + ) + + +class EffectiveFrequencyLimit(proto.Message): + r"""Effective frequency limit. + + Attributes: + effective_frequency_breakdown_limit (int): + The highest effective frequency value to include in + Forecast.effective_frequency_breakdowns. This field supports + frequencies 1-10, inclusive. + """ + + effective_frequency_breakdown_limit: int = proto.Field( + proto.INT32, + number=1, + ) + + +class FrequencyCap(proto.Message): + r"""A rule specifying the maximum number of times an ad can be + shown to a user over a particular time period. + + Attributes: + impressions (int): + Required. The number of impressions, + inclusive. + time_unit (google.ads.googleads.v23.enums.types.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit): + Required. The type of time unit. + """ + + impressions: int = proto.Field( + proto.INT32, + number=3, + ) + time_unit: ( + frequency_cap_time_unit.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit + ) = proto.Field( + proto.ENUM, + number=2, + enum=frequency_cap_time_unit.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit, + ) + + +class Targeting(proto.Message): + r"""The targeting for which traffic metrics will be reported. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + plannable_location_id (str): + The ID of the selected location. Plannable location IDs can + be obtained from + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v23.services.ReachPlanService.ListPlannableLocations]. + + Requests must set either this field or + ``plannable_location_ids``. + + This field is deprecated as of V12 and will be removed in a + future release. Use ``plannable_location_ids`` instead. + + This field is a member of `oneof`_ ``_plannable_location_id``. + plannable_location_ids (MutableSequence[str]): + The list of plannable location IDs to target with this + forecast. + + If more than one ID is provided, all IDs must have the same + ``parent_country_id``. Planning for more than + ``parent_county`` is not supported. Plannable location IDs + and their ``parent_country_id`` can be obtained from + [ReachPlanService.ListPlannableLocations][google.ads.googleads.v23.services.ReachPlanService.ListPlannableLocations]. + + Requests must set either this field or + ``plannable_location_id``. + age_range (google.ads.googleads.v23.enums.types.ReachPlanAgeRangeEnum.ReachPlanAgeRange): + Targeted age range. + An unset value is equivalent to targeting all + ages. + genders (MutableSequence[google.ads.googleads.v23.common.types.GenderInfo]): + Targeted genders. + An unset value is equivalent to targeting MALE + and FEMALE. + devices (MutableSequence[google.ads.googleads.v23.common.types.DeviceInfo]): + Targeted devices. If not specified, targets all applicable + devices. Applicable devices vary by product and region and + can be obtained from + [ReachPlanService.ListPlannableProducts][google.ads.googleads.v23.services.ReachPlanService.ListPlannableProducts]. + network (google.ads.googleads.v23.enums.types.ReachPlanNetworkEnum.ReachPlanNetwork): + Targetable network for the ad product. If not specified, + targets all applicable networks. Applicable networks vary by + product and region and can be obtained from + [ReachPlanService.ListPlannableProducts][google.ads.googleads.v23.services.ReachPlanService.ListPlannableProducts]. + audience_targeting (google.ads.googleads.v23.services.types.AudienceTargeting): + Targeted audiences. + If not specified, does not target any specific + audience. + """ + + plannable_location_id: str = proto.Field( + proto.STRING, + number=6, + optional=True, + ) + plannable_location_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + age_range: reach_plan_age_range.ReachPlanAgeRangeEnum.ReachPlanAgeRange = ( + proto.Field( + proto.ENUM, + number=2, + enum=reach_plan_age_range.ReachPlanAgeRangeEnum.ReachPlanAgeRange, + ) + ) + genders: MutableSequence[criteria.GenderInfo] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=criteria.GenderInfo, + ) + devices: MutableSequence[criteria.DeviceInfo] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message=criteria.DeviceInfo, + ) + network: reach_plan_network.ReachPlanNetworkEnum.ReachPlanNetwork = ( + proto.Field( + proto.ENUM, + number=5, + enum=reach_plan_network.ReachPlanNetworkEnum.ReachPlanNetwork, + ) + ) + audience_targeting: "AudienceTargeting" = proto.Field( + proto.MESSAGE, + number=7, + message="AudienceTargeting", + ) + + +class CampaignDuration(proto.Message): + r"""The duration of a planned campaign. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + duration_in_days (int): + The duration value in days. + + This field cannot be combined with the date_range field. + + This field is a member of `oneof`_ ``_duration_in_days``. + date_range (google.ads.googleads.v23.common.types.DateRange): + Date range of the campaign. Dates are in the yyyy-mm-dd + format and inclusive. The end date must be < 1 year in the + future and the date range must be <= 92 days long. + + This field cannot be combined with the duration_in_days + field. + """ + + duration_in_days: int = proto.Field( + proto.INT32, + number=2, + optional=True, + ) + date_range: dates.DateRange = proto.Field( + proto.MESSAGE, + number=3, + message=dates.DateRange, + ) + + +class PlannedProduct(proto.Message): + r"""A product being planned for reach. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + plannable_product_code (str): + Required. Selected product for planning. The code associated + with the ad product (for example: Trueview, Bumper). To list + the available plannable product codes use + [ReachPlanService.ListPlannableProducts][google.ads.googleads.v23.services.ReachPlanService.ListPlannableProducts]. + + This field is a member of `oneof`_ ``_plannable_product_code``. + budget_micros (int): + Required. Maximum budget allocation in micros for the + selected product. The value is specified in the selected + planning currency_code. For example: 1 000 000$ = 1 000 000 + 000 000 micros. + + This field is a member of `oneof`_ ``_budget_micros``. + conversion_rate (float): + Conversion rate as a decimal between 0 and 1, exclusive. For + example: if 2% of ad interactions are expected to lead to + conversions, conversion_rate should be 0.02. This field is + required for DEMAND_GEN plannable products. It is not + supported for other plannable products. + + This field is a member of `oneof`_ ``_conversion_rate``. + advanced_product_targeting (google.ads.googleads.v23.services.types.AdvancedProductTargeting): + Targeting settings for the selected product. To list the + available targeting for each product use + [ReachPlanService.ListPlannableProducts][google.ads.googleads.v23.services.ReachPlanService.ListPlannableProducts]. + """ + + plannable_product_code: str = proto.Field( + proto.STRING, + number=3, + optional=True, + ) + budget_micros: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + conversion_rate: float = proto.Field( + proto.DOUBLE, + number=6, + optional=True, + ) + advanced_product_targeting: "AdvancedProductTargeting" = proto.Field( + proto.MESSAGE, + number=5, + message="AdvancedProductTargeting", + ) + + +class GenerateReachForecastResponse(proto.Message): + r"""Response message containing the generated reach curve. + + Attributes: + on_target_audience_metrics (google.ads.googleads.v23.services.types.OnTargetAudienceMetrics): + Reference on target audiences for this curve. + reach_curve (google.ads.googleads.v23.services.types.ReachCurve): + The generated reach curve for the planned + product mix. + """ + + on_target_audience_metrics: "OnTargetAudienceMetrics" = proto.Field( + proto.MESSAGE, + number=1, + message="OnTargetAudienceMetrics", + ) + reach_curve: "ReachCurve" = proto.Field( + proto.MESSAGE, + number=2, + message="ReachCurve", + ) + + +class ReachCurve(proto.Message): + r"""The reach curve for the planned products. + + Attributes: + reach_forecasts (MutableSequence[google.ads.googleads.v23.services.types.ReachForecast]): + All points on the reach curve. + """ + + reach_forecasts: MutableSequence["ReachForecast"] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message="ReachForecast", + ) + + +class ReachForecast(proto.Message): + r"""A point on reach curve. + + Attributes: + cost_micros (int): + The cost in micros. + forecast (google.ads.googleads.v23.services.types.Forecast): + Forecasted traffic metrics for this point. + planned_product_reach_forecasts (MutableSequence[google.ads.googleads.v23.services.types.PlannedProductReachForecast]): + The forecasted allocation and traffic metrics + for each planned product at this point on the + reach curve. + """ + + cost_micros: int = proto.Field( + proto.INT64, + number=5, + ) + forecast: "Forecast" = proto.Field( + proto.MESSAGE, + number=2, + message="Forecast", + ) + planned_product_reach_forecasts: MutableSequence[ + "PlannedProductReachForecast" + ] = proto.RepeatedField( + proto.MESSAGE, + number=4, + message="PlannedProductReachForecast", + ) + + +class Forecast(proto.Message): + r"""Forecasted traffic metrics for the planned products and + targeting. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + on_target_reach (int): + Number of unique people reached at least + GenerateReachForecastRequest.min_effective_frequency or + GenerateReachForecastRequest.effective_frequency_limit times + that exactly matches the Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the on_target_reach value will be rounded to 0. + + This field is a member of `oneof`_ ``_on_target_reach``. + total_reach (int): + Total number of unique people reached at least + GenerateReachForecastRequest.min_effective_frequency or + GenerateReachForecastRequest.effective_frequency_limit + times. This includes people that may fall outside the + specified Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the total_reach value will be rounded to 0. + + This field is a member of `oneof`_ ``_total_reach``. + on_target_impressions (int): + Number of ad impressions that exactly matches + the Targeting. + + This field is a member of `oneof`_ ``_on_target_impressions``. + total_impressions (int): + Total number of ad impressions. This includes + impressions that may fall outside the specified + Targeting, due to insufficient information on + signed-in users. + + This field is a member of `oneof`_ ``_total_impressions``. + viewable_impressions (int): + Number of times the ad's impressions were + considered viewable. See + https://support.google.com/google-ads/answer/7029393 + for more information about what makes an ad + viewable and how viewability is measured. + + This field is a member of `oneof`_ ``_viewable_impressions``. + effective_frequency_breakdowns (MutableSequence[google.ads.googleads.v23.services.types.EffectiveFrequencyBreakdown]): + A list of effective frequency forecasts. The list is ordered + starting with 1+ and ending with the value set in + GenerateReachForecastRequest.effective_frequency_limit. If + no effective_frequency_limit was set, this list will be + empty. + on_target_coview_reach (int): + Number of unique people reached that exactly + matches the Targeting including co-viewers. + + This field is a member of `oneof`_ ``_on_target_coview_reach``. + total_coview_reach (int): + Number of unique people reached including + co-viewers. This includes people that may fall + outside the specified Targeting. + + This field is a member of `oneof`_ ``_total_coview_reach``. + on_target_coview_impressions (int): + Number of ad impressions that exactly matches + the Targeting including co-viewers. + + This field is a member of `oneof`_ ``_on_target_coview_impressions``. + total_coview_impressions (int): + Total number of ad impressions including + co-viewers. This includes impressions that may + fall outside the specified Targeting, due to + insufficient information on signed-in users. + + This field is a member of `oneof`_ ``_total_coview_impressions``. + conversions (float): + The number of conversions. This metric is only available for + DEMAND_GEN plannable products. + + See https://support.google.com/google-ads/answer/2375431 for + more information on conversions. + + This field is a member of `oneof`_ ``_conversions``. + trueview_views (int): + Number of ad views forecasted for the + specified product and targeting. A TrueView View + is counted when a viewer views a larger portion + or the entirety of an ad beyond an impression. + + See + https://support.google.com/google-ads/answer/2375431 + for more information on TrueView Views. + + This field is a member of `oneof`_ ``_trueview_views``. + """ + + on_target_reach: int = proto.Field( + proto.INT64, + number=5, + optional=True, + ) + total_reach: int = proto.Field( + proto.INT64, + number=6, + optional=True, + ) + on_target_impressions: int = proto.Field( + proto.INT64, + number=7, + optional=True, + ) + total_impressions: int = proto.Field( + proto.INT64, + number=8, + optional=True, + ) + viewable_impressions: int = proto.Field( + proto.INT64, + number=9, + optional=True, + ) + effective_frequency_breakdowns: MutableSequence[ + "EffectiveFrequencyBreakdown" + ] = proto.RepeatedField( + proto.MESSAGE, + number=10, + message="EffectiveFrequencyBreakdown", + ) + on_target_coview_reach: int = proto.Field( + proto.INT64, + number=11, + optional=True, + ) + total_coview_reach: int = proto.Field( + proto.INT64, + number=12, + optional=True, + ) + on_target_coview_impressions: int = proto.Field( + proto.INT64, + number=13, + optional=True, + ) + total_coview_impressions: int = proto.Field( + proto.INT64, + number=14, + optional=True, + ) + conversions: float = proto.Field( + proto.DOUBLE, + number=16, + optional=True, + ) + trueview_views: int = proto.Field( + proto.INT64, + number=17, + optional=True, + ) + + +class PlannedProductReachForecast(proto.Message): + r"""The forecasted allocation and traffic metrics for a specific + product at a point on the reach curve. + + Attributes: + plannable_product_code (str): + Selected product for planning. The product + codes returned are within the set of the ones + returned by ListPlannableProducts when using the + same location ID. + cost_micros (int): + The cost in micros. This may differ from the + product's input allocation if one or more + planned products cannot fulfill the budget + because of limited inventory. + planned_product_forecast (google.ads.googleads.v23.services.types.PlannedProductForecast): + Forecasted traffic metrics for this product. + """ + + plannable_product_code: str = proto.Field( + proto.STRING, + number=1, + ) + cost_micros: int = proto.Field( + proto.INT64, + number=2, + ) + planned_product_forecast: "PlannedProductForecast" = proto.Field( + proto.MESSAGE, + number=3, + message="PlannedProductForecast", + ) + + +class PlannedProductForecast(proto.Message): + r"""Forecasted traffic metrics for a planned product. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + on_target_reach (int): + Number of unique people reached that exactly matches the + Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the on_target_reach value will be rounded to 0. + total_reach (int): + Number of unique people reached. This includes people that + may fall outside the specified Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the total_reach value will be rounded to 0. + on_target_impressions (int): + Number of ad impressions that exactly matches + the Targeting. + total_impressions (int): + Total number of ad impressions. This includes + impressions that may fall outside the specified + Targeting, due to insufficient information on + signed-in users. + viewable_impressions (int): + Number of times the ad's impressions were + considered viewable. See + https://support.google.com/google-ads/answer/7029393 + for more information about what makes an ad + viewable and how viewability is measured. + + This field is a member of `oneof`_ ``_viewable_impressions``. + on_target_coview_reach (int): + Number of unique people reached that exactly + matches the Targeting including co-viewers. + + This field is a member of `oneof`_ ``_on_target_coview_reach``. + total_coview_reach (int): + Number of unique people reached including + co-viewers. This includes people that may fall + outside the specified Targeting. + + This field is a member of `oneof`_ ``_total_coview_reach``. + on_target_coview_impressions (int): + Number of ad impressions that exactly matches + the Targeting including co-viewers. + + This field is a member of `oneof`_ ``_on_target_coview_impressions``. + total_coview_impressions (int): + Total number of ad impressions including + co-viewers. This includes impressions that may + fall outside the specified Targeting, due to + insufficient information on signed-in users. + + This field is a member of `oneof`_ ``_total_coview_impressions``. + average_frequency (float): + The number of times per selected time unit a + user will see an ad, averaged over the number of + time units in the forecast length. This field + will only be populated for a Target Frequency + campaign. + + See + https://support.google.com/google-ads/answer/12400225 + for more information about Target Frequency + campaigns. + + This field is a member of `oneof`_ ``_average_frequency``. + conversions (float): + The number of conversions. This metric is only available for + DEMAND_GEN plannable products. + + See https://support.google.com/google-ads/answer/2375431 for + more information on conversions. + + This field is a member of `oneof`_ ``_conversions``. + trueview_views (int): + Number of ad views forecasted for the + specified product and targeting. A TrueView View + is counted when a viewer views a larger portion + or the entirety of an ad beyond an impression. + + See + https://support.google.com/google-ads/answer/2375431 + for more information on TrueView Views. + + This field is a member of `oneof`_ ``_trueview_views``. + """ + + on_target_reach: int = proto.Field( + proto.INT64, + number=1, + ) + total_reach: int = proto.Field( + proto.INT64, + number=2, + ) + on_target_impressions: int = proto.Field( + proto.INT64, + number=3, + ) + total_impressions: int = proto.Field( + proto.INT64, + number=4, + ) + viewable_impressions: int = proto.Field( + proto.INT64, + number=5, + optional=True, + ) + on_target_coview_reach: int = proto.Field( + proto.INT64, + number=6, + optional=True, + ) + total_coview_reach: int = proto.Field( + proto.INT64, + number=7, + optional=True, + ) + on_target_coview_impressions: int = proto.Field( + proto.INT64, + number=8, + optional=True, + ) + total_coview_impressions: int = proto.Field( + proto.INT64, + number=9, + optional=True, + ) + average_frequency: float = proto.Field( + proto.DOUBLE, + number=10, + optional=True, + ) + conversions: float = proto.Field( + proto.DOUBLE, + number=12, + optional=True, + ) + trueview_views: int = proto.Field( + proto.INT64, + number=13, + optional=True, + ) + + +class OnTargetAudienceMetrics(proto.Message): + r"""Audience metrics for the planned products. These metrics consider + the following targeting dimensions: + + - Location + - PlannableAgeRange + - Gender + - AudienceTargeting (only for youtube_audience_size) + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + youtube_audience_size (int): + Reference audience size matching the + considered targeting for YouTube. + + This field is a member of `oneof`_ ``_youtube_audience_size``. + census_audience_size (int): + Reference audience size matching the + considered targeting for Census. + + This field is a member of `oneof`_ ``_census_audience_size``. + """ + + youtube_audience_size: int = proto.Field( + proto.INT64, + number=3, + optional=True, + ) + census_audience_size: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + + +class EffectiveFrequencyBreakdown(proto.Message): + r"""A breakdown of the number of unique people reached at a given + effective frequency. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + effective_frequency (int): + The effective frequency [1-10]. + on_target_reach (int): + The number of unique people reached at least + effective_frequency times that exactly matches the + Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the on_target_reach value will be rounded to 0. + total_reach (int): + Total number of unique people reached at least + effective_frequency times. This includes people that may + fall outside the specified Targeting. + + Note that a minimum number of unique people must be reached + in order for data to be reported. If the minimum number is + not met, the total_reach value will be rounded to 0. + effective_coview_reach (int): + The number of users (including co-viewing users) reached for + the associated effective_frequency value. + + This field is a member of `oneof`_ ``_effective_coview_reach``. + on_target_effective_coview_reach (int): + The number of users (including co-viewing users) reached for + the associated effective_frequency value within the + specified plan demographic. + + This field is a member of `oneof`_ ``_on_target_effective_coview_reach``. + """ + + effective_frequency: int = proto.Field( + proto.INT32, + number=1, + ) + on_target_reach: int = proto.Field( + proto.INT64, + number=2, + ) + total_reach: int = proto.Field( + proto.INT64, + number=3, + ) + effective_coview_reach: int = proto.Field( + proto.INT64, + number=4, + optional=True, + ) + on_target_effective_coview_reach: int = proto.Field( + proto.INT64, + number=5, + optional=True, + ) + + +class ForecastMetricOptions(proto.Message): + r"""Controls forecast metrics to return. + + Attributes: + include_coview (bool): + Indicates whether to include co-view metrics + in the response forecast. + """ + + include_coview: bool = proto.Field( + proto.BOOL, + number=1, + ) + + +class AudienceTargeting(proto.Message): + r"""Audience targeting for reach forecast. + + Attributes: + user_interest (MutableSequence[google.ads.googleads.v23.common.types.UserInterestInfo]): + List of audiences based on user interests to + be targeted. + user_lists (MutableSequence[google.ads.googleads.v23.common.types.UserListInfo]): + List of audiences based on user lists to be + targeted. + """ + + user_interest: MutableSequence[criteria.UserInterestInfo] = ( + proto.RepeatedField( + proto.MESSAGE, + number=1, + message=criteria.UserInterestInfo, + ) + ) + user_lists: MutableSequence[criteria.UserListInfo] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=criteria.UserListInfo, + ) + + +class AdvancedProductTargeting(proto.Message): + r"""Advanced targeting settings for products. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + surface_targeting_settings (google.ads.googleads.v23.services.types.SurfaceTargeting): + Surface targeting settings for this product. + target_frequency_settings (google.ads.googleads.v23.services.types.TargetFrequencySettings): + Settings for a Target frequency campaign. Must be set when + selecting the TARGET_FREQUENCY product. + + See https://support.google.com/google-ads/answer/12400225 + for more information about Target Frequency campaigns. + youtube_select_settings (google.ads.googleads.v23.services.types.YouTubeSelectSettings): + Settings for YouTube Select targeting. + + This field is a member of `oneof`_ ``advanced_targeting``. + """ + + surface_targeting_settings: "SurfaceTargeting" = proto.Field( + proto.MESSAGE, + number=2, + message="SurfaceTargeting", + ) + target_frequency_settings: "TargetFrequencySettings" = proto.Field( + proto.MESSAGE, + number=3, + message="TargetFrequencySettings", + ) + youtube_select_settings: "YouTubeSelectSettings" = proto.Field( + proto.MESSAGE, + number=1, + oneof="advanced_targeting", + message="YouTubeSelectSettings", + ) + + +class YouTubeSelectSettings(proto.Message): + r"""Request settings for YouTube Select Lineups + + Attributes: + lineup_id (int): + Lineup for YouTube Select Targeting. + """ + + lineup_id: int = proto.Field( + proto.INT64, + number=1, + ) + + +class YouTubeSelectLineUp(proto.Message): + r"""A Plannable YouTube Select Lineup for product targeting. + + Attributes: + lineup_id (int): + The ID of the YouTube Select Lineup. + lineup_name (str): + The unique name of the YouTube Select Lineup. + """ + + lineup_id: int = proto.Field( + proto.INT64, + number=1, + ) + lineup_name: str = proto.Field( + proto.STRING, + number=2, + ) + + +class SurfaceTargetingCombinations(proto.Message): + r"""The surface targeting combinations available for an ad + product. + + Attributes: + default_targeting (google.ads.googleads.v23.services.types.SurfaceTargeting): + Default surface targeting applied to the ad + product. + available_targeting_combinations (MutableSequence[google.ads.googleads.v23.services.types.SurfaceTargeting]): + Available surface target combinations for the + ad product. + """ + + default_targeting: "SurfaceTargeting" = proto.Field( + proto.MESSAGE, + number=1, + message="SurfaceTargeting", + ) + available_targeting_combinations: MutableSequence["SurfaceTargeting"] = ( + proto.RepeatedField( + proto.MESSAGE, + number=2, + message="SurfaceTargeting", + ) + ) + + +class SurfaceTargeting(proto.Message): + r"""Container for surfaces for a product. Surfaces refer to the + available types of ad inventories such as In-Feed, In-Stream, + and Shorts. + + Attributes: + surfaces (MutableSequence[google.ads.googleads.v23.enums.types.ReachPlanSurfaceEnum.ReachPlanSurface]): + List of surfaces available to target. + """ + + surfaces: MutableSequence[ + reach_plan_surface.ReachPlanSurfaceEnum.ReachPlanSurface + ] = proto.RepeatedField( + proto.ENUM, + number=1, + enum=reach_plan_surface.ReachPlanSurfaceEnum.ReachPlanSurface, + ) + + +class TargetFrequencySettings(proto.Message): + r"""Target Frequency settings for a supported product. + + Attributes: + time_unit (google.ads.googleads.v23.enums.types.TargetFrequencyTimeUnitEnum.TargetFrequencyTimeUnit): + Required. The time unit used to describe the time frame for + target_frequency. + target_frequency (int): + Required. The target frequency goal per + selected time unit. + """ + + time_unit: ( + target_frequency_time_unit.TargetFrequencyTimeUnitEnum.TargetFrequencyTimeUnit + ) = proto.Field( + proto.ENUM, + number=1, + enum=target_frequency_time_unit.TargetFrequencyTimeUnitEnum.TargetFrequencyTimeUnit, + ) + target_frequency: int = proto.Field( + proto.INT32, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/ads/googleads/v19/services/types/recommendation_service.py b/google/ads/googleads/v23/services/types/recommendation_service.py similarity index 89% rename from google/ads/googleads/v19/services/types/recommendation_service.py rename to google/ads/googleads/v23/services/types/recommendation_service.py index d02014309..122139846 100644 --- a/google/ads/googleads/v19/services/types/recommendation_service.py +++ b/google/ads/googleads/v23/services/types/recommendation_service.py @@ -19,32 +19,32 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.common.types import extensions -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.common.types import extensions +from google.ads.googleads.v23.enums.types import ( ad_group_type as gage_ad_group_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( advertising_channel_type as gage_advertising_channel_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( bidding_strategy_type as gage_bidding_strategy_type, ) -from google.ads.googleads.v19.enums.types import conversion_tracking_status_enum -from google.ads.googleads.v19.enums.types import keyword_match_type -from google.ads.googleads.v19.enums.types import recommendation_type -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import conversion_tracking_status_enum +from google.ads.googleads.v23.enums.types import keyword_match_type +from google.ads.googleads.v23.enums.types import recommendation_type +from google.ads.googleads.v23.enums.types import ( target_impression_share_location, ) -from google.ads.googleads.v19.resources.types import ad as gagr_ad -from google.ads.googleads.v19.resources.types import asset -from google.ads.googleads.v19.resources.types import recommendation +from google.ads.googleads.v23.resources.types import ad as gagr_ad +from google.ads.googleads.v23.resources.types import asset +from google.ads.googleads.v23.resources.types import recommendation from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "ApplyRecommendationRequest", "ApplyRecommendationOperation", @@ -60,13 +60,13 @@ class ApplyRecommendationRequest(proto.Message): r"""Request message for - [RecommendationService.ApplyRecommendation][google.ads.googleads.v19.services.RecommendationService.ApplyRecommendation]. + [RecommendationService.ApplyRecommendation][google.ads.googleads.v23.services.RecommendationService.ApplyRecommendation]. Attributes: customer_id (str): Required. The ID of the customer with the recommendation. - operations (MutableSequence[google.ads.googleads.v19.services.types.ApplyRecommendationOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.ApplyRecommendationOperation]): Required. The list of operations to apply recommendations. If partial_failure=false all recommendations should be of the same type There is a limit of 100 operations per @@ -111,72 +111,72 @@ class ApplyRecommendationOperation(proto.Message): resource_name (str): The resource name of the recommendation to apply. - campaign_budget (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.CampaignBudgetParameters): + campaign_budget (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.CampaignBudgetParameters): Optional parameters to use when applying a campaign budget recommendation. This field is a member of `oneof`_ ``apply_parameters``. - text_ad (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.TextAdParameters): + text_ad (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.TextAdParameters): Optional parameters to use when applying a text ad recommendation. This field is a member of `oneof`_ ``apply_parameters``. - keyword (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.KeywordParameters): + keyword (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.KeywordParameters): Optional parameters to use when applying keyword recommendation. This field is a member of `oneof`_ ``apply_parameters``. - target_cpa_opt_in (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.TargetCpaOptInParameters): + target_cpa_opt_in (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.TargetCpaOptInParameters): Optional parameters to use when applying target CPA opt-in recommendation. This field is a member of `oneof`_ ``apply_parameters``. - target_roas_opt_in (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.TargetRoasOptInParameters): + target_roas_opt_in (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.TargetRoasOptInParameters): Optional parameters to use when applying target ROAS opt-in recommendation. This field is a member of `oneof`_ ``apply_parameters``. - callout_extension (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.CalloutExtensionParameters): + callout_extension (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.CalloutExtensionParameters): Parameters to use when applying callout extension recommendation. This field is a member of `oneof`_ ``apply_parameters``. - call_extension (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.CallExtensionParameters): + call_extension (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.CallExtensionParameters): Parameters to use when applying call extension recommendation. This field is a member of `oneof`_ ``apply_parameters``. - sitelink_extension (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.SitelinkExtensionParameters): + sitelink_extension (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.SitelinkExtensionParameters): Parameters to use when applying sitelink recommendation. This field is a member of `oneof`_ ``apply_parameters``. - move_unused_budget (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.MoveUnusedBudgetParameters): + move_unused_budget (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.MoveUnusedBudgetParameters): Parameters to use when applying move unused budget recommendation. This field is a member of `oneof`_ ``apply_parameters``. - responsive_search_ad (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.ResponsiveSearchAdParameters): + responsive_search_ad (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.ResponsiveSearchAdParameters): Parameters to use when applying a responsive search ad recommendation. This field is a member of `oneof`_ ``apply_parameters``. - use_broad_match_keyword (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.UseBroadMatchKeywordParameters): + use_broad_match_keyword (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.UseBroadMatchKeywordParameters): Parameters to use when applying a use broad match keyword recommendation. This field is a member of `oneof`_ ``apply_parameters``. - responsive_search_ad_asset (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.ResponsiveSearchAdAssetParameters): + responsive_search_ad_asset (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.ResponsiveSearchAdAssetParameters): Parameters to use when applying a responsive search ad asset recommendation. This field is a member of `oneof`_ ``apply_parameters``. - responsive_search_ad_improve_ad_strength (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.ResponsiveSearchAdImproveAdStrengthParameters): + responsive_search_ad_improve_ad_strength (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.ResponsiveSearchAdImproveAdStrengthParameters): Parameters to use when applying a responsive search ad improve ad strength recommendation. This field is a member of `oneof`_ ``apply_parameters``. - raise_target_cpa_bid_too_low (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.RaiseTargetCpaBidTooLowParameters): + raise_target_cpa_bid_too_low (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.RaiseTargetCpaBidTooLowParameters): Parameters to use when applying a raise target CPA bid too low recommendation. The apply is asynchronous and can take minutes depending @@ -184,52 +184,52 @@ class ApplyRecommendationOperation(proto.Message): related campaign. This field is a member of `oneof`_ ``apply_parameters``. - forecasting_set_target_roas (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.ForecastingSetTargetRoasParameters): + forecasting_set_target_roas (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.ForecastingSetTargetRoasParameters): Parameters to use when applying a forecasting set target ROAS recommendation. This field is a member of `oneof`_ ``apply_parameters``. - callout_asset (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.CalloutAssetParameters): + callout_asset (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.CalloutAssetParameters): Parameters to use when applying callout asset recommendation. This field is a member of `oneof`_ ``apply_parameters``. - call_asset (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.CallAssetParameters): + call_asset (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.CallAssetParameters): Parameters to use when applying call asset recommendation. This field is a member of `oneof`_ ``apply_parameters``. - sitelink_asset (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.SitelinkAssetParameters): + sitelink_asset (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.SitelinkAssetParameters): Parameters to use when applying sitelink asset recommendation. This field is a member of `oneof`_ ``apply_parameters``. - raise_target_cpa (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.RaiseTargetCpaParameters): + raise_target_cpa (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.RaiseTargetCpaParameters): Parameters to use when applying raise Target CPA recommendation. This field is a member of `oneof`_ ``apply_parameters``. - lower_target_roas (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.LowerTargetRoasParameters): + lower_target_roas (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.LowerTargetRoasParameters): Parameters to use when applying lower Target ROAS recommendation. This field is a member of `oneof`_ ``apply_parameters``. - forecasting_set_target_cpa (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.ForecastingSetTargetCpaParameters): + forecasting_set_target_cpa (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.ForecastingSetTargetCpaParameters): Parameters to use when applying forecasting set target CPA recommendation. This field is a member of `oneof`_ ``apply_parameters``. - set_target_cpa (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.ForecastingSetTargetCpaParameters): + set_target_cpa (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.ForecastingSetTargetCpaParameters): Parameters to use when applying set target CPA recommendation. This field is a member of `oneof`_ ``apply_parameters``. - set_target_roas (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.ForecastingSetTargetRoasParameters): + set_target_roas (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.ForecastingSetTargetRoasParameters): Parameters to use when applying set target ROAS recommendation. This field is a member of `oneof`_ ``apply_parameters``. - lead_form_asset (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.LeadFormAssetParameters): + lead_form_asset (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.LeadFormAssetParameters): Parameters to use when applying lead form asset recommendation. @@ -293,7 +293,7 @@ class TextAdParameters(proto.Message): r"""Parameters to use when applying a text ad recommendation. Attributes: - ad (google.ads.googleads.v19.resources.types.Ad): + ad (google.ads.googleads.v23.resources.types.Ad): New ad to add to recommended ad group. All necessary fields need to be set in this message. This is a required field. @@ -316,7 +316,7 @@ class KeywordParameters(proto.Message): is a required field. This field is a member of `oneof`_ ``_ad_group``. - match_type (google.ads.googleads.v19.enums.types.KeywordMatchTypeEnum.KeywordMatchType): + match_type (google.ads.googleads.v23.enums.types.KeywordMatchTypeEnum.KeywordMatchType): The match type of the keyword. This is a required field. cpc_bid_micros (int): @@ -412,7 +412,7 @@ class CalloutExtensionParameters(proto.Message): recommendation. Attributes: - callout_extensions (MutableSequence[google.ads.googleads.v19.common.types.CalloutFeedItem]): + callout_extensions (MutableSequence[google.ads.googleads.v23.common.types.CalloutFeedItem]): Callout extensions to be added. This is a required field. """ @@ -430,7 +430,7 @@ class CallExtensionParameters(proto.Message): recommendation. Attributes: - call_extensions (MutableSequence[google.ads.googleads.v19.common.types.CallFeedItem]): + call_extensions (MutableSequence[google.ads.googleads.v23.common.types.CallFeedItem]): Call extensions to be added. This is a required field. """ @@ -447,7 +447,7 @@ class SitelinkExtensionParameters(proto.Message): r"""Parameters to use when applying sitelink recommendation. Attributes: - sitelink_extensions (MutableSequence[google.ads.googleads.v19.common.types.SitelinkFeedItem]): + sitelink_extensions (MutableSequence[google.ads.googleads.v23.common.types.SitelinkFeedItem]): Sitelinks to be added. This is a required field. """ @@ -465,7 +465,7 @@ class CalloutAssetParameters(proto.Message): recommendations. Attributes: - ad_asset_apply_parameters (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.AdAssetApplyParameters): + ad_asset_apply_parameters (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.AdAssetApplyParameters): Required. Callout assets to be added. This is a required field. """ @@ -482,7 +482,7 @@ class CallAssetParameters(proto.Message): r"""Parameters to use when applying call asset recommendations. Attributes: - ad_asset_apply_parameters (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.AdAssetApplyParameters): + ad_asset_apply_parameters (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.AdAssetApplyParameters): Required. Call assets to be added. This is a required field. """ @@ -500,7 +500,7 @@ class SitelinkAssetParameters(proto.Message): recommendations. Attributes: - ad_asset_apply_parameters (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.AdAssetApplyParameters): + ad_asset_apply_parameters (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.AdAssetApplyParameters): Required. Sitelink assets to be added. This is a required field. """ @@ -548,13 +548,13 @@ class AdAssetApplyParameters(proto.Message): recommendations. Attributes: - new_assets (MutableSequence[google.ads.googleads.v19.resources.types.Asset]): + new_assets (MutableSequence[google.ads.googleads.v23.resources.types.Asset]): The assets to create and attach to a scope. This may be combined with existing_assets in the same call. existing_assets (MutableSequence[str]): The resource names of existing assets to attach to a scope. This may be combined with new_assets in the same call. - scope (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.AdAssetApplyParameters.ApplyScope): + scope (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.AdAssetApplyParameters.ApplyScope): Required. The scope at which to apply the assets. Assets at the campaign scope level will be applied to the campaign associated with the @@ -626,7 +626,7 @@ class ResponsiveSearchAdAssetParameters(proto.Message): recommendation. Attributes: - updated_ad (google.ads.googleads.v19.resources.types.Ad): + updated_ad (google.ads.googleads.v23.resources.types.Ad): Updated ad. The current ad's content will be replaced. """ @@ -642,7 +642,7 @@ class ResponsiveSearchAdImproveAdStrengthParameters(proto.Message): improve ad strength recommendation. Attributes: - updated_ad (google.ads.googleads.v19.resources.types.Ad): + updated_ad (google.ads.googleads.v23.resources.types.Ad): Updated ad. The current ad's content will be replaced. """ @@ -658,7 +658,7 @@ class ResponsiveSearchAdParameters(proto.Message): recommendation. Attributes: - ad (google.ads.googleads.v19.resources.types.Ad): + ad (google.ads.googleads.v23.resources.types.Ad): Required. New ad to add to recommended ad group. """ @@ -747,7 +747,7 @@ class LeadFormAssetParameters(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - ad_asset_apply_parameters (google.ads.googleads.v19.services.types.ApplyRecommendationOperation.AdAssetApplyParameters): + ad_asset_apply_parameters (google.ads.googleads.v23.services.types.ApplyRecommendationOperation.AdAssetApplyParameters): Required. Lead form assets to be added. This is a required field. set_submit_lead_form_asset_campaign_goal (bool): @@ -932,10 +932,10 @@ class LeadFormAssetParameters(proto.Message): class ApplyRecommendationResponse(proto.Message): r"""Response message for - [RecommendationService.ApplyRecommendation][google.ads.googleads.v19.services.RecommendationService.ApplyRecommendation]. + [RecommendationService.ApplyRecommendation][google.ads.googleads.v23.services.RecommendationService.ApplyRecommendation]. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.ApplyRecommendationResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.ApplyRecommendationResult]): Results of operations to apply recommendations. partial_failure_error (google.rpc.status_pb2.Status): @@ -974,13 +974,13 @@ class ApplyRecommendationResult(proto.Message): class DismissRecommendationRequest(proto.Message): r"""Request message for - [RecommendationService.DismissRecommendation][google.ads.googleads.v19.services.RecommendationService.DismissRecommendation]. + [RecommendationService.DismissRecommendation][google.ads.googleads.v23.services.RecommendationService.DismissRecommendation]. Attributes: customer_id (str): Required. The ID of the customer with the recommendation. - operations (MutableSequence[google.ads.googleads.v19.services.types.DismissRecommendationRequest.DismissRecommendationOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.DismissRecommendationRequest.DismissRecommendationOperation]): Required. The list of operations to dismiss recommendations. If partial_failure=false all recommendations should be of the same type There is a limit of 100 operations per @@ -1027,10 +1027,10 @@ class DismissRecommendationOperation(proto.Message): class DismissRecommendationResponse(proto.Message): r"""Response message for - [RecommendationService.DismissRecommendation][google.ads.googleads.v19.services.RecommendationService.DismissRecommendation]. + [RecommendationService.DismissRecommendation][google.ads.googleads.v23.services.RecommendationService.DismissRecommendation]. Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.DismissRecommendationResponse.DismissRecommendationResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.DismissRecommendationResponse.DismissRecommendationResult]): Results of operations to dismiss recommendations. partial_failure_error (google.rpc.status_pb2.Status): @@ -1068,7 +1068,7 @@ class DismissRecommendationResult(proto.Message): class GenerateRecommendationsRequest(proto.Message): r"""Request message for - [RecommendationService.GenerateRecommendations][google.ads.googleads.v19.services.RecommendationService.GenerateRecommendations]. + [RecommendationService.GenerateRecommendations][google.ads.googleads.v23.services.RecommendationService.GenerateRecommendations]. .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -1077,7 +1077,7 @@ class GenerateRecommendationsRequest(proto.Message): customer_id (str): Required. The ID of the customer generating recommendations. - recommendation_types (MutableSequence[google.ads.googleads.v19.enums.types.RecommendationTypeEnum.RecommendationType]): + recommendation_types (MutableSequence[google.ads.googleads.v23.enums.types.RecommendationTypeEnum.RecommendationType]): Required. List of eligible recommendation_types to generate. If the uploaded criteria isn't sufficient to make a recommendation, or the campaign is already in the @@ -1092,7 +1092,7 @@ class GenerateRecommendationsRequest(proto.Message): MAXIMIZE_CONVERSION_VALUE_OPT_IN, SET_TARGET_CPA, SET_TARGET_ROAS, SITELINK_ASSET, TARGET_CPA_OPT_IN, TARGET_ROAS_OPT_IN - advertising_channel_type (google.ads.googleads.v19.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): + advertising_channel_type (google.ads.googleads.v23.enums.types.AdvertisingChannelTypeEnum.AdvertisingChannelType): Required. Advertising channel type of the campaign. The following advertising_channel_types are supported for recommendation generation: PERFORMANCE_MAX and SEARCH @@ -1102,7 +1102,7 @@ class GenerateRecommendationsRequest(proto.Message): SITELINK_ASSET This field is a member of `oneof`_ ``_campaign_sitelink_count``. - conversion_tracking_status (google.ads.googleads.v19.enums.types.ConversionTrackingStatusEnum.ConversionTrackingStatus): + conversion_tracking_status (google.ads.googleads.v23.enums.types.ConversionTrackingStatusEnum.ConversionTrackingStatus): Optional. Current conversion tracking status. This field is necessary for the following recommendation_types: MAXIMIZE_CLICKS_OPT_IN, MAXIMIZE_CONVERSIONS_OPT_IN, @@ -1110,7 +1110,7 @@ class GenerateRecommendationsRequest(proto.Message): SET_TARGET_ROAS, TARGET_CPA_OPT_IN, TARGET_ROAS_OPT_IN This field is a member of `oneof`_ ``_conversion_tracking_status``. - bidding_info (google.ads.googleads.v19.services.types.GenerateRecommendationsRequest.BiddingInfo): + bidding_info (google.ads.googleads.v23.services.types.GenerateRecommendationsRequest.BiddingInfo): Optional. Current bidding information of the campaign. This field is necessary for the following recommendation_types: CAMPAIGN_BUDGET, MAXIMIZE_CLICKS_OPT_IN, @@ -1119,18 +1119,18 @@ class GenerateRecommendationsRequest(proto.Message): SET_TARGET_ROAS, TARGET_CPA_OPT_IN, TARGET_ROAS_OPT_IN This field is a member of `oneof`_ ``_bidding_info``. - ad_group_info (MutableSequence[google.ads.googleads.v19.services.types.GenerateRecommendationsRequest.AdGroupInfo]): + ad_group_info (MutableSequence[google.ads.googleads.v23.services.types.GenerateRecommendationsRequest.AdGroupInfo]): Optional. Current AdGroup Information. Supports information from a single AdGroup. This field is optional for the following recommendation_types: KEYWORD This field is required for the following recommendation_types: CAMPAIGN_BUDGET if AdvertisingChannelType is SEARCH - seed_info (google.ads.googleads.v19.services.types.GenerateRecommendationsRequest.SeedInfo): + seed_info (google.ads.googleads.v23.services.types.GenerateRecommendationsRequest.SeedInfo): Optional. Seed information for Keywords. This field is necessary for the following recommendation_types: KEYWORD This field is a member of `oneof`_ ``_seed_info``. - budget_info (google.ads.googleads.v19.services.types.GenerateRecommendationsRequest.BudgetInfo): + budget_info (google.ads.googleads.v23.services.types.GenerateRecommendationsRequest.BudgetInfo): Optional. Current budget information. This field is optional for the following recommendation_types: CAMPAIGN_BUDGET @@ -1165,7 +1165,7 @@ class GenerateRecommendationsRequest(proto.Message): this field OR positive_location_ids is required for the following recommendation_types: CAMPAIGN_BUDGET if AdvertisingChannelType is SEARCH - asset_group_info (MutableSequence[google.ads.googleads.v19.services.types.GenerateRecommendationsRequest.AssetGroupInfo]): + asset_group_info (MutableSequence[google.ads.googleads.v23.services.types.GenerateRecommendationsRequest.AssetGroupInfo]): Optional. Current AssetGroup Information. This field is required for the following recommendation_types: CAMPAIGN_BUDGET @@ -1182,6 +1182,30 @@ class GenerateRecommendationsRequest(proto.Message): CAMPAIGN_BUDGET This field is a member of `oneof`_ ``_target_content_network``. + merchant_center_account_id (int): + Optional. Merchant Center account ID. This field should only + be set when advertising_channel_type is PERFORMANCE_MAX. + Setting this field causes RecommendationService to generate + recommendations for Performance Max for retail instead of + standard Performance Max. This field is optional for the + following recommendation_types: CAMPAIGN_BUDGET + + This field is a member of `oneof`_ ``_merchant_center_account_id``. + is_new_customer (bool): + Optional. Whether or not this customer should be treated as + a "new" customer (that is, a customer who has not yet + created a campaign). + + Setting this to ``true`` will cause the backend to generate + recommendations using a dedicated recommendation model for + onboarding new customers, as opposed to the default model + for existing customers. This is only recommended for + customers with 0 campaigns. + + This field is optional for the following + recommendation_types: CAMPAIGN_BUDGET + + This field is a member of `oneof`_ ``_is_new_customer``. """ class BiddingInfo(proto.Message): @@ -1196,7 +1220,7 @@ class BiddingInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - bidding_strategy_type (google.ads.googleads.v19.enums.types.BiddingStrategyTypeEnum.BiddingStrategyType): + bidding_strategy_type (google.ads.googleads.v23.enums.types.BiddingStrategyTypeEnum.BiddingStrategyType): Current bidding strategy. This field is necessary for the following recommendation_types: CAMPAIGN_BUDGET, MAXIMIZE_CLICKS_OPT_IN, MAXIMIZE_CONVERSIONS_OPT_IN, @@ -1216,7 +1240,7 @@ class BiddingInfo(proto.Message): MAXIMIZE_CONVERSION_VALUE. This field is a member of `oneof`_ ``bidding_strategy_target_info``. - target_impression_share_info (google.ads.googleads.v19.services.types.GenerateRecommendationsRequest.TargetImpressionShareInfo): + target_impression_share_info (google.ads.googleads.v23.services.types.GenerateRecommendationsRequest.TargetImpressionShareInfo): Optional. Current Target Impression Share information of the campaign. This field is necessary for the following recommendation_types: CAMPAIGN_BUDGET @@ -1257,13 +1281,13 @@ class AdGroupInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - ad_group_type (google.ads.googleads.v19.enums.types.AdGroupTypeEnum.AdGroupType): + ad_group_type (google.ads.googleads.v23.enums.types.AdGroupTypeEnum.AdGroupType): Optional. AdGroup Type of the AdGroup. This field is necessary for the following recommendation_types if ad_group_info is set: KEYWORD This field is a member of `oneof`_ ``_ad_group_type``. - keywords (MutableSequence[google.ads.googleads.v19.common.types.KeywordInfo]): + keywords (MutableSequence[google.ads.googleads.v23.common.types.KeywordInfo]): Optional. Current keywords. This field is optional for the following recommendation_types if ad_group_info is set: KEYWORD This field is required for the following @@ -1374,7 +1398,7 @@ class TargetImpressionShareInfo(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - location (google.ads.googleads.v19.enums.types.TargetImpressionShareLocationEnum.TargetImpressionShareLocation): + location (google.ads.googleads.v23.enums.types.TargetImpressionShareLocationEnum.TargetImpressionShareLocation): Required. The targeted location on the search results page. This is required for campaigns where the AdvertisingChannelType is SEARCH and the bidding strategy @@ -1512,14 +1536,24 @@ class TargetImpressionShareInfo(proto.Message): number=19, optional=True, ) + merchant_center_account_id: int = proto.Field( + proto.INT64, + number=20, + optional=True, + ) + is_new_customer: bool = proto.Field( + proto.BOOL, + number=21, + optional=True, + ) class GenerateRecommendationsResponse(proto.Message): r"""Response message for - [RecommendationService.GenerateRecommendations][google.ads.googleads.v19.services.RecommendationService.GenerateRecommendations]. + [RecommendationService.GenerateRecommendations][google.ads.googleads.v23.services.RecommendationService.GenerateRecommendations]. Attributes: - recommendations (MutableSequence[google.ads.googleads.v19.resources.types.Recommendation]): + recommendations (MutableSequence[google.ads.googleads.v23.resources.types.Recommendation]): List of generated recommendations from the passed in set of requested recommendation_types. If there isn't sufficient data to generate a recommendation for the requested diff --git a/google/ads/googleads/v19/services/types/recommendation_subscription_service.py b/google/ads/googleads/v23/services/types/recommendation_subscription_service.py similarity index 87% rename from google/ads/googleads/v19/services/types/recommendation_subscription_service.py rename to google/ads/googleads/v23/services/types/recommendation_subscription_service.py index d3f6cd32a..414d454fb 100644 --- a/google/ads/googleads/v19/services/types/recommendation_subscription_service.py +++ b/google/ads/googleads/v23/services/types/recommendation_subscription_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( recommendation_subscription as gagr_recommendation_subscription, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateRecommendationSubscriptionRequest", "RecommendationSubscriptionOperation", @@ -43,12 +43,12 @@ class MutateRecommendationSubscriptionRequest(proto.Message): r"""Request message for - [RecommendationSubscriptionService.MutateRecommendationSubscription] + [RecommendationSubscriptionService.MutateRecommendationSubscription][google.ads.googleads.v23.services.RecommendationSubscriptionService.MutateRecommendationSubscription] Attributes: customer_id (str): Required. The ID of the subscribing customer. - operations (MutableSequence[google.ads.googleads.v19.services.types.RecommendationSubscriptionOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.RecommendationSubscriptionOperation]): Required. The list of create or update operations. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateRecommendationSubscriptionRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -100,7 +100,7 @@ class MutateRecommendationSubscriptionRequest(proto.Message): class RecommendationSubscriptionOperation(proto.Message): r"""A single operation (create, update) on a recommendation subscription. - [RecommendationSubscriptionService.MutateRecommendationSubscription] + [RecommendationSubscriptionService.MutateRecommendationSubscription][google.ads.googleads.v23.services.RecommendationSubscriptionService.MutateRecommendationSubscription] This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -113,12 +113,12 @@ class RecommendationSubscriptionOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): Optional. FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.RecommendationSubscription): + create (google.ads.googleads.v23.resources.types.RecommendationSubscription): Create operation: No resource name is expected for the new subscription. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.RecommendationSubscription): + update (google.ads.googleads.v23.resources.types.RecommendationSubscription): Update operation: The subscription is expected to have a valid resource name. @@ -150,10 +150,10 @@ class RecommendationSubscriptionOperation(proto.Message): class MutateRecommendationSubscriptionResponse(proto.Message): r"""Response message for - [RecommendationSubscriptionService.MutateRecommendationSubscription] + [RecommendationSubscriptionService.MutateRecommendationSubscription][google.ads.googleads.v23.services.RecommendationSubscriptionService.MutateRecommendationSubscription] Attributes: - results (MutableSequence[google.ads.googleads.v19.services.types.MutateRecommendationSubscriptionResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateRecommendationSubscriptionResult]): Results, one per operation. partial_failure_error (google.rpc.status_pb2.Status): Errors that pertain to operation failures in the partial @@ -179,13 +179,13 @@ class MutateRecommendationSubscriptionResponse(proto.Message): class MutateRecommendationSubscriptionResult(proto.Message): r"""Result message for - [RecommendationSubscriptionService.MutateRecommendationSubscription] + [RecommendationSubscriptionService.MutateRecommendationSubscription][google.ads.googleads.v23.services.RecommendationSubscriptionService.MutateRecommendationSubscription] Attributes: resource_name (str): Resource name of the subscription that was modified. - recommendation_subscription (google.ads.googleads.v19.resources.types.RecommendationSubscription): + recommendation_subscription (google.ads.googleads.v23.resources.types.RecommendationSubscription): The mutated recommendation subscription with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/remarketing_action_service.py b/google/ads/googleads/v23/services/types/remarketing_action_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/remarketing_action_service.py rename to google/ads/googleads/v23/services/types/remarketing_action_service.py index c29f090fe..16362d99a 100644 --- a/google/ads/googleads/v19/services/types/remarketing_action_service.py +++ b/google/ads/googleads/v23/services/types/remarketing_action_service.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import remarketing_action +from google.ads.googleads.v23.resources.types import remarketing_action from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateRemarketingActionsRequest", "RemarketingActionOperation", @@ -38,13 +38,13 @@ class MutateRemarketingActionsRequest(proto.Message): r"""Request message for - [RemarketingActionService.MutateRemarketingActions][google.ads.googleads.v19.services.RemarketingActionService.MutateRemarketingActions]. + [RemarketingActionService.MutateRemarketingActions][google.ads.googleads.v23.services.RemarketingActionService.MutateRemarketingActions]. Attributes: customer_id (str): Required. The ID of the customer whose remarketing actions are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.RemarketingActionOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.RemarketingActionOperation]): Required. The list of operations to perform on individual remarketing actions. partial_failure (bool): @@ -93,12 +93,12 @@ class RemarketingActionOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.RemarketingAction): + create (google.ads.googleads.v23.resources.types.RemarketingAction): Create operation: No resource name is expected for the new remarketing action. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.RemarketingAction): + update (google.ads.googleads.v23.resources.types.RemarketingAction): Update operation: The remarketing action is expected to have a valid resource name. @@ -134,7 +134,7 @@ class MutateRemarketingActionsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateRemarketingActionResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateRemarketingActionResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/shareable_preview_service.py b/google/ads/googleads/v23/services/types/shareable_preview_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/shareable_preview_service.py rename to google/ads/googleads/v23/services/types/shareable_preview_service.py index b055210be..4dff2814c 100644 --- a/google/ads/googleads/v19/services/types/shareable_preview_service.py +++ b/google/ads/googleads/v23/services/types/shareable_preview_service.py @@ -23,8 +23,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "GenerateShareablePreviewsRequest", "ShareablePreview", @@ -38,13 +38,13 @@ class GenerateShareablePreviewsRequest(proto.Message): r"""Request message for - [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v19.services.ShareablePreviewService.GenerateShareablePreviews]. + [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v23.services.ShareablePreviewService.GenerateShareablePreviews]. Attributes: customer_id (str): Required. The customer creating the shareable previews request. - shareable_previews (MutableSequence[google.ads.googleads.v19.services.types.ShareablePreview]): + shareable_previews (MutableSequence[google.ads.googleads.v23.services.types.ShareablePreview]): Required. The list of shareable previews to generate. """ @@ -66,7 +66,7 @@ class ShareablePreview(proto.Message): r"""A shareable preview with its identifier. Attributes: - asset_group_identifier (google.ads.googleads.v19.services.types.AssetGroupIdentifier): + asset_group_identifier (google.ads.googleads.v23.services.types.AssetGroupIdentifier): Required. Asset group of the shareable preview. """ @@ -94,10 +94,10 @@ class AssetGroupIdentifier(proto.Message): class GenerateShareablePreviewsResponse(proto.Message): r"""Response message for - [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v19.services.ShareablePreviewService.GenerateShareablePreviews]. + [ShareablePreviewService.GenerateShareablePreviews][google.ads.googleads.v23.services.ShareablePreviewService.GenerateShareablePreviews]. Attributes: - responses (MutableSequence[google.ads.googleads.v19.services.types.ShareablePreviewOrError]): + responses (MutableSequence[google.ads.googleads.v23.services.types.ShareablePreviewOrError]): List of generate shareable preview results. """ @@ -119,9 +119,9 @@ class ShareablePreviewOrError(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - asset_group_identifier (google.ads.googleads.v19.services.types.AssetGroupIdentifier): + asset_group_identifier (google.ads.googleads.v23.services.types.AssetGroupIdentifier): The asset group of the shareable preview. - shareable_preview_result (google.ads.googleads.v19.services.types.ShareablePreviewResult): + shareable_preview_result (google.ads.googleads.v23.services.types.ShareablePreviewResult): The shareable preview result. This field is a member of `oneof`_ ``generate_shareable_preview_response``. diff --git a/google/ads/googleads/v19/services/types/shared_criterion_service.py b/google/ads/googleads/v23/services/types/shared_criterion_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/shared_criterion_service.py rename to google/ads/googleads/v23/services/types/shared_criterion_service.py index dc1bd9734..532bb36e8 100644 --- a/google/ads/googleads/v19/services/types/shared_criterion_service.py +++ b/google/ads/googleads/v23/services/types/shared_criterion_service.py @@ -19,18 +19,18 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( shared_criterion as gagr_shared_criterion, ) from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateSharedCriteriaRequest", "SharedCriterionOperation", @@ -42,13 +42,13 @@ class MutateSharedCriteriaRequest(proto.Message): r"""Request message for - [SharedCriterionService.MutateSharedCriteria][google.ads.googleads.v19.services.SharedCriterionService.MutateSharedCriteria]. + [SharedCriterionService.MutateSharedCriteria][google.ads.googleads.v23.services.SharedCriterionService.MutateSharedCriteria]. Attributes: customer_id (str): Required. The ID of the customer whose shared criteria are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.SharedCriterionOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.SharedCriterionOperation]): Required. The list of operations to perform on individual shared criteria. partial_failure (bool): @@ -60,7 +60,7 @@ class MutateSharedCriteriaRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -105,7 +105,7 @@ class SharedCriterionOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.SharedCriterion): + create (google.ads.googleads.v23.resources.types.SharedCriterion): Create operation: No resource name is expected for the new shared criterion. @@ -142,7 +142,7 @@ class MutateSharedCriteriaResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateSharedCriterionResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateSharedCriterionResult]): All results for the mutate. """ @@ -166,7 +166,7 @@ class MutateSharedCriterionResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - shared_criterion (google.ads.googleads.v19.resources.types.SharedCriterion): + shared_criterion (google.ads.googleads.v23.resources.types.SharedCriterion): The mutated shared criterion with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/shared_set_service.py b/google/ads/googleads/v23/services/types/shared_set_service.py similarity index 90% rename from google/ads/googleads/v19/services/types/shared_set_service.py rename to google/ads/googleads/v23/services/types/shared_set_service.py index eb8bf717b..fe102cecd 100644 --- a/google/ads/googleads/v19/services/types/shared_set_service.py +++ b/google/ads/googleads/v23/services/types/shared_set_service.py @@ -19,10 +19,10 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( shared_set as gagr_shared_set, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -30,8 +30,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateSharedSetsRequest", "SharedSetOperation", @@ -43,13 +43,13 @@ class MutateSharedSetsRequest(proto.Message): r"""Request message for - [SharedSetService.MutateSharedSets][google.ads.googleads.v19.services.SharedSetService.MutateSharedSets]. + [SharedSetService.MutateSharedSets][google.ads.googleads.v23.services.SharedSetService.MutateSharedSets]. Attributes: customer_id (str): Required. The ID of the customer whose shared sets are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.SharedSetOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.SharedSetOperation]): Required. The list of operations to perform on individual shared sets. partial_failure (bool): @@ -61,7 +61,7 @@ class MutateSharedSetsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -107,12 +107,12 @@ class SharedSetOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.SharedSet): + create (google.ads.googleads.v23.resources.types.SharedSet): Create operation: No resource name is expected for the new shared set. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.SharedSet): + update (google.ads.googleads.v23.resources.types.SharedSet): Update operation: The shared set is expected to have a valid resource name. @@ -160,7 +160,7 @@ class MutateSharedSetsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateSharedSetResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateSharedSetResult]): All results for the mutate. """ @@ -182,7 +182,7 @@ class MutateSharedSetResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - shared_set (google.ads.googleads.v19.resources.types.SharedSet): + shared_set (google.ads.googleads.v23.resources.types.SharedSet): The mutated shared set with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/smart_campaign_setting_service.py b/google/ads/googleads/v23/services/types/smart_campaign_setting_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/smart_campaign_setting_service.py rename to google/ads/googleads/v23/services/types/smart_campaign_setting_service.py index b4e2cb325..f4a702318 100644 --- a/google/ads/googleads/v19/services/types/smart_campaign_setting_service.py +++ b/google/ads/googleads/v23/services/types/smart_campaign_setting_service.py @@ -19,16 +19,16 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( response_content_type as gage_response_content_type, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( smart_campaign_not_eligible_reason, ) -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( smart_campaign_status as gage_smart_campaign_status, ) -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.resources.types import ( smart_campaign_setting as gagr_smart_campaign_setting, ) from google.protobuf import field_mask_pb2 # type: ignore @@ -36,8 +36,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "GetSmartCampaignStatusRequest", "SmartCampaignNotEligibleDetails", @@ -56,7 +56,7 @@ class GetSmartCampaignStatusRequest(proto.Message): r"""Request message for - [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v19.services.SmartCampaignSettingService.GetSmartCampaignStatus]. + [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v23.services.SmartCampaignSettingService.GetSmartCampaignStatus]. Attributes: resource_name (str): @@ -79,7 +79,7 @@ class SmartCampaignNotEligibleDetails(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - not_eligible_reason (google.ads.googleads.v19.enums.types.SmartCampaignNotEligibleReasonEnum.SmartCampaignNotEligibleReason): + not_eligible_reason (google.ads.googleads.v23.enums.types.SmartCampaignNotEligibleReasonEnum.SmartCampaignNotEligibleReason): The reason why the Smart campaign is not eligible to serve. @@ -197,7 +197,7 @@ class SmartCampaignEndedDetails(proto.Message): class GetSmartCampaignStatusResponse(proto.Message): r"""Response message for - [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v19.services.SmartCampaignSettingService.GetSmartCampaignStatus]. + [SmartCampaignSettingService.GetSmartCampaignStatus][google.ads.googleads.v23.services.SmartCampaignSettingService.GetSmartCampaignStatus]. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -207,27 +207,27 @@ class GetSmartCampaignStatusResponse(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - smart_campaign_status (google.ads.googleads.v19.enums.types.SmartCampaignStatusEnum.SmartCampaignStatus): + smart_campaign_status (google.ads.googleads.v23.enums.types.SmartCampaignStatusEnum.SmartCampaignStatus): The status of this Smart campaign. - not_eligible_details (google.ads.googleads.v19.services.types.SmartCampaignNotEligibleDetails): + not_eligible_details (google.ads.googleads.v23.services.types.SmartCampaignNotEligibleDetails): Details related to Smart campaigns that are ineligible to serve. This field is a member of `oneof`_ ``smart_campaign_status_details``. - eligible_details (google.ads.googleads.v19.services.types.SmartCampaignEligibleDetails): + eligible_details (google.ads.googleads.v23.services.types.SmartCampaignEligibleDetails): Details related to Smart campaigns that are eligible to serve. This field is a member of `oneof`_ ``smart_campaign_status_details``. - paused_details (google.ads.googleads.v19.services.types.SmartCampaignPausedDetails): + paused_details (google.ads.googleads.v23.services.types.SmartCampaignPausedDetails): Details related to paused Smart campaigns. This field is a member of `oneof`_ ``smart_campaign_status_details``. - removed_details (google.ads.googleads.v19.services.types.SmartCampaignRemovedDetails): + removed_details (google.ads.googleads.v23.services.types.SmartCampaignRemovedDetails): Details related to removed Smart campaigns. This field is a member of `oneof`_ ``smart_campaign_status_details``. - ended_details (google.ads.googleads.v19.services.types.SmartCampaignEndedDetails): + ended_details (google.ads.googleads.v23.services.types.SmartCampaignEndedDetails): Details related to Smart campaigns that have ended. @@ -275,13 +275,13 @@ class GetSmartCampaignStatusResponse(proto.Message): class MutateSmartCampaignSettingsRequest(proto.Message): r"""Request message for - [SmartCampaignSettingService.MutateSmartCampaignSettings][google.ads.googleads.v19.services.SmartCampaignSettingService.MutateSmartCampaignSettings]. + [SmartCampaignSettingService.MutateSmartCampaignSettings][google.ads.googleads.v23.services.SmartCampaignSettingService.MutateSmartCampaignSettings]. Attributes: customer_id (str): Required. The ID of the customer whose Smart campaign settings are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.SmartCampaignSettingOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.SmartCampaignSettingOperation]): Required. The list of operations to perform on individual Smart campaign settings. partial_failure (bool): @@ -293,7 +293,7 @@ class MutateSmartCampaignSettingsRequest(proto.Message): validate_only (bool): If true, the request is validated but not executed. Only errors are returned, not results. - response_content_type (google.ads.googleads.v19.enums.types.ResponseContentTypeEnum.ResponseContentType): + response_content_type (google.ads.googleads.v23.enums.types.ResponseContentTypeEnum.ResponseContentType): The response content type setting. Determines whether the mutable resource or just the resource name should be returned post mutation. @@ -332,7 +332,7 @@ class SmartCampaignSettingOperation(proto.Message): campaign. Attributes: - update (google.ads.googleads.v19.resources.types.SmartCampaignSetting): + update (google.ads.googleads.v23.resources.types.SmartCampaignSetting): Update operation: The Smart campaign setting must specify a valid resource name. update_mask (google.protobuf.field_mask_pb2.FieldMask): @@ -362,7 +362,7 @@ class MutateSmartCampaignSettingsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateSmartCampaignSettingResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateSmartCampaignSettingResult]): All results for the mutate. """ @@ -386,7 +386,7 @@ class MutateSmartCampaignSettingResult(proto.Message): Attributes: resource_name (str): Returned for successful operations. - smart_campaign_setting (google.ads.googleads.v19.resources.types.SmartCampaignSetting): + smart_campaign_setting (google.ads.googleads.v23.resources.types.SmartCampaignSetting): The mutated Smart campaign setting with only mutable fields after mutate. The field will only be returned when response_content_type is set to "MUTABLE_RESOURCE". diff --git a/google/ads/googleads/v19/services/types/smart_campaign_suggest_service.py b/google/ads/googleads/v23/services/types/smart_campaign_suggest_service.py similarity index 87% rename from google/ads/googleads/v19/services/types/smart_campaign_suggest_service.py rename to google/ads/googleads/v23/services/types/smart_campaign_suggest_service.py index db9202cdc..24a05c137 100644 --- a/google/ads/googleads/v19/services/types/smart_campaign_suggest_service.py +++ b/google/ads/googleads/v23/services/types/smart_campaign_suggest_service.py @@ -19,16 +19,16 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import ad_type_infos -from google.ads.googleads.v19.common.types import criteria -from google.ads.googleads.v19.resources.types import ( +from google.ads.googleads.v23.common.types import ad_type_infos +from google.ads.googleads.v23.common.types import criteria +from google.ads.googleads.v23.resources.types import ( keyword_theme_constant as gagr_keyword_theme_constant, ) __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "SuggestSmartCampaignBudgetOptionsRequest", "SmartCampaignSuggestionInfo", @@ -43,7 +43,7 @@ class SuggestSmartCampaignBudgetOptionsRequest(proto.Message): r"""Request message for - [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. + [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. This message has `oneof`_ fields (mutually exclusive fields). For each oneof, at most one member field can be set at the same time. @@ -61,7 +61,7 @@ class SuggestSmartCampaignBudgetOptionsRequest(proto.Message): to get suggestion for. This field is a member of `oneof`_ ``suggestion_data``. - suggestion_info (google.ads.googleads.v19.services.types.SmartCampaignSuggestionInfo): + suggestion_info (google.ads.googleads.v23.services.types.SmartCampaignSuggestionInfo): Required. Information needed to get budget options @@ -104,13 +104,13 @@ class SmartCampaignSuggestionInfo(proto.Message): Optional. The two letter advertising language for the Smart campaign to be constructed, default to 'en' if not set. - ad_schedules (MutableSequence[google.ads.googleads.v19.common.types.AdScheduleInfo]): + ad_schedules (MutableSequence[google.ads.googleads.v23.common.types.AdScheduleInfo]): Optional. The business ad schedule. - keyword_themes (MutableSequence[google.ads.googleads.v19.common.types.KeywordThemeInfo]): + keyword_themes (MutableSequence[google.ads.googleads.v23.common.types.KeywordThemeInfo]): Optional. Smart campaign keyword themes. This field may greatly improve suggestion accuracy and we recommend always setting it if possible. - business_context (google.ads.googleads.v19.services.types.SmartCampaignSuggestionInfo.BusinessContext): + business_context (google.ads.googleads.v23.services.types.SmartCampaignSuggestionInfo.BusinessContext): Optional. Context describing the business to advertise. @@ -126,12 +126,12 @@ class SmartCampaignSuggestionInfo(proto.Message): for additional details. This field is a member of `oneof`_ ``business_setting``. - location_list (google.ads.googleads.v19.services.types.SmartCampaignSuggestionInfo.LocationList): + location_list (google.ads.googleads.v23.services.types.SmartCampaignSuggestionInfo.LocationList): Optional. The targeting geo location by locations. This field is a member of `oneof`_ ``geo_target``. - proximity (google.ads.googleads.v19.common.types.ProximityInfo): + proximity (google.ads.googleads.v23.common.types.ProximityInfo): Optional. The targeting geo location by proximity. @@ -142,7 +142,7 @@ class LocationList(proto.Message): r"""A list of locations. Attributes: - locations (MutableSequence[google.ads.googleads.v19.common.types.LocationInfo]): + locations (MutableSequence[google.ads.googleads.v23.common.types.LocationInfo]): Required. Locations. """ @@ -214,7 +214,7 @@ class BusinessContext(proto.Message): class SuggestSmartCampaignBudgetOptionsResponse(proto.Message): r"""Response message for - [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. + [SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignBudgetOptions]. Depending on whether the system could suggest the options, either all of the options or none of them might be returned. @@ -222,15 +222,15 @@ class SuggestSmartCampaignBudgetOptionsResponse(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - low (google.ads.googleads.v19.services.types.SuggestSmartCampaignBudgetOptionsResponse.BudgetOption): + low (google.ads.googleads.v23.services.types.SuggestSmartCampaignBudgetOptionsResponse.BudgetOption): Optional. The lowest budget option. This field is a member of `oneof`_ ``_low``. - recommended (google.ads.googleads.v19.services.types.SuggestSmartCampaignBudgetOptionsResponse.BudgetOption): + recommended (google.ads.googleads.v23.services.types.SuggestSmartCampaignBudgetOptionsResponse.BudgetOption): Optional. The recommended budget option. This field is a member of `oneof`_ ``_recommended``. - high (google.ads.googleads.v19.services.types.SuggestSmartCampaignBudgetOptionsResponse.BudgetOption): + high (google.ads.googleads.v23.services.types.SuggestSmartCampaignBudgetOptionsResponse.BudgetOption): Optional. The highest budget option. This field is a member of `oneof`_ ``_high``. @@ -264,7 +264,7 @@ class BudgetOption(proto.Message): currency for the account. Amount is specified in micros, where one million is equivalent to one currency unit. - metrics (google.ads.googleads.v19.services.types.SuggestSmartCampaignBudgetOptionsResponse.Metrics): + metrics (google.ads.googleads.v23.services.types.SuggestSmartCampaignBudgetOptionsResponse.Metrics): Metrics pertaining to the suggested budget, could be empty if there is not enough information to derive the estimates. @@ -304,12 +304,12 @@ class BudgetOption(proto.Message): class SuggestSmartCampaignAdRequest(proto.Message): r"""Request message for - [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. + [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. Attributes: customer_id (str): Required. The ID of the customer. - suggestion_info (google.ads.googleads.v19.services.types.SmartCampaignSuggestionInfo): + suggestion_info (google.ads.googleads.v23.services.types.SmartCampaignSuggestionInfo): Required. Inputs used to suggest a Smart campaign ad. Required fields: final_url, language_code, keyword_themes. Optional but recommended fields to improve the quality of @@ -329,10 +329,10 @@ class SuggestSmartCampaignAdRequest(proto.Message): class SuggestSmartCampaignAdResponse(proto.Message): r"""Response message for - [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. + [SmartCampaignSuggestService.SuggestSmartCampaignAd][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestSmartCampaignAd]. Attributes: - ad_info (google.ads.googleads.v19.common.types.SmartCampaignAdInfo): + ad_info (google.ads.googleads.v23.common.types.SmartCampaignAdInfo): Optional. Ad info includes 3 creative headlines and 2 creative descriptions. """ @@ -346,22 +346,22 @@ class SuggestSmartCampaignAdResponse(proto.Message): class SuggestKeywordThemesRequest(proto.Message): r"""Request message for - [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestKeywordThemes]. + [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestKeywordThemes]. Attributes: customer_id (str): Required. The ID of the customer. - suggestion_info (google.ads.googleads.v19.services.types.SmartCampaignSuggestionInfo): + suggestion_info (google.ads.googleads.v23.services.types.SmartCampaignSuggestionInfo): Required. Information to get keyword theme suggestions. Required fields: - - suggestion_info.final_url - - suggestion_info.language_code - - suggestion_info.geo_target + - suggestion_info.final_url + - suggestion_info.language_code + - suggestion_info.geo_target Recommended fields: - - suggestion_info.business_setting + - suggestion_info.business_setting """ customer_id: str = proto.Field( @@ -377,10 +377,10 @@ class SuggestKeywordThemesRequest(proto.Message): class SuggestKeywordThemesResponse(proto.Message): r"""Response message for - [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v19.services.SmartCampaignSuggestService.SuggestKeywordThemes]. + [SmartCampaignSuggestService.SuggestKeywordThemes][google.ads.googleads.v23.services.SmartCampaignSuggestService.SuggestKeywordThemes]. Attributes: - keyword_themes (MutableSequence[google.ads.googleads.v19.services.types.SuggestKeywordThemesResponse.KeywordTheme]): + keyword_themes (MutableSequence[google.ads.googleads.v23.services.types.SuggestKeywordThemesResponse.KeywordTheme]): Smart campaign keyword theme suggestions. """ @@ -395,7 +395,7 @@ class KeywordTheme(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - keyword_theme_constant (google.ads.googleads.v19.resources.types.KeywordThemeConstant): + keyword_theme_constant (google.ads.googleads.v23.resources.types.KeywordThemeConstant): A Smart campaign keyword theme constant. This field is a member of `oneof`_ ``keyword_theme``. diff --git a/google/ads/googleads/v19/services/types/third_party_app_analytics_link_service.py b/google/ads/googleads/v23/services/types/third_party_app_analytics_link_service.py similarity index 86% rename from google/ads/googleads/v19/services/types/third_party_app_analytics_link_service.py rename to google/ads/googleads/v23/services/types/third_party_app_analytics_link_service.py index da44b79cf..6903a1137 100644 --- a/google/ads/googleads/v19/services/types/third_party_app_analytics_link_service.py +++ b/google/ads/googleads/v23/services/types/third_party_app_analytics_link_service.py @@ -20,8 +20,8 @@ __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "RegenerateShareableLinkIdRequest", "RegenerateShareableLinkIdResponse", @@ -31,7 +31,7 @@ class RegenerateShareableLinkIdRequest(proto.Message): r"""Request message for - [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. + [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. Attributes: resource_name (str): @@ -47,7 +47,7 @@ class RegenerateShareableLinkIdRequest(proto.Message): class RegenerateShareableLinkIdResponse(proto.Message): r"""Response message for - [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v19.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. + [ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId][google.ads.googleads.v23.services.ThirdPartyAppAnalyticsLinkService.RegenerateShareableLinkId]. """ diff --git a/google/ads/googleads/v19/services/types/travel_asset_suggestion_service.py b/google/ads/googleads/v23/services/types/travel_asset_suggestion_service.py similarity index 87% rename from google/ads/googleads/v19/services/types/travel_asset_suggestion_service.py rename to google/ads/googleads/v23/services/types/travel_asset_suggestion_service.py index f401928e6..4737b6d7f 100644 --- a/google/ads/googleads/v19/services/types/travel_asset_suggestion_service.py +++ b/google/ads/googleads/v23/services/types/travel_asset_suggestion_service.py @@ -19,16 +19,16 @@ import proto # type: ignore -from google.ads.googleads.v19.enums.types import ( +from google.ads.googleads.v23.enums.types import ( asset_field_type as gage_asset_field_type, ) -from google.ads.googleads.v19.enums.types import call_to_action_type -from google.ads.googleads.v19.enums.types import hotel_asset_suggestion_status +from google.ads.googleads.v23.enums.types import call_to_action_type +from google.ads.googleads.v23.enums.types import hotel_asset_suggestion_status __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "SuggestTravelAssetsRequest", "SuggestTravelAssetsResponse", @@ -41,7 +41,7 @@ class SuggestTravelAssetsRequest(proto.Message): r"""Request message for - [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v19.services.TravelAssetSuggestionService.SuggestTravelAssets]. + [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v23.services.TravelAssetSuggestionService.SuggestTravelAssets]. Attributes: customer_id (str): @@ -75,10 +75,10 @@ class SuggestTravelAssetsRequest(proto.Message): class SuggestTravelAssetsResponse(proto.Message): r"""Response message for - [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v19.services.TravelAssetSuggestionService.SuggestTravelAssets]. + [TravelAssetSuggestionService.SuggestTravelAssets][google.ads.googleads.v23.services.TravelAssetSuggestionService.SuggestTravelAssets]. Attributes: - hotel_asset_suggestions (MutableSequence[google.ads.googleads.v19.services.types.HotelAssetSuggestion]): + hotel_asset_suggestions (MutableSequence[google.ads.googleads.v23.services.types.HotelAssetSuggestion]): Asset suggestions for each place ID submitted in the request. """ @@ -102,15 +102,15 @@ class HotelAssetSuggestion(proto.Message): Suggested final URL for an AssetGroup. hotel_name (str): Hotel name in requested language. - call_to_action (google.ads.googleads.v19.enums.types.CallToActionTypeEnum.CallToActionType): + call_to_action (google.ads.googleads.v23.enums.types.CallToActionTypeEnum.CallToActionType): Call to action type. - text_assets (MutableSequence[google.ads.googleads.v19.services.types.HotelTextAsset]): + text_assets (MutableSequence[google.ads.googleads.v23.services.types.HotelTextAsset]): Text assets such as headline, description, etc. - image_assets (MutableSequence[google.ads.googleads.v19.services.types.HotelImageAsset]): + image_assets (MutableSequence[google.ads.googleads.v23.services.types.HotelImageAsset]): Image assets such as landscape/portrait/square, etc. - status (google.ads.googleads.v19.enums.types.HotelAssetSuggestionStatusEnum.HotelAssetSuggestionStatus): + status (google.ads.googleads.v23.enums.types.HotelAssetSuggestionStatusEnum.HotelAssetSuggestionStatus): The status of the hotel asset suggestion. """ @@ -158,7 +158,7 @@ class HotelTextAsset(proto.Message): Attributes: text (str): Asset text in requested language. - asset_field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + asset_field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): The text asset type. For example, HEADLINE, DESCRIPTION, etc. """ @@ -182,7 +182,7 @@ class HotelImageAsset(proto.Message): Attributes: uri (str): URI for the image. - asset_field_type (google.ads.googleads.v19.enums.types.AssetFieldTypeEnum.AssetFieldType): + asset_field_type (google.ads.googleads.v23.enums.types.AssetFieldTypeEnum.AssetFieldType): The Image asset type. For example, MARKETING_IMAGE, PORTRAIT_MARKETING_IMAGE, etc. """ diff --git a/google/ads/googleads/v19/services/types/user_data_service.py b/google/ads/googleads/v23/services/types/user_data_service.py similarity index 87% rename from google/ads/googleads/v19/services/types/user_data_service.py rename to google/ads/googleads/v23/services/types/user_data_service.py index 0e1797dca..c79f9ef8a 100644 --- a/google/ads/googleads/v19/services/types/user_data_service.py +++ b/google/ads/googleads/v23/services/types/user_data_service.py @@ -19,12 +19,12 @@ import proto # type: ignore -from google.ads.googleads.v19.common.types import offline_user_data +from google.ads.googleads.v23.common.types import offline_user_data __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "UploadUserDataRequest", "UserDataOperation", @@ -35,7 +35,7 @@ class UploadUserDataRequest(proto.Message): r"""Request message for - [UserDataService.UploadUserData][google.ads.googleads.v19.services.UserDataService.UploadUserData] + [UserDataService.UploadUserData][google.ads.googleads.v23.services.UserDataService.UploadUserData] .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields @@ -44,9 +44,9 @@ class UploadUserDataRequest(proto.Message): customer_id (str): Required. The ID of the customer for which to update the user data. - operations (MutableSequence[google.ads.googleads.v19.services.types.UserDataOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.UserDataOperation]): Required. The list of operations to be done. - customer_match_user_list_metadata (google.ads.googleads.v19.common.types.CustomerMatchUserListMetadata): + customer_match_user_list_metadata (google.ads.googleads.v23.common.types.CustomerMatchUserListMetadata): Metadata for data updates to a Customer Match user list. @@ -83,12 +83,12 @@ class UserDataOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.common.types.UserData): + create (google.ads.googleads.v23.common.types.UserData): The list of user data to be appended to the user list. This field is a member of `oneof`_ ``operation``. - remove (google.ads.googleads.v19.common.types.UserData): + remove (google.ads.googleads.v23.common.types.UserData): The list of user data to be removed from the user list. @@ -111,7 +111,7 @@ class UserDataOperation(proto.Message): class UploadUserDataResponse(proto.Message): r"""Response message for - [UserDataService.UploadUserData][google.ads.googleads.v19.services.UserDataService.UploadUserData] + [UserDataService.UploadUserData][google.ads.googleads.v23.services.UserDataService.UploadUserData] Uploads made through this service will not be visible under the 'Segment members' section for the Customer Match List in the Google Ads UI. @@ -122,7 +122,7 @@ class UploadUserDataResponse(proto.Message): Attributes: upload_date_time (str): The date time at which the request was received by API, - formatted as "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, + formatted as "yyyy-mm-dd hh:mm:ss+\|-hh:mm", for example, "2019-01-01 12:32:45-08:00". This field is a member of `oneof`_ ``_upload_date_time``. diff --git a/google/ads/googleads/v19/services/types/user_list_customer_type_service.py b/google/ads/googleads/v23/services/types/user_list_customer_type_service.py similarity index 92% rename from google/ads/googleads/v19/services/types/user_list_customer_type_service.py rename to google/ads/googleads/v23/services/types/user_list_customer_type_service.py index c0c01a2d9..dc9fe767f 100644 --- a/google/ads/googleads/v19/services/types/user_list_customer_type_service.py +++ b/google/ads/googleads/v23/services/types/user_list_customer_type_service.py @@ -19,13 +19,13 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import user_list_customer_type +from google.ads.googleads.v23.resources.types import user_list_customer_type from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateUserListCustomerTypesRequest", "UserListCustomerTypeOperation", @@ -37,13 +37,13 @@ class MutateUserListCustomerTypesRequest(proto.Message): r"""Request message for - [UserListCustomerTypeService.MutateUserListCustomerTypes][google.ads.googleads.v19.services.UserListCustomerTypeService.MutateUserListCustomerTypes]. + [UserListCustomerTypeService.MutateUserListCustomerTypes][google.ads.googleads.v23.services.UserListCustomerTypeService.MutateUserListCustomerTypes]. Attributes: customer_id (str): Required. The ID of the customer whose user list customer types are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.UserListCustomerTypeOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.UserListCustomerTypeOperation]): Required. The list of operations to perform on the user list customer types. partial_failure (bool): @@ -90,7 +90,7 @@ class UserListCustomerTypeOperation(proto.Message): .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields Attributes: - create (google.ads.googleads.v19.resources.types.UserListCustomerType): + create (google.ads.googleads.v23.resources.types.UserListCustomerType): Attach a user list customer type to a user list. No resource name is expected for the new user list customer type. @@ -129,7 +129,7 @@ class MutateUserListCustomerTypesResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateUserListCustomerTypeResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateUserListCustomerTypeResult]): All results for the mutate. """ diff --git a/google/ads/googleads/v19/services/types/user_list_service.py b/google/ads/googleads/v23/services/types/user_list_service.py similarity index 91% rename from google/ads/googleads/v19/services/types/user_list_service.py rename to google/ads/googleads/v23/services/types/user_list_service.py index 47a2cc049..f88d6bca8 100644 --- a/google/ads/googleads/v19/services/types/user_list_service.py +++ b/google/ads/googleads/v23/services/types/user_list_service.py @@ -19,14 +19,14 @@ import proto # type: ignore -from google.ads.googleads.v19.resources.types import user_list +from google.ads.googleads.v23.resources.types import user_list from google.protobuf import field_mask_pb2 # type: ignore from google.rpc import status_pb2 # type: ignore __protobuf__ = proto.module( - package="google.ads.googleads.v19.services", - marshal="google.ads.googleads.v19", + package="google.ads.googleads.v23.services", + marshal="google.ads.googleads.v23", manifest={ "MutateUserListsRequest", "UserListOperation", @@ -38,13 +38,13 @@ class MutateUserListsRequest(proto.Message): r"""Request message for - [UserListService.MutateUserLists][google.ads.googleads.v19.services.UserListService.MutateUserLists]. + [UserListService.MutateUserLists][google.ads.googleads.v23.services.UserListService.MutateUserLists]. Attributes: customer_id (str): Required. The ID of the customer whose user lists are being modified. - operations (MutableSequence[google.ads.googleads.v19.services.types.UserListOperation]): + operations (MutableSequence[google.ads.googleads.v23.services.types.UserListOperation]): Required. The list of operations to perform on individual user lists. partial_failure (bool): @@ -91,12 +91,12 @@ class UserListOperation(proto.Message): update_mask (google.protobuf.field_mask_pb2.FieldMask): FieldMask that determines which resource fields are modified in an update. - create (google.ads.googleads.v19.resources.types.UserList): + create (google.ads.googleads.v23.resources.types.UserList): Create operation: No resource name is expected for the new user list. This field is a member of `oneof`_ ``operation``. - update (google.ads.googleads.v19.resources.types.UserList): + update (google.ads.googleads.v23.resources.types.UserList): Update operation: The user list is expected to have a valid resource name. @@ -144,7 +144,7 @@ class MutateUserListsResponse(proto.Message): all errors occur inside the operations. If any errors occur outside the operations (for example, auth errors), we return an RPC level error. - results (MutableSequence[google.ads.googleads.v19.services.types.MutateUserListResult]): + results (MutableSequence[google.ads.googleads.v23.services.types.MutateUserListResult]): All results for the mutate. """ diff --git a/pyproject.toml b/pyproject.toml index 57eb4ee51..a7e0fbbc3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ build-backend = "setuptools.build_meta" [project] name = "google-ads" -version = "28.4.1" +version = "29.0.0" description = "Client library for the Google Ads API" readme = "./README.rst" requires-python = ">=3.9, <3.15" diff --git a/tests/examples/asyncio/async_add_campaigns_test.py b/tests/examples/asyncio/async_add_campaigns_test.py index d1db73926..5b8729d96 100644 --- a/tests/examples/asyncio/async_add_campaigns_test.py +++ b/tests/examples/asyncio/async_add_campaigns_test.py @@ -9,19 +9,19 @@ sys.modules["google.ads.googleads"] = mock_google sys.modules["google.ads.googleads.client"] = mock_google sys.modules["google.ads.googleads.errors"] = mock_google -sys.modules["google.ads.googleads.v22"] = mock_google -sys.modules["google.ads.googleads.v22.resources"] = mock_google -sys.modules["google.ads.googleads.v22.resources.types"] = mock_google -sys.modules["google.ads.googleads.v22.resources.types.campaign"] = mock_google -sys.modules["google.ads.googleads.v22.resources.types.campaign_budget"] = mock_google -sys.modules["google.ads.googleads.v22.services"] = mock_google -sys.modules["google.ads.googleads.v22.services.services"] = mock_google -sys.modules["google.ads.googleads.v22.services.services.campaign_budget_service"] = mock_google -sys.modules["google.ads.googleads.v22.services.services.campaign_service"] = mock_google -sys.modules["google.ads.googleads.v22.services.types"] = mock_google -sys.modules["google.ads.googleads.v22.services.types.campaign_budget_service"] = mock_google -sys.modules["google.ads.googleads.v22.services.types.campaign_service"] = mock_google -sys.modules["google.ads.googleads.v22.services.types.google_ads_service"] = mock_google +sys.modules["google.ads.googleads.v23"] = mock_google +sys.modules["google.ads.googleads.v23.resources"] = mock_google +sys.modules["google.ads.googleads.v23.resources.types"] = mock_google +sys.modules["google.ads.googleads.v23.resources.types.campaign"] = mock_google +sys.modules["google.ads.googleads.v23.resources.types.campaign_budget"] = mock_google +sys.modules["google.ads.googleads.v23.services"] = mock_google +sys.modules["google.ads.googleads.v23.services.services"] = mock_google +sys.modules["google.ads.googleads.v23.services.services.campaign_budget_service"] = mock_google +sys.modules["google.ads.googleads.v23.services.services.campaign_service"] = mock_google +sys.modules["google.ads.googleads.v23.services.types"] = mock_google +sys.modules["google.ads.googleads.v23.services.types.campaign_budget_service"] = mock_google +sys.modules["google.ads.googleads.v23.services.types.campaign_service"] = mock_google +sys.modules["google.ads.googleads.v23.services.types.google_ads_service"] = mock_google from examples.asyncio import async_add_campaigns diff --git a/tests/examples/asyncio/async_search_stream_test.py b/tests/examples/asyncio/async_search_stream_test.py index 28cddd24c..87afbf8a2 100644 --- a/tests/examples/asyncio/async_search_stream_test.py +++ b/tests/examples/asyncio/async_search_stream_test.py @@ -9,12 +9,12 @@ sys.modules["google.ads.googleads"] = mock_google sys.modules["google.ads.googleads.client"] = mock_google sys.modules["google.ads.googleads.errors"] = mock_google -sys.modules["google.ads.googleads.v22"] = mock_google -sys.modules["google.ads.googleads.v22.services"] = mock_google -sys.modules["google.ads.googleads.v22.services.services"] = mock_google -sys.modules["google.ads.googleads.v22.services.services.google_ads_service"] = mock_google -sys.modules["google.ads.googleads.v22.services.types"] = mock_google -sys.modules["google.ads.googleads.v22.services.types.google_ads_service"] = mock_google +sys.modules["google.ads.googleads.v23"] = mock_google +sys.modules["google.ads.googleads.v23.services"] = mock_google +sys.modules["google.ads.googleads.v23.services.services"] = mock_google +sys.modules["google.ads.googleads.v23.services.services.google_ads_service"] = mock_google +sys.modules["google.ads.googleads.v23.services.types"] = mock_google +sys.modules["google.ads.googleads.v23.services.types.google_ads_service"] = mock_google # Import module under test AFTER mocking from examples.asyncio import async_search_stream diff --git a/tests/examples/asyncio/async_search_test.py b/tests/examples/asyncio/async_search_test.py index 95ca6da11..f77543acb 100644 --- a/tests/examples/asyncio/async_search_test.py +++ b/tests/examples/asyncio/async_search_test.py @@ -9,12 +9,12 @@ sys.modules["google.ads.googleads"] = mock_google sys.modules["google.ads.googleads.client"] = mock_google sys.modules["google.ads.googleads.errors"] = mock_google -sys.modules["google.ads.googleads.v22"] = mock_google -sys.modules["google.ads.googleads.v22.services"] = mock_google -sys.modules["google.ads.googleads.v22.services.services"] = mock_google -sys.modules["google.ads.googleads.v22.services.services.google_ads_service"] = mock_google -sys.modules["google.ads.googleads.v22.services.types"] = mock_google -sys.modules["google.ads.googleads.v22.services.types.google_ads_service"] = mock_google +sys.modules["google.ads.googleads.v23"] = mock_google +sys.modules["google.ads.googleads.v23.services"] = mock_google +sys.modules["google.ads.googleads.v23.services.services"] = mock_google +sys.modules["google.ads.googleads.v23.services.services.google_ads_service"] = mock_google +sys.modules["google.ads.googleads.v23.services.types"] = mock_google +sys.modules["google.ads.googleads.v23.services.types.google_ads_service"] = mock_google # Import module under test AFTER mocking from examples.asyncio import async_search diff --git a/tests/examples/misc/add_ad_group_image_asset_test.py b/tests/examples/misc/add_ad_group_image_asset_test.py index ddf1bffd3..ced674dfa 100644 --- a/tests/examples/misc/add_ad_group_image_asset_test.py +++ b/tests/examples/misc/add_ad_group_image_asset_test.py @@ -159,7 +159,7 @@ def _simulate_script_main_block( # Script's GoogleAdsClient.load_from_storage call mock_client_instance = mock.Mock(name="GoogleAdsClientInstance") mock_gads_client_class_from_decorator.load_from_storage.return_value = mock_client_instance - googleads_client = mock_gads_client_class_from_decorator.load_from_storage(version="v19") + googleads_client = mock_gads_client_class_from_decorator.load_from_storage(version="v23") # Script's main function call mock_main_func_from_decorator( @@ -207,7 +207,7 @@ def test_argument_parsing( mock_parser_instance_for_assert.parse_args.assert_called_once_with() - mock_gads_client_class.load_from_storage.assert_called_once_with(version="v19") + mock_gads_client_class.load_from_storage.assert_called_once_with(version="v23") client_instance_for_assert = mock_gads_client_class.load_from_storage.return_value mock_script_main.assert_called_once_with( diff --git a/tests/examples/misc/campaign_report_to_csv_test.py b/tests/examples/misc/campaign_report_to_csv_test.py index 3f2af1aa4..b867ed524 100644 --- a/tests/examples/misc/campaign_report_to_csv_test.py +++ b/tests/examples/misc/campaign_report_to_csv_test.py @@ -466,7 +466,7 @@ def _simulate_script_main_block( ) googleads_client = ( mock_gads_client_class_from_decorator.load_from_storage( - version="v20" + version="v23" ) ) @@ -548,7 +548,7 @@ def test_argument_parsing( mock_parser_inst_for_assert.parse_args.assert_called_once_with() mock_gads_client_class.load_from_storage.assert_called_once_with( - version="v20" + version="v23" ) client_inst_for_assert = ( @@ -600,7 +600,7 @@ def test_argument_parsing_no_headers_flag( mock_parser_inst_for_assert.parse_args.assert_called_once_with() mock_gads_client_class.load_from_storage.assert_called_once_with( - version="v20" + version="v23" ) client_inst_for_assert = ( diff --git a/tests/examples/misc/set_custom_client_timeouts_test.py b/tests/examples/misc/set_custom_client_timeouts_test.py index b97e8f02d..5f37bcaa8 100644 --- a/tests/examples/misc/set_custom_client_timeouts_test.py +++ b/tests/examples/misc/set_custom_client_timeouts_test.py @@ -256,13 +256,13 @@ def _run_main_block_logic( args = parser.parse_args() # This will return mock_parsed_args_obj # 4. Script calls GoogleAdsClient.load_from_storage: - # googleads_client = GoogleAdsClient.load_from_storage(version="v19") + # googleads_client = GoogleAdsClient.load_from_storage(version="v23") # This call goes to mock_gads_client_class_from_decorator. # We need to configure what this mock class's method returns (a client instance mock). mock_client_instance = mock.Mock(name="GoogleAdsClientInstance") mock_gads_client_class_from_decorator.load_from_storage.return_value = mock_client_instance - googleads_client = mock_gads_client_class_from_decorator.load_from_storage(version="v19") + googleads_client = mock_gads_client_class_from_decorator.load_from_storage(version="v23") # 5. Script calls main function: # main(googleads_client, args.customer_id) @@ -310,7 +310,7 @@ def test_argument_parsing_and_script_execution( mock_parser_instance_for_assert.parse_args.assert_called_once_with() # Assert GoogleAdsClient.load_from_storage was called - mock_google_ads_client_class_in_script.load_from_storage.assert_called_once_with(version="v19") + mock_google_ads_client_class_in_script.load_from_storage.assert_called_once_with(version="v23") # Assert the script's main function (mock_script_main_function) was called client_instance_for_assert = mock_google_ads_client_class_in_script.load_from_storage.return_value diff --git a/tests/examples/misc/upload_image_asset_test.py b/tests/examples/misc/upload_image_asset_test.py index 25107a0c0..595b617fc 100644 --- a/tests/examples/misc/upload_image_asset_test.py +++ b/tests/examples/misc/upload_image_asset_test.py @@ -152,7 +152,7 @@ def _simulate_script_main_block( # Script's GoogleAdsClient.load_from_storage call mock_client_instance = mock.Mock(name="GoogleAdsClientInstance") mock_gads_client_class_from_decorator.load_from_storage.return_value = mock_client_instance - googleads_client = mock_gads_client_class_from_decorator.load_from_storage(version="v19") + googleads_client = mock_gads_client_class_from_decorator.load_from_storage(version="v23") # Script's main function call mock_main_func_from_decorator(googleads_client, args.customer_id) @@ -186,7 +186,7 @@ def test_argument_parsing_and_script_execution( ) mock_parser_instance_for_assert.parse_args.assert_called_once_with() - mock_gads_client_class.load_from_storage.assert_called_once_with(version="v19") + mock_gads_client_class.load_from_storage.assert_called_once_with(version="v23") client_instance_for_assert = mock_gads_client_class.load_from_storage.return_value mock_script_main.assert_called_once_with(